Re: [myhdl-list] address decoder in myHDL
Brought to you by:
jandecaluwe
From: Aaron F. <aar...@gm...> - 2012-12-02 23:41:21
|
Thanks Christopher! Your solution works just fine. Now that I see how you did it, it looks obvious :) I tested the generated Verilog in Modelsim (6.6d) and ran it through Quartus synthesis (11.1sp1), and everything looks ok. -Aaron On Sat, Dec 1, 2012 at 9:06 PM, Christopher Felton <chr...@gm...>wrote: > 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() > > > > > > > > ------------------------------------------------------------------------------ > Keep yourself connected to Go Parallel: > DESIGN Expert tips on starting your parallel project right. > http://goparallel.sourceforge.net/ > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |