Re: [myhdl-list] address decoder in myHDL
Brought to you by:
jandecaluwe
From: Christopher F. <chr...@gm...> - 2012-12-02 05:07:00
|
On 12/1/12 7:00 PM, Aaron Ferrucci wrote: > I'm trying to implement a conceptually simple, but > Verilog/VHDL-unfriendly module in myHDL. So far I've had success with > some simplified forms of the module, but not with the full-fledged spec. > > The module, an address decoder, takes as input an n-bit address input > signal and outputs an m-bit decoded value which can be considered as the > binary encoding of a selected slave, according to which of several > address ranges the address falls in. If no address range matches, a > default value is output. The set of decoded address ranges and their > output encodings are parameters of the generator. Here's what one > generator instance could look like: > If I understood the requirements, this is the solution I came up with. Didn't have a lot of time this is a rough first pass. I re-phrased the requirements at the beginning, I might be way off what you are trying to achieve. The MyHDL works as expected but I didn't verify the converted HDL works as expected. from myhdl import * from random import randint from pprint import pprint # Create an m-bit address range based on an n-bit address. # If there is no range match a default is output. The # address ranges are passed to the module. def addr_range_decoder(addr, select, Ranges=[(),(),()], Default=0xFF): assert len(Ranges) > 0 assert len(Ranges[0]) == 3 # Use the elaboration to put the Ranges into a usable form Nranges = len(Ranges) lr = tuple([ss[0] for ss in Ranges]) # low address hr = tuple([ss[1] for ss in Ranges]) # high address sel = tuple([ss[2] for ss in Ranges]) # select value for # the address range print(Nranges, len(lr), len(hr), len(sel)) @always_comb def hdl_decoder(): vsel = Default for ii in range(Nranges): laddr = lr[ii] haddr = hr[ii] if addr >= laddr and addr < haddr: vsel = sel[ii] select.next = vsel return hdl_decoder def test(): NbitOpt = (8,16,20,24,32,36,48) Nbit = NbitOpt[randint(0,len(NbitOpt)-1)] Mbit = randint(2,8) print("Nbit %d, Mbit %d" % (Nbit,Mbit)) d = (2**Nbit)/(2**Mbit) Ranges = [] Laddr = {} Nr = 2**Mbit for ii in range(Nr-3): la = ii*d ha = (ii*d+d)-1 sv = ii Ranges.append((la,ha,sv)) Laddr[la] = (la,ha,sv) pprint(Ranges) addr = Signal(intbv(0)[Nbit:]) select = Signal(intbv(0)[Mbit:]) tb_dut = addr_range_decoder(addr, select, Ranges=Ranges, Default=select.max-1) TestAddrs = [randint(0,2**Nbit-1) for ii in range(32)] @instance def tb_stim(): for taddr in TestAddrs: addr.next = taddr yield delay(10) print(' addr %12X sel %X' % (addr, select)) baddr = taddr - (taddr%d) if Laddr.has_key(baddr): tsel = Laddr[baddr][2] else: tsel = select.max-1 assert tsel == select raise StopSimulation Simulation((tb_dut, tb_stim)).run() toVerilog(addr_range_decoder, addr, select, Ranges=Ranges, Default=select.max-1) toVHDL(addr_range_decoder, addr, select, Ranges=Ranges, Default=select.max-1) if __name__ == '__main__': test() |