return reg1rtl, reg2rtl, reg3rtl, reg4rtl
January 15, 2016 ยท View on GitHub
''' Created on 29 Dec 2015
@author: Josy ''' from future import print_function
import random
import myhdl from Utilities import hdlutils
class Register( object): ''' a simple class with limited functionality ''' def init(self, WIDTH_D, Clk, Data, Shift, Result=None): self.width_d = WIDTH_D self.clk = Clk self.shift = Shift self.data = Data # imagine that 'Data' can be any type (almost) if Result is None: # in this particular case the Result is of the same type of the Data # so we resort to getting a new object of that type # but it could be any type, except 'interface' # unless you write a copy() attribute for every new interface # I added this copy() attribute to the _Signal class ... self.result = self.data.copy() # if using the 'master' branch of MyHDL: you can replace the above line with: # self.result = myhdl.Signal( Data._val )
else:
self.result = Result
def rtl(self):
''' the actual rtl is an elaborate way to code a 'simple' register
this is what gets converted, eventually '''
lqn = myhdl.Signal( myhdl.intbv(0)[self.width_d:])
@myhdl.always_comb
def regcomb():
''' the combinatorial part of the rtl'''
if self.shift:
lqn.next = self.data[:1]
else:
lqn.next = self.data
@myhdl.always_seq( self.clk.posedge, reset= None)
def regreg():
''' the registered part of the rtl'''
self.result.next = lqn
return regcomb, regreg
def mregister(WIDTH_D, Clk, D, Shift, Q): ''' the top level module is 'structural' we simply concatenate four modules ''' # instantiate the four sub-modules reg1 = Register(WIDTH_D, Clk, D, Shift) reg2 = Register(WIDTH_D, Clk, reg1.result, Shift) reg3 = Register(WIDTH_D, Clk, reg2.result, Shift) reg4 = Register(WIDTH_D, Clk, reg3.result, Shift, Q)
# but we need to collect the generators
# we could automate that, like myhdl.instances()?
if RETURN_GENERATORS_METHOD == 'Append':
# this works
# but the 'original' names reg1, ... get replaced by inst0, inst1, ...
inst = []
inst.append(reg1.rtl())
inst.append(reg2.rtl())
inst.append(reg3.rtl())
inst.append(reg4.rtl())
return inst
elif RETURN_GENERATORS_METHOD == 'IntermediateObject':
# this works too
# but here also the 'original' names reg1, ... get replaced by inst0, inst1, ...
inst = reg1.rtl(), reg2.rtl(), reg3.rtl(), reg4.rtl()
return inst
elif RETURN_GENERATORS_METHOD == 'Direct':
# this throws an 'myhdl.ExtractHierarchyError: Inconsistent hierarchy - are all instances returned ?'
return reg1.rtl(), reg2.rtl(), reg3.rtl(), reg4.rtl()
elif RETURN_GENERATORS_METHOD == 'Indirect':
# this works as 'desired'
reg1rtl = reg1.rtl()
reg2rtl = reg2.rtl()
reg3rtl = reg3.rtl()
reg4rtl = reg4.rtl()
return reg1rtl, reg2rtl, reg3rtl, reg4rtl
return myhdl.instances()
elif RETURN_GENERATORS_METHOD == 'Named':
# this is a mixed success ...
# reg1rtl and reg3rtl are in the VHDL code,
# whereas reg2rtl and reg4rtl are replaced by inst1 and inst3 ...
inst = []
reg1rtl = reg1.rtl()
reg2rtl = reg2.rtl()
reg3rtl = reg3.rtl()
reg4rtl = reg4.rtl()
inst.append(reg1rtl)
inst.append(reg2rtl)
inst.append(reg3rtl)
inst.append(reg4rtl)
return inst
def tb_mregister(): ''' test bench not self-checking ... ''' Clk = myhdl.Signal( bool( 0 )) Shift = myhdl.Signal( bool( 0 )) D = myhdl.Signal(myhdl.intbv(0)[T_WIDTH_D:]) Q = myhdl.Signal(myhdl.intbv(0)[T_WIDTH_D:])
dut = mregister(T_WIDTH_D, Clk, D, Shift, Q)
ClkCount = myhdl.Signal(myhdl.intbv(0)[8:])
tCK = 20
random.seed('We want repeatable randomness')
@myhdl.instance
def clkgen():
yield hdlutils.genClk(Clk, tCK, ClkCount)
@myhdl.instance
def stimulusin():
Shift.next = 0
yield hdlutils.delayclks(Clk, tCK, 5)
for _ in range(16):
D.next = random.randint(0,2**T_WIDTH_D)
yield hdlutils.delayclks(Clk, tCK, 1)
yield hdlutils.delayclks(Clk, tCK, 5)
Shift.next = 1
for _ in range(16):
D.next = random.randint(0,2**T_WIDTH_D)
yield hdlutils.delayclks(Clk, tCK, 1)
yield hdlutils.delayclks(Clk, tCK, 5)
raise myhdl.StopSimulation
return dut, clkgen, stimulusin
def convert(): Clk = myhdl.Signal( bool( 0 )) Shift = myhdl.Signal( bool( 0 )) D = myhdl.Signal(myhdl.intbv(0)[T_WIDTH_D:]) Q = myhdl.Signal(myhdl.intbv(0)[T_WIDTH_D:])
myhdl.toVHDL( mregister, T_WIDTH_D, Clk, D, Shift, Q )
myhdl.toVerilog( mregister, T_WIDTH_D, Clk, D, Shift, Q )
if name == 'main': T_WIDTH_D = 8 RETURN_GENERATORS_METHOD = 'Indirect' # 'Append', 'Direct', 'Named', 'IntermediateObject' or 'Indirect' hdlutils.simulate(0, tb_mregister) convert()