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()