Skip to content

Instantly share code, notes, and snippets.

@josyb
Last active March 14, 2018 14:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josyb/d119a2f3f12dcc28533ac612e30576af to your computer and use it in GitHub Desktop.
Save josyb/d119a2f3f12dcc28533ac612e30576af to your computer and use it in GitHub Desktop.
Structural Design in MyHDL - to @block or not to @block?

Following a discussion on Gitter[https://gitter.im/myhdl/myhdl] (November 24th, 14:40 about) I decided to make a small example to test it all. I have two versions of the MyHDL source:

  • structuraldesign_block.py: using the @block
  • structuraldesign_noblock.py: as in 0.9 using the old toVHDL() function call

You can see the two resulting VHDL files.

The one generated with the @block is a mess as it duplicates a lot of names. Of course the one generated by my local no-block MyHDL packages is ... well ... beautiful

Follow-up November 25th:

I added explicit naming , see the third source: structuraldesign_block_explicit.py. And that generates valid VHDL, see structuraldesign_block_explicit.vhd. I still have a few gripes like the file is not nicely formatted and the generate names carry redundant prefixes, but this can be helped easily by post-editing. Actually the code generated with the @block looks better to me as the signal names represent now what I do (did) in VHDL: the signal connecting the output of one building block (e.g. buf0) to the next (e.g. mux) are buildingblock_OutputPort. This helps interpreting the VHDL filke as we now know where we have come from (opposite to the song ...).

2nd Follow-up November 25th:

I started to like the @block (notwithstanding my earlier aversion ...) so I worked a bit on collecting the rtl() stuff from the class objects I use: a couple hours of work and it looks promising: see structural2.py Note that I only handle the simple case here, lists of instantiations will need more work.

So I will start backporting soon.

'''
Created on Nov 24, 2017
@author: josy
'''
from __future__ import print_function
from collections import namedtuple
import myhdl
from myhdl import Signal, intbv, modbv, enum, always_comb, always_seq, ResetSignal
if myhdl.__version__ == '1.0dev':
from myhdl import block
else:
from myhdl import toVHDL
# define an 'empty' block decorator
def block(ob):
return ob
def _copy( sig ):
''' a helper to create Signals without thinking '''
if isinstance(sig.val, intbv):
return Signal(intbv(0)[len(sig):])
else:
return Signal(bool(0))
ForwardPort = namedtuple('ForwardPort', ['rtlblock', 'port'])
class RtlProvider(object):
''' Base class for MyHdl generating classes '''
# yes, it needs an @block decorator
@block
def rtlinstances(self, dlocals):
''' return the rtl() of the instantiated building blocks '''
keys = dlocals.keys()
values = dlocals.values()
# first resolve the ForwardPorts (if any)
for value in values:
if isinstance(value, RtlProvider):
if id(value) != id(self):
refs = vars(value)
for dest, sig in refs.iteritems():
if isinstance(sig, ForwardPort):
value.__setattr__(dest, getattr(dlocals[sig.rtlblock], sig.port))
# now collect the rtl()
l = []
for key, value in zip(keys, values):
if isinstance(value, RtlProvider):
if id(value) != id(self):
trtl = value.rtl()
if myhdl.__version__ == '1.0dev':
trtl.name = '{}'.format(key)
l.append(trtl)
return l
def rtl(self):
''' placeholder to detect empty instances '''
raise NotImplementedError('You need to define a rtl() method!')
class Buffer(RtlProvider):
''' a simple 1 register deep buffer '''
def __init__(self,Clk, Reset, DataIn, ValidIn, ReadyOut, ReadyIn=None, ValidOut=None, DataOut=None ):
# super(Buffer, self).__init__()
self.Clk = Clk
self.Reset = Reset
self.DataIn = DataIn
self.ValidIn = ValidIn
self.ReadyOut = ReadyOut
self.ReadyIn = ReadyIn if ReadyIn is not None else Signal(bool(0))
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn)
@block
def rtl(self):
''' the logic '''
buffer_state = enum("BUF_FREE", "BUF_TAKEN")
smp, smn = [Signal(buffer_state.BUF_FREE) for _ in range(2)]
ldbuf = Signal(bool(0))
@always_comb
def smcomb():
''' Buffer: the combinatorial part of the state-machine '''
self.ReadyIn.next = 0
self.ValidOut.next = 0
ldbuf.next = 0
if smp == buffer_state.BUF_FREE:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
elif smp == buffer_state.BUF_TAKEN:
self.ValidOut.next = 1
if self.ReadyOut:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
else:
smn.next = buffer_state.BUF_TAKEN
@always_seq(self.Clk.posedge, reset=self.Reset)
def smsync():
''' Buffer: the synchronous part of the state-machine '''
smp.next = smn
@always_seq(self.Clk.posedge, reset=None)
def smreg():
''' Buffer: the registered part of the state-machine '''
if ldbuf:
self.DataOut.next = self.DataIn
return smcomb, smsync, smreg
class Mux4t1(RtlProvider):
''' a naive 4 to 1 multiplexer '''
def __init__(self, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None
):
# super(Mux4t1, self).__init__()
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
@block
def rtl(self):
''' the logic '''
@always_comb
def mux():
self.ReadyIn0.next = 0
self.ReadyIn1.next = 0
self.ReadyIn2.next = 0
self.ReadyIn3.next = 0
self.ValidOut.next = 0
self.DataOut.next = 0
if self.ValidIn0:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn0
if self.ReadyOut:
self.ReadyIn0.next = 1
elif self.ValidIn1:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn1
if self.ReadyOut:
self.ReadyIn1.next = 1
elif self.ValidIn2:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn2
if self.ReadyOut:
self.ReadyIn2.next = 1
elif self.ValidIn3:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn3
if self.ReadyOut:
self.ReadyIn3.next = 1
return mux
class Counter(RtlProvider):
'''a simple counter '''
def __init__(self, WIDTH_COUNT, Clk, Reset, CntEn=None, Q=None):
self.WIDTH_COUNT= WIDTH_COUNT
self.Clk = Clk
self.Reset = Reset
self.CntEn = CntEn if CntEn is not None else Signal(bool(1))
self.Q = Q if Q is not None else Signal(modbv(0)[WIDTH_COUNT:])
@block
def rtl(self):
''' the logic '''
@always_seq(self.Clk.posedge, reset=self.Reset)
def count():
if self.CntEn:
self.Q.next = self.Q + 1
return count
class StructuralDesign(RtlProvider):
'''
a simple structural design
consisting of 4 input buffers, a 4 to 1 multiplexer and a single output buffer
|-------| |-
| | | -
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | | |-------|
|-------| | | | |
| |----| |----
|-------| | | | |
| | | | |-------|
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | -
|-------| |_-
'''
def __init__(self, Clk, Reset,
DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None,
TransactionCount=None
):
# super(StructuralDesign, self).__init__()
self.Clk = Clk
self.Reset = Reset
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
self.TransactionCount = TransactionCount if TransactionCount is not None else Signal(intbv(0)[16:])
@block
def rtl(self):
'''
the *structural* logic
look ma! No local glue Signals!
'''
buf0 = Buffer(self.Clk, self.Reset, self.DataIn0, self.ValidIn0, ForwardPort('mux', 'ReadyIn0'), self.ReadyIn0)
buf1 = Buffer(self.Clk, self.Reset, self.DataIn1, self.ValidIn1, ForwardPort('mux', 'ReadyIn1'), self.ReadyIn1)
buf2 = Buffer(self.Clk, self.Reset, self.DataIn2, self.ValidIn2, ForwardPort('mux', 'ReadyIn2'), self.ReadyIn2)
buf3 = Buffer(self.Clk, self.Reset, self.DataIn3, self.ValidIn3, ForwardPort('mux', 'ReadyIn3'), self.ReadyIn3)
mux = Mux4t1(buf0.DataOut, buf0.ValidOut,
buf1.DataOut, buf1.ValidOut,
buf2.DataOut, buf2.ValidOut,
buf3.DataOut, buf3.ValidOut,
ForwardPort('bufo', 'ReadyIn')
)
bufo = Buffer(self.Clk, self.Reset, mux.DataOut, mux.ValidOut, self.ReadyOut, DataOut=self.DataOut)
#let's add a counter to count the transactions
tac = Counter(len(self.TransactionCount), self.Clk, self.Reset )
# now we need some local glue-code
@always_comb
def assign():
tac.CntEn.next = 0
self.ValidOut.next = bufo.ValidOut
self.TransactionCount.next = tac.Q
if bufo.ValidOut and self.ReadyOut:
tac.CntEn.next = 1
# having to pass the locals() may look a bit off, but is by far the easiest way
# to achieve our goal(s)
return self.rtlinstances(locals()), assign
if __name__ == '__main__':
# unfortunately we need to wrap the *main* class in a function ...
@block
def top_structuraldesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut, TransactionCount):
top_structuraldesignrtl = StructuralDesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut, TransactionCount).rtl()
if myhdl.__version__ == '1.0dev':
top_structuraldesignrtl.name = 'top_structuraldesign'
return top_structuraldesignrtl
def convert():
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, True)
DataIn0 = Signal(intbv(0)[8:])
ValidIn0 = Signal(bool(0))
DataIn1 = Signal(intbv(0)[8:])
ValidIn1 = Signal(bool(0))
DataIn2 = Signal(intbv(0)[8:])
ValidIn2 = Signal(bool(0))
DataIn3 = Signal(intbv(0)[8:])
ValidIn3 = Signal(bool(0))
ReadyOut = Signal(bool(0))
ReadyIn0 = Signal(bool(0))
ReadyIn1 = Signal(bool(0))
ReadyIn2 = Signal(bool(0))
ReadyIn3 = Signal(bool(0))
DataOut = Signal(intbv(0)[8:])
ValidOut = Signal(bool(0))
TransactionCount = Signal(intbv(0)[24:])
if myhdl.__version__ == '1.0dev':
dut = top_structuraldesign(Clk, Reset,
DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut, TransactionCount)
dut.convert('VHDL')
else:
toVHDL.standard = '2008'
toVHDL.name = 'StructuralDesign'
toVHDL(top_structuraldesign, Clk, Reset,
DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut, TransactionCount)
# dut.convert('Verilog')
convert()
'''
Created on Nov 24, 2017
@author: josy
'''
from myhdl import Signal, intbv, enum, block, always_comb, always_seq, ResetSignal
def _copy( sig ):
if isinstance(sig.val, intbv):
return Signal(intbv(0)[len(sig):])
else:
return Signal(bool(0))
class Buffer(object):
''' a simple 1 register deep buffer '''
def __init__(self,Clk, Reset, DataIn, ValidIn, ReadyOut, ReadyIn=None, ValidOut=None, DataOut=None ):
self.Clk = Clk
self.Reset = Reset
self.DataIn = DataIn
self.ValidIn = ValidIn
self.ReadyOut = ReadyOut
self.ReadyIn = ReadyIn if ReadyIn is not None else Signal(bool(0))
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn)
@block
def rtl(self):
''' the logic '''
buffer_state = enum("BUF_FREE", "BUF_TAKEN")
smp, smn = [Signal(buffer_state.BUF_FREE) for _ in range(2)]
ldbuf = Signal(bool(0))
@always_comb
def smcomb():
''' Buffer: the combinatorial part of the state-machine '''
self.ReadyIn.next = 0
self.ValidOut.next = 0
ldbuf.next = 0
if smp == buffer_state.BUF_FREE:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
elif smp == buffer_state.BUF_TAKEN:
self.ValidOut.next = 1
if self.ReadyOut:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
else:
smn.next = buffer_state.BUF_TAKEN
@always_seq(self.Clk.posedge, reset=self.Reset)
def smsync():
''' Buffer: the synchronous part of the state-machine '''
smp.next = smn
@always_seq(self.Clk.posedge, reset=None)
def smreg():
''' Buffer: the registered part of the state-machine '''
if ldbuf:
self.DataOut.next = self.DataIn
return smcomb, smsync, smreg
class Mux4t1(object):
''' a naive 4 to 1 multiplexer '''
def __init__(self, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None
):
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
@block
def rtl(self):
''' the logic '''
@always_comb
def mux():
self.ReadyIn0.next = 0
self.ReadyIn1.next = 0
self.ReadyIn2.next = 0
self.ReadyIn3.next = 0
self.ValidOut.next = 0
self.DataOut.next = 0
if self.ValidIn0:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn0
if self.ReadyOut:
self.ReadyIn0.next = 1
elif self.ValidIn1:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn1
if self.ReadyOut:
self.ReadyIn1.next = 1
elif self.ValidIn2:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn2
if self.ReadyOut:
self.ReadyIn2.next = 1
elif self.ValidIn3:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn3
if self.ReadyOut:
self.ReadyIn3.next = 1
return mux
class StructuralDesign(object):
'''
a simple structural design
consisting of 4 input buffers, a 4 to 1 multiplexer and a single output buffer
|-------| |-
| | | -
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | | |-------|
|-------| | | | |
| |----| |----
|-------| | | | |
| | | | |-------|
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | -
|-------| |_-
'''
def __init__(self, Clk, Reset,
DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None
):
self.Clk = Clk
self.Reset = Reset
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
@block
def rtl(self):
''' the *structural* logic '''
# unfortunately we still need to declare *forward* Signals
# but we can remedy that later
muxreadyin0 = Signal(bool(0))
muxreadyin1 = Signal(bool(0))
muxreadyin2 = Signal(bool(0))
muxreadyin3 = Signal(bool(0))
buforeadyin = Signal(bool(0))
buf0 = Buffer(self.Clk, self.Reset, self.DataIn0, self.ValidIn0, muxreadyin0, self.ReadyIn0)
buf1 = Buffer(self.Clk, self.Reset, self.DataIn1, self.ValidIn1, muxreadyin1, self.ReadyIn1)
buf2 = Buffer(self.Clk, self.Reset, self.DataIn2, self.ValidIn2, muxreadyin2, self.ReadyIn2)
buf3 = Buffer(self.Clk, self.Reset, self.DataIn3, self.ValidIn3, muxreadyin3, self.ReadyIn3)
mux = Mux4t1(buf0.DataOut, buf0.ValidOut,
buf1.DataOut, buf1.ValidOut,
buf2.DataOut, buf2.ValidOut,
buf3.DataOut, buf3.ValidOut,
buforeadyin,
muxreadyin0, muxreadyin1, muxreadyin2, muxreadyin3
)
bufo = Buffer(self.Clk, self.Reset, mux.DataOut, mux.ValidOut, self.ReadyOut, buforeadyin, self.ValidOut, self.DataOut)
# now we still have to collect the rtl
buf0rtl = buf0.rtl()
buf1rtl = buf1.rtl()
buf2rtl = buf2.rtl()
buf3rtl = buf3.rtl()
muxrtl = mux.rtl()
bufortl = bufo.rtl()
return buf0rtl, buf1rtl, buf2rtl, buf3rtl, muxrtl, bufortl
if __name__ == '__main__':
# unfortunately we need to wrap the *main* class in a function ...
@block
def top_structuraldesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut):
return StructuralDesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut).rtl()
def convert():
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, True)
DataIn0 = Signal(intbv(0)[8:])
ValidIn0 = Signal(bool(0))
DataIn1 = Signal(intbv(0)[8:])
ValidIn1 = Signal(bool(0))
DataIn2 = Signal(intbv(0)[8:])
ValidIn2 = Signal(bool(0))
DataIn3 = Signal(intbv(0)[8:])
ValidIn3 = Signal(bool(0))
ReadyOut = Signal(bool(0))
ReadyIn0 = Signal(bool(0))
ReadyIn1 = Signal(bool(0))
ReadyIn2 = Signal(bool(0))
ReadyIn3 = Signal(bool(0))
DataOut = Signal(intbv(0)[8:])
ValidOut = Signal(bool(0))
dut = top_structuraldesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut)
dut.convert('VHDL')
convert()
'''
Created on Nov 24, 2017
@author: josy
'''
from myhdl import Signal, intbv, enum, block, always_comb, always_seq, ResetSignal
def _copy( sig ):
if isinstance(sig.val, intbv):
return Signal(intbv(0)[len(sig):])
else:
return Signal(bool(0))
class Buffer(object):
''' a simple 1 register deep buffer '''
def __init__(self,Clk, Reset, DataIn, ValidIn, ReadyOut, ReadyIn=None, ValidOut=None, DataOut=None ):
self.Clk = Clk
self.Reset = Reset
self.DataIn = DataIn
self.ValidIn = ValidIn
self.ReadyOut = ReadyOut
self.ReadyIn = ReadyIn if ReadyIn is not None else Signal(bool(0))
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn)
@block
def rtl(self):
''' the logic '''
buffer_state = enum("BUF_FREE", "BUF_TAKEN")
smp, smn = [Signal(buffer_state.BUF_FREE) for _ in range(2)]
ldbuf = Signal(bool(0))
@always_comb
def smcomb():
''' Buffer: the combinatorial part of the state-machine '''
self.ReadyIn.next = 0
self.ValidOut.next = 0
ldbuf.next = 0
if smp == buffer_state.BUF_FREE:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
elif smp == buffer_state.BUF_TAKEN:
self.ValidOut.next = 1
if self.ReadyOut:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
else:
smn.next = buffer_state.BUF_TAKEN
@always_seq(self.Clk.posedge, reset=self.Reset)
def smsync():
''' Buffer: the synchronous part of the state-machine '''
smp.next = smn
@always_seq(self.Clk.posedge, reset=None)
def smreg():
''' Buffer: the registered part of the state-machine '''
if ldbuf:
self.DataOut.next = self.DataIn
return smcomb, smsync, smreg
class Mux4t1(object):
''' a naive 4 to 1 multiplexer '''
def __init__(self, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None
):
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
@block
def rtl(self):
''' the logic '''
@always_comb
def mux():
self.ReadyIn0.next = 0
self.ReadyIn1.next = 0
self.ReadyIn2.next = 0
self.ReadyIn3.next = 0
self.ValidOut.next = 0
self.DataOut.next = 0
if self.ValidIn0:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn0
if self.ReadyOut:
self.ReadyIn0.next = 1
elif self.ValidIn1:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn1
if self.ReadyOut:
self.ReadyIn1.next = 1
elif self.ValidIn2:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn2
if self.ReadyOut:
self.ReadyIn2.next = 1
elif self.ValidIn3:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn3
if self.ReadyOut:
self.ReadyIn3.next = 1
return mux
class StructuralDesign(object):
'''
a simple structural design
consisting of 4 input buffers, a 4 to 1 multiplexer and a single output buffer
|-------| |-
| | | -
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | | |-------|
|-------| | | | |
| |----| |----
|-------| | | | |
| | | | |-------|
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | -
|-------| |_-
'''
def __init__(self, Clk, Reset,
DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None
):
self.Clk = Clk
self.Reset = Reset
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
@block
def rtl(self):
''' the *structural* logic '''
# unfortunately we still need to declare *forward* Signals
# but we can remedy that later
muxreadyin0 = Signal(bool(0))
muxreadyin1 = Signal(bool(0))
muxreadyin2 = Signal(bool(0))
muxreadyin3 = Signal(bool(0))
buforeadyin = Signal(bool(0))
buf0 = Buffer(self.Clk, self.Reset, self.DataIn0, self.ValidIn0, muxreadyin0, self.ReadyIn0)
buf1 = Buffer(self.Clk, self.Reset, self.DataIn1, self.ValidIn1, muxreadyin1, self.ReadyIn1)
buf2 = Buffer(self.Clk, self.Reset, self.DataIn2, self.ValidIn2, muxreadyin2, self.ReadyIn2)
buf3 = Buffer(self.Clk, self.Reset, self.DataIn3, self.ValidIn3, muxreadyin3, self.ReadyIn3)
mux = Mux4t1(buf0.DataOut, buf0.ValidOut,
buf1.DataOut, buf1.ValidOut,
buf2.DataOut, buf2.ValidOut,
buf3.DataOut, buf3.ValidOut,
buforeadyin,
muxreadyin0, muxreadyin1, muxreadyin2, muxreadyin3
)
bufo = Buffer(self.Clk, self.Reset, mux.DataOut, mux.ValidOut, self.ReadyOut, buforeadyin, self.ValidOut, self.DataOut)
# now we still have to collect the rtl
buf0rtl = buf0.rtl()
buf0rtl.name = 'buf0'
buf1rtl = buf1.rtl()
buf1rtl.name = 'buf1'
buf2rtl = buf2.rtl()
buf2rtl.name = 'buf2'
buf3rtl = buf3.rtl()
buf3rtl.name = 'buf3'
muxrtl = mux.rtl()
muxrtl.name = 'mux'
bufortl = bufo.rtl()
bufortl.name = 'bufo'
return buf0rtl, buf1rtl, buf2rtl, buf3rtl, muxrtl, bufortl
if __name__ == '__main__':
# unfortunately we need to warp the *main8 class in a function ...
@block
def top_structuraldesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut):
return StructuralDesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut).rtl()
def convert():
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, True)
DataIn0 = Signal(intbv(0)[8:])
ValidIn0 = Signal(bool(0))
DataIn1 = Signal(intbv(0)[8:])
ValidIn1 = Signal(bool(0))
DataIn2 = Signal(intbv(0)[8:])
ValidIn2 = Signal(bool(0))
DataIn3 = Signal(intbv(0)[8:])
ValidIn3 = Signal(bool(0))
ReadyOut = Signal(bool(0))
ReadyIn0 = Signal(bool(0))
ReadyIn1 = Signal(bool(0))
ReadyIn2 = Signal(bool(0))
ReadyIn3 = Signal(bool(0))
DataOut = Signal(intbv(0)[8:])
ValidOut = Signal(bool(0))
dut = top_structuraldesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut)
dut.convert('VHDL')
convert()
-- File: top_structuraldesign.vhd
-- Generated by MyHDL 1.0dev
-- Date: Sat Nov 25 10:54:46 2017
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_10.all;
entity top_structuraldesign is
port (
Clk: in std_logic;
Reset: in std_logic;
DataIn0: in unsigned(7 downto 0);
ValidIn0: in std_logic;
DataIn1: in unsigned(7 downto 0);
ValidIn1: in std_logic;
DataIn2: in unsigned(7 downto 0);
ValidIn2: in std_logic;
DataIn3: in unsigned(7 downto 0);
ValidIn3: in std_logic;
ReadyOut: in std_logic;
ReadyIn0: out std_logic;
ReadyIn1: out std_logic;
ReadyIn2: out std_logic;
ReadyIn3: out std_logic;
DataOut: out unsigned(7 downto 0);
ValidOut: out std_logic
);
end entity top_structuraldesign;
architecture MyHDL of top_structuraldesign is
type t_enum_buffer_state_1 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_2 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_3 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_4 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_5 is (
BUF_FREE,
BUF_TAKEN
);
signal rtl_1_muxreadyin1: std_logic;
signal rtl_1_buforeadyin: std_logic;
signal rtl_1_muxreadyin3: std_logic;
signal rtl_1_muxreadyin2: std_logic;
signal rtl_1_muxreadyin0: std_logic;
signal rtl_1_buf0_self_ValidOut: std_logic;
signal rtl_1_buf0_smn: t_enum_buffer_state_1;
signal rtl_1_buf0_ldbuf: std_logic;
signal rtl_1_buf0_smp: t_enum_buffer_state_1;
signal rtl_1_buf0_self_DataOut: unsigned(7 downto 0);
signal rtl_1_buf1_self_ValidOut: std_logic;
signal rtl_1_buf1_smn: t_enum_buffer_state_2;
signal rtl_1_buf1_ldbuf: std_logic;
signal rtl_1_buf1_smp: t_enum_buffer_state_2;
signal rtl_1_buf1_self_DataOut: unsigned(7 downto 0);
signal rtl_1_buf2_self_ValidOut: std_logic;
signal rtl_1_buf2_smn: t_enum_buffer_state_3;
signal rtl_1_buf2_ldbuf: std_logic;
signal rtl_1_buf2_smp: t_enum_buffer_state_3;
signal rtl_1_buf2_self_DataOut: unsigned(7 downto 0);
signal rtl_1_buf3_self_ValidOut: std_logic;
signal rtl_1_buf3_smn: t_enum_buffer_state_4;
signal rtl_1_buf3_ldbuf: std_logic;
signal rtl_1_buf3_smp: t_enum_buffer_state_4;
signal rtl_1_buf3_self_DataOut: unsigned(7 downto 0);
signal rtl_1_mux_self_ValidOut: std_logic;
signal rtl_1_mux_self_DataOut: unsigned(7 downto 0);
signal rtl_1_bufo_smn: t_enum_buffer_state_5;
signal rtl_1_bufo_ldbuf: std_logic;
signal rtl_1_bufo_smp: t_enum_buffer_state_5;
begin
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF0_SMCOMB: process (rtl_1_muxreadyin0, ValidIn0, rtl_1_buf0_smp) is
begin
ReadyIn0 <= '0';
rtl_1_buf0_self_ValidOut <= '0';
rtl_1_buf0_ldbuf <= '0';
case rtl_1_buf0_smp is
when BUF_FREE =>
ReadyIn0 <= '1';
if bool(ValidIn0) then
rtl_1_buf0_smn <= BUF_TAKEN;
rtl_1_buf0_ldbuf <= '1';
else
rtl_1_buf0_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_buf0_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin0) then
ReadyIn0 <= '1';
if bool(ValidIn0) then
rtl_1_buf0_smn <= BUF_TAKEN;
rtl_1_buf0_ldbuf <= '1';
else
rtl_1_buf0_smn <= BUF_FREE;
end if;
else
rtl_1_buf0_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF0_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF0_SMSYNC: process (Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_buf0_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_buf0_smp <= rtl_1_buf0_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF0_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF0_SMREG: process (Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_buf0_ldbuf) then
rtl_1_buf0_self_DataOut <= DataIn0;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF0_SMREG;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF1_SMCOMB: process (rtl_1_muxreadyin1, ValidIn1, rtl_1_buf1_smp) is
begin
ReadyIn1 <= '0';
rtl_1_buf1_self_ValidOut <= '0';
rtl_1_buf1_ldbuf <= '0';
case rtl_1_buf1_smp is
when BUF_FREE =>
ReadyIn1 <= '1';
if bool(ValidIn1) then
rtl_1_buf1_smn <= BUF_TAKEN;
rtl_1_buf1_ldbuf <= '1';
else
rtl_1_buf1_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_buf1_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin1) then
ReadyIn1 <= '1';
if bool(ValidIn1) then
rtl_1_buf1_smn <= BUF_TAKEN;
rtl_1_buf1_ldbuf <= '1';
else
rtl_1_buf1_smn <= BUF_FREE;
end if;
else
rtl_1_buf1_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF1_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF1_SMSYNC: process (Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_buf1_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_buf1_smp <= rtl_1_buf1_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF1_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF1_SMREG: process (Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_buf1_ldbuf) then
rtl_1_buf1_self_DataOut <= DataIn1;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF1_SMREG;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF2_SMCOMB: process (rtl_1_muxreadyin2, ValidIn2, rtl_1_buf2_smp) is
begin
ReadyIn2 <= '0';
rtl_1_buf2_self_ValidOut <= '0';
rtl_1_buf2_ldbuf <= '0';
case rtl_1_buf2_smp is
when BUF_FREE =>
ReadyIn2 <= '1';
if bool(ValidIn2) then
rtl_1_buf2_smn <= BUF_TAKEN;
rtl_1_buf2_ldbuf <= '1';
else
rtl_1_buf2_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_buf2_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin2) then
ReadyIn2 <= '1';
if bool(ValidIn2) then
rtl_1_buf2_smn <= BUF_TAKEN;
rtl_1_buf2_ldbuf <= '1';
else
rtl_1_buf2_smn <= BUF_FREE;
end if;
else
rtl_1_buf2_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF2_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF2_SMSYNC: process (Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_buf2_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_buf2_smp <= rtl_1_buf2_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF2_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF2_SMREG: process (Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_buf2_ldbuf) then
rtl_1_buf2_self_DataOut <= DataIn2;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF2_SMREG;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF3_SMCOMB: process (rtl_1_muxreadyin3, ValidIn3, rtl_1_buf3_smp) is
begin
ReadyIn3 <= '0';
rtl_1_buf3_self_ValidOut <= '0';
rtl_1_buf3_ldbuf <= '0';
case rtl_1_buf3_smp is
when BUF_FREE =>
ReadyIn3 <= '1';
if bool(ValidIn3) then
rtl_1_buf3_smn <= BUF_TAKEN;
rtl_1_buf3_ldbuf <= '1';
else
rtl_1_buf3_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_buf3_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin3) then
ReadyIn3 <= '1';
if bool(ValidIn3) then
rtl_1_buf3_smn <= BUF_TAKEN;
rtl_1_buf3_ldbuf <= '1';
else
rtl_1_buf3_smn <= BUF_FREE;
end if;
else
rtl_1_buf3_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF3_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF3_SMSYNC: process (Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_buf3_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_buf3_smp <= rtl_1_buf3_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF3_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUF3_SMREG: process (Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_buf3_ldbuf) then
rtl_1_buf3_self_DataOut <= DataIn3;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUF3_SMREG;
TOP_STRUCTURALDESIGN_RTL_1_MUX_MUX: process (rtl_1_buforeadyin, rtl_1_buf0_self_DataOut, rtl_1_buf1_self_DataOut, rtl_1_buf2_self_DataOut, rtl_1_buf3_self_DataOut, rtl_1_buf1_self_ValidOut, rtl_1_buf0_self_ValidOut, rtl_1_buf3_self_ValidOut, rtl_1_buf2_self_ValidOut) is
begin
rtl_1_muxreadyin0 <= '0';
rtl_1_muxreadyin1 <= '0';
rtl_1_muxreadyin2 <= '0';
rtl_1_muxreadyin3 <= '0';
rtl_1_mux_self_ValidOut <= '0';
rtl_1_mux_self_DataOut <= to_unsigned(0, 8);
if bool(rtl_1_buf0_self_ValidOut) then
rtl_1_mux_self_ValidOut <= '1';
rtl_1_mux_self_DataOut <= rtl_1_buf0_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin0 <= '1';
end if;
elsif bool(rtl_1_buf1_self_ValidOut) then
rtl_1_mux_self_ValidOut <= '1';
rtl_1_mux_self_DataOut <= rtl_1_buf1_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin1 <= '1';
end if;
elsif bool(rtl_1_buf2_self_ValidOut) then
rtl_1_mux_self_ValidOut <= '1';
rtl_1_mux_self_DataOut <= rtl_1_buf2_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin2 <= '1';
end if;
elsif bool(rtl_1_buf3_self_ValidOut) then
rtl_1_mux_self_ValidOut <= '1';
rtl_1_mux_self_DataOut <= rtl_1_buf3_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin3 <= '1';
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_MUX_MUX;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUFO_SMCOMB: process (ReadyOut, rtl_1_mux_self_ValidOut, rtl_1_bufo_smp) is
begin
rtl_1_buforeadyin <= '0';
ValidOut <= '0';
rtl_1_bufo_ldbuf <= '0';
case rtl_1_bufo_smp is
when BUF_FREE =>
rtl_1_buforeadyin <= '1';
if bool(rtl_1_mux_self_ValidOut) then
rtl_1_bufo_smn <= BUF_TAKEN;
rtl_1_bufo_ldbuf <= '1';
else
rtl_1_bufo_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
ValidOut <= '1';
if bool(ReadyOut) then
rtl_1_buforeadyin <= '1';
if bool(rtl_1_mux_self_ValidOut) then
rtl_1_bufo_smn <= BUF_TAKEN;
rtl_1_bufo_ldbuf <= '1';
else
rtl_1_bufo_smn <= BUF_FREE;
end if;
else
rtl_1_bufo_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_BUFO_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUFO_SMSYNC: process (Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_bufo_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_bufo_smp <= rtl_1_bufo_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUFO_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_BUFO_SMREG: process (Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_bufo_ldbuf) then
DataOut <= rtl_1_mux_self_DataOut;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_BUFO_SMREG;
end architecture MyHDL;
'''
Created on Nov 24, 2017
@author: josy
'''
from myhdl import Signal, intbv, enum, always_comb, always_seq, ResetSignal, toVHDL
def _copy( sig ):
if isinstance(sig.val, intbv):
return Signal(intbv(0)[len(sig):])
else:
return Signal(bool(0))
class Buffer(object):
''' a simple 1 register deep buffer '''
def __init__(self,Clk, Reset, DataIn, ValidIn, ReadyOut, ReadyIn=None, ValidOut=None, DataOut=None ):
self.Clk = Clk
self.Reset = Reset
self.DataIn = DataIn
self.ValidIn = ValidIn
self.ReadyOut = ReadyOut
self.ReadyIn = ReadyIn if ReadyIn is not None else Signal(bool(0))
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn)
def rtl(self):
''' the logic '''
buffer_state = enum("BUF_FREE", "BUF_TAKEN")
smp, smn = [Signal(buffer_state.BUF_FREE) for _ in range(2)]
ldbuf = Signal(bool(0))
@always_comb
def smcomb():
''' Buffer: the combinatorial part of the state-machine '''
self.ReadyIn.next = 0
self.ValidOut.next = 0
ldbuf.next = 0
if smp == buffer_state.BUF_FREE:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
elif smp == buffer_state.BUF_TAKEN:
self.ValidOut.next = 1
if self.ReadyOut:
self.ReadyIn.next = 1
if self.ValidIn:
smn.next = buffer_state.BUF_TAKEN
ldbuf.next = 1
else:
smn.next = buffer_state.BUF_FREE
else:
smn.next = buffer_state.BUF_TAKEN
@always_seq(self.Clk.posedge, reset=self.Reset)
def smsync():
''' Buffer: the synchronous part of the state-machine '''
smp.next = smn
@always_seq(self.Clk.posedge, reset=None)
def smreg():
''' Buffer: the registered part of the state-machine '''
if ldbuf:
self.DataOut.next = self.DataIn
return smcomb, smsync, smreg
class Mux4t1(object):
''' a naive 4 to 1 multiplexer '''
def __init__(self, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None
):
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
def rtl(self):
''' the logic '''
@always_comb
def mux():
self.ReadyIn0.next = 0
self.ReadyIn1.next = 0
self.ReadyIn2.next = 0
self.ReadyIn3.next = 0
self.ValidOut.next = 0
self.DataOut.next = 0
if self.ValidIn0:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn0
if self.ReadyOut:
self.ReadyIn0.next = 1
elif self.ValidIn1:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn1
if self.ReadyOut:
self.ReadyIn1.next = 1
elif self.ValidIn2:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn2
if self.ReadyOut:
self.ReadyIn2.next = 1
elif self.ValidIn3:
self.ValidOut.next = 1
self.DataOut.next = self.DataIn3
if self.ReadyOut:
self.ReadyIn3.next = 1
return mux
class StructuralDesign(object):
'''
a simple structural design
consisting of 4 input buffers, a 4 to 1 multiplexer and a single output buffer
|-------| |-
| | | -
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | | |-------|
|-------| | | | |
| |----| |----
|-------| | | | |
| | | | |-------|
----| |----| |
| | | |
|-------| | |
| |
|-------| | |
| | | |
----| |----| |
| | | -
|-------| |_-
'''
def __init__(self, Clk, Reset,
DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0=None, ReadyIn1=None, ReadyIn2=None, ReadyIn3=None,
DataOut=None, ValidOut=None
):
self.Clk = Clk
self.Reset = Reset
self.DataIn0 = DataIn0
self.ValidIn0 = ValidIn0
self.DataIn1 = DataIn1
self.ValidIn1 = ValidIn1
self.DataIn2 = DataIn2
self.ValidIn2 = ValidIn2
self.DataIn3 = DataIn3
self.ValidIn3 = ValidIn3
self.ReadyOut = ReadyOut
self.ReadyIn0 = ReadyIn0 if ReadyIn0 is not None else Signal(bool(0))
self.ReadyIn1 = ReadyIn1 if ReadyIn1 is not None else Signal(bool(0))
self.ReadyIn2 = ReadyIn2 if ReadyIn2 is not None else Signal(bool(0))
self.ReadyIn3 = ReadyIn3 if ReadyIn3 is not None else Signal(bool(0))
self.DataOut = DataOut if DataOut is not None else _copy(DataIn0)
self.ValidOut = ValidOut if ValidOut is not None else Signal(bool(0))
def rtl(self):
''' the *structural* logic '''
# unfortunately we still need to declare *forward* Signals
# but we can remedy that later
muxreadyin0 = Signal(bool(0))
muxreadyin1 = Signal(bool(0))
muxreadyin2 = Signal(bool(0))
muxreadyin3 = Signal(bool(0))
buforeadyin = Signal(bool(0))
buf0 = Buffer(self.Clk, self.Reset, self.DataIn0, self.ValidIn0, muxreadyin0, self.ReadyIn0)
buf1 = Buffer(self.Clk, self.Reset, self.DataIn1, self.ValidIn1, muxreadyin1, self.ReadyIn1)
buf2 = Buffer(self.Clk, self.Reset, self.DataIn2, self.ValidIn2, muxreadyin2, self.ReadyIn2)
buf3 = Buffer(self.Clk, self.Reset, self.DataIn3, self.ValidIn3, muxreadyin3, self.ReadyIn3)
mux = Mux4t1(buf0.DataOut, buf0.ValidOut,
buf1.DataOut, buf1.ValidOut,
buf2.DataOut, buf2.ValidOut,
buf3.DataOut, buf3.ValidOut,
buforeadyin,
muxreadyin0, muxreadyin1, muxreadyin2, muxreadyin3
)
bufo = Buffer(self.Clk, self.Reset, mux.DataOut, mux.ValidOut, self.ReadyOut, buforeadyin, self.ValidOut, self.DataOut)
# now we still have to collect the rtl
buf0rtl = buf0.rtl()
buf1rtl = buf1.rtl()
buf2rtl = buf2.rtl()
buf3rtl = buf3.rtl()
muxrtl = mux.rtl()
bufortl = bufo.rtl()
return buf0rtl, buf1rtl, buf2rtl, buf3rtl, muxrtl, bufortl
if __name__ == '__main__':
# unfortunately we need to wrap the *main* class in a function ...
def top_structuraldesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut):
return StructuralDesign(Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut).rtl()
def convert():
Clk = Signal(bool(0))
Reset = ResetSignal(0, 1, True)
DataIn0 = Signal(intbv(0)[8:])
ValidIn0 = Signal(bool(0))
DataIn1 = Signal(intbv(0)[8:])
ValidIn1 = Signal(bool(0))
DataIn2 = Signal(intbv(0)[8:])
ValidIn2 = Signal(bool(0))
DataIn3 = Signal(intbv(0)[8:])
ValidIn3 = Signal(bool(0))
ReadyOut = Signal(bool(0))
ReadyIn0 = Signal(bool(0))
ReadyIn1 = Signal(bool(0))
ReadyIn2 = Signal(bool(0))
ReadyIn3 = Signal(bool(0))
DataOut = Signal(intbv(0)[8:])
ValidOut = Signal(bool(0))
toVHDL.standard = '2008'
toVHDL.no_initial_values = True
toVHDL(top_structuraldesign, Clk, Reset, DataIn0, ValidIn0,
DataIn1, ValidIn1,
DataIn2, ValidIn2,
DataIn3, ValidIn3,
ReadyOut,
ReadyIn0, ReadyIn1, ReadyIn2, ReadyIn3,
DataOut, ValidOut)
convert()
-- File: top_structuraldesign.vhd
-- Generated by MyHDL 1.0dev
-- Date: Fri Nov 24 20:27:59 2017
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_10.all;
entity top_structuraldesign is
port(
Clk : in std_logic;
Reset : in std_logic;
DataIn0 : in unsigned(7 downto 0);
ValidIn0 : in std_logic;
DataIn1 : in unsigned(7 downto 0);
ValidIn1 : in std_logic;
DataIn2 : in unsigned(7 downto 0);
ValidIn2 : in std_logic;
DataIn3 : in unsigned(7 downto 0);
ValidIn3 : in std_logic;
ReadyOut : in std_logic;
ReadyIn0 : out std_logic;
ReadyIn1 : out std_logic;
ReadyIn2 : out std_logic;
ReadyIn3 : out std_logic;
DataOut : out unsigned(7 downto 0);
ValidOut : out std_logic
);
end entity top_structuraldesign;
architecture MyHDL of top_structuraldesign is
type t_enum_buffer_state_1 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_2 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_3 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_4 is (
BUF_FREE,
BUF_TAKEN
);
type t_enum_buffer_state_5 is (
BUF_FREE,
BUF_TAKEN
);
signal rtl_1_muxreadyin1 : std_logic;
signal rtl_1_buforeadyin : std_logic;
signal rtl_1_muxreadyin3 : std_logic;
signal rtl_1_muxreadyin2 : std_logic;
signal rtl_1_muxreadyin0 : std_logic;
signal rtl_1_rtl_1_self_ValidOut : std_logic;
signal rtl_1_rtl_1_smn : t_enum_buffer_state_1;
signal rtl_1_rtl_1_ldbuf : std_logic;
signal rtl_1_rtl_1_smp : t_enum_buffer_state_1;
signal rtl_1_rtl_1_self_DataOut : unsigned(7 downto 0);
signal rtl_1_rtl_1_self_ValidOut : std_logic;
signal rtl_1_rtl_1_smn : t_enum_buffer_state_2;
signal rtl_1_rtl_1_ldbuf : std_logic;
signal rtl_1_rtl_1_smp : t_enum_buffer_state_2;
signal rtl_1_rtl_1_self_DataOut : unsigned(7 downto 0);
signal rtl_1_rtl_1_self_ValidOut : std_logic;
signal rtl_1_rtl_1_smn : t_enum_buffer_state_3;
signal rtl_1_rtl_1_ldbuf : std_logic;
signal rtl_1_rtl_1_smp : t_enum_buffer_state_3;
signal rtl_1_rtl_1_self_DataOut : unsigned(7 downto 0);
signal rtl_1_rtl_1_self_ValidOut : std_logic;
signal rtl_1_rtl_1_smn : t_enum_buffer_state_4;
signal rtl_1_rtl_1_ldbuf : std_logic;
signal rtl_1_rtl_1_smp : t_enum_buffer_state_4;
signal rtl_1_rtl_1_self_DataOut : unsigned(7 downto 0);
signal rtl_1_rtl_1_self_ValidOut : std_logic;
signal rtl_1_rtl_1_self_DataOut : unsigned(7 downto 0);
signal rtl_1_rtl_1_smn : t_enum_buffer_state_5;
signal rtl_1_rtl_1_ldbuf : std_logic;
signal rtl_1_rtl_1_smp : t_enum_buffer_state_5;
begin
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB : process(rtl_1_muxreadyin0, ValidIn0, rtl_1_rtl_1_smp) is
begin
ReadyIn0 <= '0';
rtl_1_rtl_1_self_ValidOut <= '0';
rtl_1_rtl_1_ldbuf <= '0';
case rtl_1_rtl_1_smp is
when BUF_FREE =>
ReadyIn0 <= '1';
if bool(ValidIn0) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_rtl_1_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin0) then
ReadyIn0 <= '1';
if bool(ValidIn0) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
else
rtl_1_rtl_1_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC : process(Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_rtl_1_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_rtl_1_smp <= rtl_1_rtl_1_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG : process(Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_rtl_1_ldbuf) then
rtl_1_rtl_1_self_DataOut <= DataIn0;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB : process(rtl_1_muxreadyin1, ValidIn1, rtl_1_rtl_1_smp) is
begin
ReadyIn1 <= '0';
rtl_1_rtl_1_self_ValidOut <= '0';
rtl_1_rtl_1_ldbuf <= '0';
case rtl_1_rtl_1_smp is
when BUF_FREE =>
ReadyIn1 <= '1';
if bool(ValidIn1) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_rtl_1_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin1) then
ReadyIn1 <= '1';
if bool(ValidIn1) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
else
rtl_1_rtl_1_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC : process(Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_rtl_1_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_rtl_1_smp <= rtl_1_rtl_1_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG : process(Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_rtl_1_ldbuf) then
rtl_1_rtl_1_self_DataOut <= DataIn1;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB : process(rtl_1_muxreadyin2, ValidIn2, rtl_1_rtl_1_smp) is
begin
ReadyIn2 <= '0';
rtl_1_rtl_1_self_ValidOut <= '0';
rtl_1_rtl_1_ldbuf <= '0';
case rtl_1_rtl_1_smp is
when BUF_FREE =>
ReadyIn2 <= '1';
if bool(ValidIn2) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_rtl_1_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin2) then
ReadyIn2 <= '1';
if bool(ValidIn2) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
else
rtl_1_rtl_1_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC : process(Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_rtl_1_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_rtl_1_smp <= rtl_1_rtl_1_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG : process(Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_rtl_1_ldbuf) then
rtl_1_rtl_1_self_DataOut <= DataIn2;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB : process(rtl_1_muxreadyin3, ValidIn3, rtl_1_rtl_1_smp) is
begin
ReadyIn3 <= '0';
rtl_1_rtl_1_self_ValidOut <= '0';
rtl_1_rtl_1_ldbuf <= '0';
case rtl_1_rtl_1_smp is
when BUF_FREE =>
ReadyIn3 <= '1';
if bool(ValidIn3) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
rtl_1_rtl_1_self_ValidOut <= '1';
if bool(rtl_1_muxreadyin3) then
ReadyIn3 <= '1';
if bool(ValidIn3) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
else
rtl_1_rtl_1_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC : process(Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_rtl_1_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_rtl_1_smp <= rtl_1_rtl_1_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG : process(Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_rtl_1_ldbuf) then
rtl_1_rtl_1_self_DataOut <= DataIn3;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG;
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_MUX : process(rtl_1_buforeadyin, rtl_1_rtl_1_self_DataOut, rtl_1_rtl_1_self_ValidOut) is
begin
rtl_1_muxreadyin0 <= '0';
rtl_1_muxreadyin1 <= '0';
rtl_1_muxreadyin2 <= '0';
rtl_1_muxreadyin3 <= '0';
rtl_1_rtl_1_self_ValidOut <= '0';
rtl_1_rtl_1_self_DataOut <= to_unsigned(0, 8);
if bool(rtl_1_rtl_1_self_ValidOut) then
rtl_1_rtl_1_self_ValidOut <= '1';
rtl_1_rtl_1_self_DataOut <= rtl_1_rtl_1_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin0 <= '1';
end if;
elsif bool(rtl_1_rtl_1_self_ValidOut) then
rtl_1_rtl_1_self_ValidOut <= '1';
rtl_1_rtl_1_self_DataOut <= rtl_1_rtl_1_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin1 <= '1';
end if;
elsif bool(rtl_1_rtl_1_self_ValidOut) then
rtl_1_rtl_1_self_ValidOut <= '1';
rtl_1_rtl_1_self_DataOut <= rtl_1_rtl_1_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin2 <= '1';
end if;
elsif bool(rtl_1_rtl_1_self_ValidOut) then
rtl_1_rtl_1_self_ValidOut <= '1';
rtl_1_rtl_1_self_DataOut <= rtl_1_rtl_1_self_DataOut;
if bool(rtl_1_buforeadyin) then
rtl_1_muxreadyin3 <= '1';
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_MUX;
-- Buffer: the combinatorial part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB : process(ReadyOut, rtl_1_rtl_1_self_ValidOut, rtl_1_rtl_1_smp) is
begin
rtl_1_buforeadyin <= '0';
ValidOut <= '0';
rtl_1_rtl_1_ldbuf <= '0';
case rtl_1_rtl_1_smp is
when BUF_FREE =>
rtl_1_buforeadyin <= '1';
if bool(rtl_1_rtl_1_self_ValidOut) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
when others => -- BUF_TAKEN
ValidOut <= '1';
if bool(ReadyOut) then
rtl_1_buforeadyin <= '1';
if bool(rtl_1_rtl_1_self_ValidOut) then
rtl_1_rtl_1_smn <= BUF_TAKEN;
rtl_1_rtl_1_ldbuf <= '1';
else
rtl_1_rtl_1_smn <= BUF_FREE;
end if;
else
rtl_1_rtl_1_smn <= BUF_TAKEN;
end if;
end case;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMCOMB;
-- Buffer: the synchronous part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC : process(Clk, Reset) is
begin
if (Reset = '1') then
rtl_1_rtl_1_smp <= BUF_FREE;
elsif rising_edge(Clk) then
rtl_1_rtl_1_smp <= rtl_1_rtl_1_smn;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMSYNC;
-- Buffer: the registered part of the state-machine
TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG : process(Clk) is
begin
if rising_edge(Clk) then
if bool(rtl_1_rtl_1_ldbuf) then
DataOut <= rtl_1_rtl_1_self_DataOut;
end if;
end if;
end process TOP_STRUCTURALDESIGN_RTL_1_RTL_1_SMREG;
end architecture MyHDL;
-- File: top_structuraldesign.vhd
-- Generated by MyHDL 1.0dev
-- BEWARE: peppered with Array, StructType,
-- advanced ShadowSignal functionality, and more
-- by Josy Boelen (josyb)
--
-- Date: Fri Nov 24 20:27:39 2017
-- synthesis VHDL_2008
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;
use work.pck_myhdl_10.all;
entity top_structuraldesign is
port (
Clk : in std_logic;
Reset : in std_logic;
DataIn0 : in unsigned(7 downto 0);
ValidIn0 : in std_logic;
DataIn1 : in unsigned(7 downto 0);
ValidIn1 : in std_logic;
DataIn2 : in unsigned(7 downto 0);
ValidIn2 : in std_logic;
DataIn3 : in unsigned(7 downto 0);
ValidIn3 : in std_logic;
ReadyOut : in std_logic;
ReadyIn0 : out std_logic;
ReadyIn1 : out std_logic;
ReadyIn2 : out std_logic;
ReadyIn3 : out std_logic;
DataOut : out unsigned(7 downto 0);
ValidOut : out std_logic
);
end entity top_structuraldesign;
architecture MyHDL of top_structuraldesign is
type e_buffer_state is (
BUF_FREE,
BUF_TAKEN
);
signal buf0_ldbuf : std_logic;
signal buf0_smn : e_buffer_state;
signal buf0_smp : e_buffer_state;
signal buf1_ldbuf : std_logic;
signal buf1_smn : e_buffer_state;
signal buf1_smp : e_buffer_state;
signal buf2_ldbuf : std_logic;
signal buf2_smn : e_buffer_state;
signal buf2_smp : e_buffer_state;
signal buf3_ldbuf : std_logic;
signal buf3_smn : e_buffer_state;
signal buf3_smp : e_buffer_state;
signal bufo_DataIn : unsigned(7 downto 0);
signal bufo_ValidIn : std_logic;
signal bufo_ldbuf : std_logic;
signal bufo_smn : e_buffer_state;
signal bufo_smp : e_buffer_state;
signal buforeadyin : std_logic;
signal mux_DataIn0 : unsigned(7 downto 0);
signal mux_DataIn1 : unsigned(7 downto 0);
signal mux_DataIn2 : unsigned(7 downto 0);
signal mux_DataIn3 : unsigned(7 downto 0);
signal mux_ValidIn0 : std_logic;
signal mux_ValidIn1 : std_logic;
signal mux_ValidIn2 : std_logic;
signal mux_ValidIn3 : std_logic;
signal muxreadyin0 : std_logic;
signal muxreadyin1 : std_logic;
signal muxreadyin2 : std_logic;
signal muxreadyin3 : std_logic;
begin
-- Buffer: the combinatorial part of the state-machine
buf0_smcomb: process ( all ) is
begin
ReadyIn0 <= '0';
mux_ValidIn0 <= '0';
buf0_ldbuf <= '0';
case buf0_smp is
when BUF_FREE =>
ReadyIn0 <= '1';
if bool(ValidIn0) then
buf0_smn <= BUF_TAKEN;
buf0_ldbuf <= '1';
else
buf0_smn <= BUF_FREE;
end if;
when BUF_TAKEN =>
mux_ValidIn0 <= '1';
if bool(muxreadyin0) then
ReadyIn0 <= '1';
if bool(ValidIn0) then
buf0_smn <= BUF_TAKEN;
buf0_ldbuf <= '1';
else
buf0_smn <= BUF_FREE;
end if;
else
buf0_smn <= BUF_TAKEN;
end if;
end case;
end process buf0_smcomb;
-- Buffer: the synchronous part of the state-machine
buf0_smsync: process (Clk, Reset) is
begin
if (Reset = '1') then
buf0_smp <= BUF_FREE;
elsif rising_edge(Clk) then
buf0_smp <= buf0_smn;
end if;
end process buf0_smsync;
-- Buffer: the registered part of the state-machine
buf0_smreg: process (Clk) is
begin
if rising_edge(Clk) then
if bool(buf0_ldbuf) then
mux_DataIn0 <= DataIn0;
end if;
end if;
end process buf0_smreg;
-- Buffer: the combinatorial part of the state-machine
buf1_smcomb: process ( all ) is
begin
ReadyIn1 <= '0';
mux_ValidIn1 <= '0';
buf1_ldbuf <= '0';
case buf1_smp is
when BUF_FREE =>
ReadyIn1 <= '1';
if bool(ValidIn1) then
buf1_smn <= BUF_TAKEN;
buf1_ldbuf <= '1';
else
buf1_smn <= BUF_FREE;
end if;
when BUF_TAKEN =>
mux_ValidIn1 <= '1';
if bool(muxreadyin1) then
ReadyIn1 <= '1';
if bool(ValidIn1) then
buf1_smn <= BUF_TAKEN;
buf1_ldbuf <= '1';
else
buf1_smn <= BUF_FREE;
end if;
else
buf1_smn <= BUF_TAKEN;
end if;
end case;
end process buf1_smcomb;
-- Buffer: the synchronous part of the state-machine
buf1_smsync: process (Clk, Reset) is
begin
if (Reset = '1') then
buf1_smp <= BUF_FREE;
elsif rising_edge(Clk) then
buf1_smp <= buf1_smn;
end if;
end process buf1_smsync;
-- Buffer: the registered part of the state-machine
buf1_smreg: process (Clk) is
begin
if rising_edge(Clk) then
if bool(buf1_ldbuf) then
mux_DataIn1 <= DataIn1;
end if;
end if;
end process buf1_smreg;
-- Buffer: the combinatorial part of the state-machine
buf2_smcomb: process ( all ) is
begin
ReadyIn2 <= '0';
mux_ValidIn2 <= '0';
buf2_ldbuf <= '0';
case buf2_smp is
when BUF_FREE =>
ReadyIn2 <= '1';
if bool(ValidIn2) then
buf2_smn <= BUF_TAKEN;
buf2_ldbuf <= '1';
else
buf2_smn <= BUF_FREE;
end if;
when BUF_TAKEN =>
mux_ValidIn2 <= '1';
if bool(muxreadyin2) then
ReadyIn2 <= '1';
if bool(ValidIn2) then
buf2_smn <= BUF_TAKEN;
buf2_ldbuf <= '1';
else
buf2_smn <= BUF_FREE;
end if;
else
buf2_smn <= BUF_TAKEN;
end if;
end case;
end process buf2_smcomb;
-- Buffer: the synchronous part of the state-machine
buf2_smsync: process (Clk, Reset) is
begin
if (Reset = '1') then
buf2_smp <= BUF_FREE;
elsif rising_edge(Clk) then
buf2_smp <= buf2_smn;
end if;
end process buf2_smsync;
-- Buffer: the registered part of the state-machine
buf2_smreg: process (Clk) is
begin
if rising_edge(Clk) then
if bool(buf2_ldbuf) then
mux_DataIn2 <= DataIn2;
end if;
end if;
end process buf2_smreg;
-- Buffer: the combinatorial part of the state-machine
buf3_smcomb: process ( all ) is
begin
ReadyIn3 <= '0';
mux_ValidIn3 <= '0';
buf3_ldbuf <= '0';
case buf3_smp is
when BUF_FREE =>
ReadyIn3 <= '1';
if bool(ValidIn3) then
buf3_smn <= BUF_TAKEN;
buf3_ldbuf <= '1';
else
buf3_smn <= BUF_FREE;
end if;
when BUF_TAKEN =>
mux_ValidIn3 <= '1';
if bool(muxreadyin3) then
ReadyIn3 <= '1';
if bool(ValidIn3) then
buf3_smn <= BUF_TAKEN;
buf3_ldbuf <= '1';
else
buf3_smn <= BUF_FREE;
end if;
else
buf3_smn <= BUF_TAKEN;
end if;
end case;
end process buf3_smcomb;
-- Buffer: the synchronous part of the state-machine
buf3_smsync: process (Clk, Reset) is
begin
if (Reset = '1') then
buf3_smp <= BUF_FREE;
elsif rising_edge(Clk) then
buf3_smp <= buf3_smn;
end if;
end process buf3_smsync;
-- Buffer: the registered part of the state-machine
buf3_smreg: process (Clk) is
begin
if rising_edge(Clk) then
if bool(buf3_ldbuf) then
mux_DataIn3 <= DataIn3;
end if;
end if;
end process buf3_smreg;
mux_mux: process ( all ) is
begin
muxreadyin0 <= '0';
muxreadyin1 <= '0';
muxreadyin2 <= '0';
muxreadyin3 <= '0';
bufo_ValidIn <= '0';
bufo_DataIn <= to_unsigned(0, 8);
if bool(mux_ValidIn0) then
bufo_ValidIn <= '1';
bufo_DataIn <= mux_DataIn0;
if bool(buforeadyin) then
muxreadyin0 <= '1';
end if;
elsif bool(mux_ValidIn1) then
bufo_ValidIn <= '1';
bufo_DataIn <= mux_DataIn1;
if bool(buforeadyin) then
muxreadyin1 <= '1';
end if;
elsif bool(mux_ValidIn2) then
bufo_ValidIn <= '1';
bufo_DataIn <= mux_DataIn2;
if bool(buforeadyin) then
muxreadyin2 <= '1';
end if;
elsif bool(mux_ValidIn3) then
bufo_ValidIn <= '1';
bufo_DataIn <= mux_DataIn3;
if bool(buforeadyin) then
muxreadyin3 <= '1';
end if;
end if;
end process mux_mux;
-- Buffer: the combinatorial part of the state-machine
bufo_smcomb: process ( all ) is
begin
buforeadyin <= '0';
ValidOut <= '0';
bufo_ldbuf <= '0';
case bufo_smp is
when BUF_FREE =>
buforeadyin <= '1';
if bool(bufo_ValidIn) then
bufo_smn <= BUF_TAKEN;
bufo_ldbuf <= '1';
else
bufo_smn <= BUF_FREE;
end if;
when BUF_TAKEN =>
ValidOut <= '1';
if bool(ReadyOut) then
buforeadyin <= '1';
if bool(bufo_ValidIn) then
bufo_smn <= BUF_TAKEN;
bufo_ldbuf <= '1';
else
bufo_smn <= BUF_FREE;
end if;
else
bufo_smn <= BUF_TAKEN;
end if;
end case;
end process bufo_smcomb;
-- Buffer: the synchronous part of the state-machine
bufo_smsync: process (Clk, Reset) is
begin
if (Reset = '1') then
bufo_smp <= BUF_FREE;
elsif rising_edge(Clk) then
bufo_smp <= bufo_smn;
end if;
end process bufo_smsync;
-- Buffer: the registered part of the state-machine
bufo_smreg: process (Clk) is
begin
if rising_edge(Clk) then
if bool(bufo_ldbuf) then
DataOut <= bufo_DataIn;
end if;
end if;
end process bufo_smreg;
end architecture MyHDL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment