[myhdl-list] Re: toVerilog and memories
Brought to you by:
jandecaluwe
From: Jan D. <ja...@ja...> - 2005-07-07 22:04:31
|
Tom Dillon wrote: > I am trying to model generate Verilog for some simple memories. For > example: > > def ram(dout,din,addr,we,clk=None,depth=4) : > memL = [Signal(intbv(0,min=0,max=2**8)) for i in range(depth)] > while 1: > yield posedge(clk) > if we: > memL[addr] = din.val > dout.next = memL[addr] > > I want addr to be a Signal as well. I get an error that it needs to be > an int. Use int(addr) to convert it to an int. (Signals support this function.) > If I use the value of addr, then it simulates fine but I get a list > comprehension error when running it through toVerilog. > > Is there a way to do this and get it through toVerilog? Not with the current version. What would be needed is support to map a list comprehension to a verilog memory. I haven´t tackled this yet, partly because verilog memories have all kinds of limitations that obfuscate what can and what should be supported. Newer Verilogs (2001 and SystemVerilog) seem to do away with limitations, but (as always with Verilog) things aren´t very clear. We will need expertise to move forward carefully. As to your model, I see the value, and how it could be done. Basically, we would need to support a list comprehension internally in a generator, and map it to a local Verilog memory. I´ll discuss the details to try to come up with an implementation spec. First, why a list of Signals? In MyHDL philosophy (as in VHDL) you would use plain variables internally. In your model, you actually use it like that, otherwise the assignment would read memL[int(addr)].next = din In Verilog 1995, you can only have a memory out of regs, so the natural base type for the supported list comprehension would be an intbv (and not an int for example). Therefore, only the following kind of list comprehension would be supported: memL = [intbv(0)[8:] for i in range(depth)] Secondly, toVerilog has to able to infer and use type and bit width information, or at least be sure that the simulation will take care of it. Because of this, an intbv has always to be assigned by modifying its contents, not by overriding it: a = intbv(0)[8:] a = 500 // not supported by toVerilog a[:] = 500 // supported (note that simulation will flag an error) Similarly, the memory assignment would have to look as follows: memL[int(addr)][:] = din // OK for toVerilog while the following would not work: memL[int(addr)] = din // not OK for toVerilog Currently, toVerilog always uses an explicit bit width in the Verilog output. For example: a = intbv(0)[8:] a[4:] = c a[:] = d is mapped to: reg [7:0] a; a[3:0] = c; a[7:0] = d; However, Verilog 1995 doesn´t permit bit or slice access to memory elements. The workaround would be to introduce a special case for the special [:] slice. For example: a[:] = c memL[int(addr)][:] = din would then be mapped to: a = c; memL[addr] = din; Now, what to do with true slices and indexing in the MyHDL code? Even though Verilog 1995 doesn´t support it on memories, newer Verilogs (2001 and SystemVerilog) do (I think). So, I would just do the conversion in the obvious way and leave it to the user to change his MyHDL code if his Verilog doesn´t support it. I don´t want to introduce Verilog conversion modes - it´s a street without and end (and probably circular in fact :-)). Ok - so much for my initial feedback. Other feedback, thoughts, experiments, welcome. Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium Using Python as a hardware description language: http://jandecaluwe.com/Tools/MyHDL/Overview.html |