myhdl-list Mailing List for MyHDL (Page 184)
Brought to you by:
jandecaluwe
You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(14) |
Nov
(4) |
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(1) |
Feb
(10) |
Mar
(19) |
Apr
(14) |
May
(1) |
Jun
(4) |
Jul
(10) |
Aug
|
Sep
(2) |
Oct
(7) |
Nov
(17) |
Dec
(12) |
| 2005 |
Jan
(6) |
Feb
(10) |
Mar
(17) |
Apr
(10) |
May
(9) |
Jun
(5) |
Jul
(26) |
Aug
(34) |
Sep
(10) |
Oct
(38) |
Nov
(71) |
Dec
(74) |
| 2006 |
Jan
(20) |
Feb
(20) |
Mar
(7) |
Apr
(2) |
May
(13) |
Jun
|
Jul
|
Aug
(4) |
Sep
(37) |
Oct
(43) |
Nov
(30) |
Dec
(33) |
| 2007 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
(30) |
Jun
(9) |
Jul
(1) |
Aug
|
Sep
(8) |
Oct
(13) |
Nov
|
Dec
(4) |
| 2008 |
Jan
(13) |
Feb
(46) |
Mar
(25) |
Apr
(7) |
May
(20) |
Jun
(73) |
Jul
(38) |
Aug
(47) |
Sep
(24) |
Oct
(18) |
Nov
(9) |
Dec
(36) |
| 2009 |
Jan
(31) |
Feb
(24) |
Mar
(73) |
Apr
(13) |
May
(47) |
Jun
(28) |
Jul
(36) |
Aug
(2) |
Sep
(5) |
Oct
(8) |
Nov
(16) |
Dec
(29) |
| 2010 |
Jan
(34) |
Feb
(18) |
Mar
(18) |
Apr
(5) |
May
|
Jun
(24) |
Jul
(53) |
Aug
(3) |
Sep
(18) |
Oct
(33) |
Nov
(19) |
Dec
(15) |
| 2011 |
Jan
(9) |
Feb
(4) |
Mar
(39) |
Apr
(213) |
May
(86) |
Jun
(46) |
Jul
(22) |
Aug
(11) |
Sep
(78) |
Oct
(59) |
Nov
(38) |
Dec
(24) |
| 2012 |
Jan
(9) |
Feb
(22) |
Mar
(89) |
Apr
(55) |
May
(222) |
Jun
(86) |
Jul
(57) |
Aug
(32) |
Sep
(49) |
Oct
(69) |
Nov
(12) |
Dec
(35) |
| 2013 |
Jan
(67) |
Feb
(39) |
Mar
(18) |
Apr
(42) |
May
(79) |
Jun
(1) |
Jul
(19) |
Aug
(18) |
Sep
(54) |
Oct
(79) |
Nov
(9) |
Dec
(26) |
| 2014 |
Jan
(30) |
Feb
(44) |
Mar
(26) |
Apr
(11) |
May
(39) |
Jun
(1) |
Jul
(89) |
Aug
(15) |
Sep
(7) |
Oct
(6) |
Nov
(20) |
Dec
(27) |
| 2015 |
Jan
(107) |
Feb
(106) |
Mar
(130) |
Apr
(90) |
May
(147) |
Jun
(28) |
Jul
(53) |
Aug
(16) |
Sep
(23) |
Oct
(7) |
Nov
|
Dec
(16) |
| 2016 |
Jan
(86) |
Feb
(41) |
Mar
(38) |
Apr
(31) |
May
(37) |
Jun
(11) |
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
(1) |
Nov
(5) |
Dec
(3) |
| 2017 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
(2) |
May
|
Jun
(3) |
Jul
(2) |
Aug
(2) |
Sep
(1) |
Oct
(2) |
Nov
(1) |
Dec
(1) |
| 2018 |
Jan
(1) |
Feb
(1) |
Mar
(7) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
| 2019 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
(1) |
May
(1) |
Jun
(2) |
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
(3) |
Dec
|
| 2020 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(3) |
| 2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
(11) |
| 2022 |
Jan
(7) |
Feb
(2) |
Mar
(1) |
Apr
|
May
|
Jun
(1) |
Jul
(3) |
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
| 2023 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2024 |
Jan
(1) |
Feb
(2) |
Mar
(4) |
Apr
(2) |
May
(2) |
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
(2) |
| 2025 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
(3) |
Oct
|
Nov
|
Dec
|
|
From: <dan...@we...> - 2005-08-16 09:34:09
|
Hi,
with the latest version of toVerilog I was able to implement a Dual-Port
RAM with synchronous read (read through) with Xilinx ISE, using XST for
synthesis.
According to the XST manual there are certain Verilog templates, if they
are recognized by XST it will implement them in block ram.
For example, for the Dual-Port RAM with synchronous read the Verilog
code should look like this:
----------------------------------------------------------------------
module raminfr (clk, we, a, dpra, di, spo, dpo);
input clk;
input we;
input [4:0] a;
input [4:0] dpra;
input [3:0] di;
output [3:0] spo;
output [3:0] dpo;
reg [3:0] ram [31:0];
reg [4:0] read_a;
reg [4:0] read_dpra;
always @(posedge clk) begin
if (we)
ram[a] <= di;
read_a <= a;
read_dpra <= dpra;
end
assign spo = ram[read_a];
assign dpo = ram[read_dpra];
endmodule
----------------------------------------------------------------------
I did the following implementation with MyHDL:
----------------------------------------------------------------------
def dp_ram_py(clk, we, addr, di, spo, dp_addr, dpo, d_width=8, a_width=2):
memL = [Signal(intbv(0)[d_width:]) for i in range(2**a_width)]
read_addr = Signal(intbv(0)[a_width:])
read_dp_addr = Signal(intbv(0)[a_width:])
def write(clk, we, addr, di, d_width=8, a_width=2):
while 1:
yield posedge(clk)
if we:
memL[int(addr)].next = di
read_addr.next = addr
read_dp_addr.next = dp_addr
def read(read_addr, spo, read_dp_addr, dpo):
def assign():
spo.next = memL[int(read_addr)]
dpo.next = memL[int(read_dp_addr)]
return always_comb(assign)
rd = read(read_addr, spo, read_dp_addr, dpo)
wr = write(clk, we, addr, di, d_width=8, a_width=2)
return rd,wr
----------------------------------------------------------------------
turning that into Verilog code with toVerilog and implementing it with
ISE, synthesis reported this:
=========================================================================
* HDL Synthesis *
=========================================================================
Synthesizing Unit <dp_ram>.
Related source file is ../../rtl/verilog/dp_ram.v.
Found 4x8-bit dual-port block RAM for signal <memL>.
-----------------------------------------------------------------------
| mode | write-first | |
| dual mode | write-first | |
| aspect ratio | 4-word x 8-bit | |
| clock | connected to signal <clk> | rise |
| dual clock | connected to signal <clk> | rise |
| write enable | connected to signal <we> | high |
| address | connected to signal <addr> | |
| dual address | connected to signal <dp_addr> | |
| data in | connected to signal <di> | |
| data out | connected to signal <spo> | |
| dual data out | connected to signal <dpo> | |
| ram_style | Auto | |
-----------------------------------------------------------------------
Summary:
inferred 1 RAM(s).
Unit <dp_ram> synthesized.
Cheers,
Guenter
|
|
From: Tom D. <td...@di...> - 2005-08-12 05:31:23
|
Jan, Thanks for the update. So far it is making memories properly including true dual port rams with separate always blocks. I will run some more cases over the next few days. One problem, it looks like all lists of signals are being mapped to memory structures in Verilog, even true lists of signals as described in 3.1.2 of the manual. This won't synthesize properly and causes some cosimulation problem, specifically slicing of one of the signals. Is it possible for you to distinguish between a list for memory and a true list of signals? Tom Jan Decaluwe wrote: > Hi all: > > Attached you find a snapshot of the myhdl development tree. The > goal is to implement RAM inference from toVerilog output. > > The purpose of this snapshot release is to get feedback from early > users that are willing to test this. As the implemented features are > especially useful in combination with the capabilities of external > tools, their feedback is essential. > > Release notes > ============= > > The requirements to infer RAM from toVerilog output were discussed > recently. Two features were implemented: > > 1. Support for lists of signals > ------------------------------- > Lists of Signals are now supported alongside Signals in the > hierarchy. They are mapped to Verilog memories. > > 2. Support to generate Verilog assign statements > ------------------------------------------------ > always_comb blocks that are simple enough are converted to a series of > assign statements, instead of a combinatorial always block. Note that > you do need to use always_comb for this feature; an explicit > combinatorial generator is not sufficient. > > Installation > ============ > > Several files have undergone changes; therefore the snapshot consists > of a complete myhdl package directory. This should be installed as a > replacement of the myhdl directory in the installed directory. > > This snapshot therefore contains several other (undocumented) features > and improvements outside the specific goal outlined above. Testers > should be aware of that and be careful, so that they can easily go > back if required. That being said, all the regression tests run fine, > of course. > > Implementation notes > ==================== > (Only for those who want to know more implementation details.) > > 1. Support for lists of signals > ------------------------------- > As always, I tried to make the implementation as general as > possible. Lists of Signals are now handled as a first-class object in > the hierarchy, alongside Signals. The Signal elements have the same > restrictions as ordinary Signals, and additional restrictions among > them. For example, they should all have the same type and bit width. > > In Python, it is easy to create lists that share elements. This can > obviously lead to problems in Verilog conversion. An attempt was made > to do meaningful things. Several error conditions were added and > checked to implement meaningful restrictions. But it is possible that > more will need to be done. > > I was pleasantly surprized to see that the existing > test_RandomScrambler.py test continues to run unmodified, but uses > memories in the Verilog output now. The usage of Lists of Signals in > that example is more sophisticated than for a single RAM inference, > showing that we may have an additional powerful feature now. > > 2. Support to generate Verilog assign statements > ------------------------------------------------ > A simple always_comb block is converted to Verilog assign > statements. It was reported that Xilinx tools need this to recognize > RAM templates. > > One criterium for "simpleness" is that the block only contains signal > assignments. However, this is not enough: for example, multiple > assignments to the same signal are perfectly valid code, but don't > qualify as simple. > > An additional point was that the signals driven by Verilog assignments > should be declared as wires. > > Regards, > > Jan > |
|
From: Jan D. <ja...@ja...> - 2005-08-09 23:17:03
|
-- 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 |
|
From: Jan D. <ja...@ja...> - 2005-08-09 19:05:48
|
Hi all: Attached you find a snapshot of the myhdl development tree. The goal is to implement RAM inference from toVerilog output. The purpose of this snapshot release is to get feedback from early users that are willing to test this. As the implemented features are especially useful in combination with the capabilities of external tools, their feedback is essential. Release notes ============= The requirements to infer RAM from toVerilog output were discussed recently. Two features were implemented: 1. Support for lists of signals ------------------------------- Lists of Signals are now supported alongside Signals in the hierarchy. They are mapped to Verilog memories. 2. Support to generate Verilog assign statements ------------------------------------------------ always_comb blocks that are simple enough are converted to a series of assign statements, instead of a combinatorial always block. Note that you do need to use always_comb for this feature; an explicit combinatorial generator is not sufficient. Installation ============ Several files have undergone changes; therefore the snapshot consists of a complete myhdl package directory. This should be installed as a replacement of the myhdl directory in the installed directory. This snapshot therefore contains several other (undocumented) features and improvements outside the specific goal outlined above. Testers should be aware of that and be careful, so that they can easily go back if required. That being said, all the regression tests run fine, of course. Implementation notes ==================== (Only for those who want to know more implementation details.) 1. Support for lists of signals ------------------------------- As always, I tried to make the implementation as general as possible. Lists of Signals are now handled as a first-class object in the hierarchy, alongside Signals. The Signal elements have the same restrictions as ordinary Signals, and additional restrictions among them. For example, they should all have the same type and bit width. In Python, it is easy to create lists that share elements. This can obviously lead to problems in Verilog conversion. An attempt was made to do meaningful things. Several error conditions were added and checked to implement meaningful restrictions. But it is possible that more will need to be done. I was pleasantly surprized to see that the existing test_RandomScrambler.py test continues to run unmodified, but uses memories in the Verilog output now. The usage of Lists of Signals in that example is more sophisticated than for a single RAM inference, showing that we may have an additional powerful feature now. 2. Support to generate Verilog assign statements ------------------------------------------------ A simple always_comb block is converted to Verilog assign statements. It was reported that Xilinx tools need this to recognize RAM templates. One criterium for "simpleness" is that the block only contains signal assignments. However, this is not enough: for example, multiple assignments to the same signal are perfectly valid code, but don't qualify as simple. An additional point was that the signals driven by Verilog assignments should be declared as wires. Regards, 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 |
|
From: Jan D. <ja...@ja...> - 2005-08-05 22:28:59
|
nicran wrote: > The platform is redhat linux enterprise version, simulator is LDV5.1 Ok. A linux platform, so pipes and environment variables should not give problems. I'm in the dark. The error would indicate that the simulator has exited immediately. So how can the simulaton then be correct? More details about what and how you simulate may be useful. Regards, Jan -- Jan Decaluwe - Resources bvba - http://jandecaluwe.com Losbergenlaan 16, B-3010 Leuven, Belgium |
|
From: Jan D. <ja...@ja...> - 2005-08-05 08:57:20
|
Tom Dillon wrote: > >> >> memL = [Signal(intbv(...)) for i in range(depth)] >> >> def wrLogic() : >> while 1: >> yield posedge(clk) >> if we: >> memL[int(wr_addr)].next = din >> >> def rdLogic() : >> while 1: >> yield posedge(clk) >> dout.next = memL[int(rd_addr)] > > > > In this example I could use rd_clk and wr_clk instead of clk twice? Definitely. > That looks very good, and I now better understand intbv vs. Signal. So > by definition, an intbv is a variable and Signal is a signal. Yes, but be careful to put them against each other like that. intbv is just one of the variable types that toVerilog can handle, others are int, bool, and enum. Likewise, toVerilog can handle Signals constructed from a number of base types. See also the manual 6.4.3: Supported types. It may also be a good idea to take a fresh look at the examples in 6.6. Especially enum usage in 6.6.4 should be of interest to FPGA designers. > I started > out thinking I could only use Signals if going through toVerilog. Certainly not. What happens is that variables and Signals should be used as in VHDL, and that variable assignment is mapped to blocking assignment, and signal assignment to non-blocking assignment. Regards, 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 |
|
From: nicran <ni...@gm...> - 2005-08-05 01:27:12
|
The platform is redhat linux enterprise version, simulator is LDV5.1 2005/8/5, Jan Decaluwe <ja...@ja...>: > nicran wrote: > > Hi, Jan, > > > > I got the following error message when using myhdl as HVL to > > co-simulate with verilog. The simulation result is correct. But this > > error message is quite annoying. Could you give me an explanation how > > to avoid this message? > > > > Thanks a lot! > > > > ERROR: no write pipe to myhdl >=20 > This indicates a fundamental problem with pipe creation or > with passing them to the simulator process through environment > variables. The simulator is supposed to exit immediately > when the pipe is not found, so I don't understand how > a simulation result could be correct. >=20 > What is your platform and what simulator are you using? >=20 > Jan >=20 > -- > 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 >=20 >=20 >=20 > ------------------------------------------------------- > SF.Net email is Sponsored by the Better Software Conference & EXPO > September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practic= es > Agile & Plan-Driven Development * Managing Projects & Teams * Testing & Q= A > Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
|
From: Tom D. <td...@di...> - 2005-08-04 19:56:55
|
Jan, >> memL = [intbv(0,min=dout._min,max=dout._max) for i in range(depth)] > > > Note that .min and .max are supported attributes of intbv's and > Signals - no need to use the private attributes. (This should never > be required - if there seems a need for it, let me know.) Thanks. > > memL = [Signal(intbv(...)) for i in range(depth)] > > def wrLogic() : > while 1: > yield posedge(clk) > if we: > memL[int(wr_addr)].next = din > > def rdLogic() : > while 1: > yield posedge(clk) > dout.next = memL[int(rd_addr)] In this example I could use rd_clk and wr_clk instead of clk twice? That looks very good, and I now better understand intbv vs. Signal. So by definition, an intbv is a variable and Signal is a signal. I started out thinking I could only use Signals if going through toVerilog. Tom |
|
From: Jan D. <ja...@ja...> - 2005-08-04 19:33:35
|
Tom Dillon wrote:
> Jan,
>
> How difficult to add the capability to handle the following?
See below for some qualifications to your proposal first and
if you agree.
I would like to come up with a general solution for RAM support,
also including a way to convert to assign statements for
simple combinatorial blocks, as discussed in other posts.
I'm working on this currently and I think it should be possible
to release something early next week.
> memL = [intbv(0,min=dout._min,max=dout._max) for i in range(depth)]
Note that .min and .max are supported attributes of intbv's and
Signals - no need to use the private attributes. (This should never
be required - if there seems a need for it, let me know.)
> def wrLogic() :
> while 1:
> yield posedge(clk)
> if we:
> memL[int(wr_addr)][:] = din
>
> def rdLogic() :
> while 1:
> yield posedge(clk)
> dout.next = memL[int(rd_addr)]
>
> WL = wrLogic()
> RL = rdLogic()
> return WL,RL
>
> This would allow true dual port capability like most FPGAs now have.
>
> I overlooked this in my initial posting. Also may want a rd_clk and wr_clk.
That is no problem - clocks will be as defined in the sourcecode.
> You would need to pull the reg definition out of the process and give a
> unique name to it.
Exactly - like for signals. The logic of MyHDL (similar to VHDL) is
to use a list of Signals in this case: signals are used for
communication between generators, variables internally. So the
code would look like:
memL = [Signal(intbv(...)) for i in range(depth)]
def wrLogic() :
while 1:
yield posedge(clk)
if we:
memL[int(wr_addr)].next = din
def rdLogic() :
while 1:
yield posedge(clk)
dout.next = memL[int(rd_addr)]
> If I do this now, it generates everything correct but leaves out the reg
> define.
That qualifies as a bug - it should give an error. (The principle is:
if the MyHDL simulation works and the conversion succeeds, the converted
code should be correct.)
I noticed that this was bug was present for non-list types also and
I have already added code to my development version that flags this
situation as a conversion error.
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
|
|
From: Jan D. <ja...@ja...> - 2005-08-04 19:08:25
|
nicran wrote: > Hi, Jan, > > I got the following error message when using myhdl as HVL to > co-simulate with verilog. The simulation result is correct. But this > error message is quite annoying. Could you give me an explanation how > to avoid this message? > > Thanks a lot! > > ERROR: no write pipe to myhdl This indicates a fundamental problem with pipe creation or with passing them to the simulator process through environment variables. The simulator is supposed to exit immediately when the pipe is not found, so I don't understand how a simulation result could be correct. What is your platform and what simulator are you using? 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 |
|
From: nicran <ni...@gm...> - 2005-08-04 04:50:46
|
Hi, Jan, I got the following error message when using myhdl as HVL to co-simulate with verilog. The simulation result is correct. But this error message is quite annoying. Could you give me an explanation how to avoid this message? Thanks a lot! ERROR: no write pipe to myhdl |
|
From: Jan D. <ja...@ja...> - 2005-08-03 21:21:50
|
Günter Dannoritzer wrote: > Jan, > > I tried a simple example with the memory and to implement it with ISE > 6.3, but ran into some problems. I am not sure whether I did something > wrong how I wrote the MyHDL code or need to do some special ISE > settings? I basically pulled in the generated Verilog file into a ISE > project with the standard settings and ran it through implementation. I don´t have ISE installed - I rely on external feedback for this. So feedback on specific tool experiences is very welcome. > Here is the MyHDL code that I used: > > > def ram(clk, dout, din, addr, we, d_width=8, depth=4) : > > memL = [intbv(0)[d_width:] for i in range(depth)] > > while 1: > yield posedge(clk) > > if we: > memL[int(addr.val)][:] = din.val > > dout.next = memL[int(addr.val)] > > > > > and that is the generated Verilog code: > > > module inst_ram ( > clk, > dout, > din, > addr, > we > ); > > input [0:0] clk; > output [7:0] dout; > reg [7:0] dout; > input [7:0] din; > input [1:0] addr; > input we; > > > > always @(posedge clk) begin: _MYHDL1_BLOCK > reg [8-1:0] memL [0:4-1]; > if (we) begin > memL[addr] = din; > end > dout <= memL[addr]; > end > > endmodule > > > The first thing ISE tripped over was that the memL array is inside the > always statement. Moving it out from there made it go on, but then there > is a blocking and nonblocking assignment inside the always statement and > that one it did not like either. The latter part is really stupid. I know where this comes from, and I know this rule is in the mainstream, but that doesn´t make it less stupid. Tool developers should be wiser. > Is it possible to change that with the toVerilog conversion? I cannot change the fact that using both signals and variables in a generator (= blocking and nonblocking in an always block) is an essential part of HDL design. However, for simple cases, there are workarounds, such as breaking an always block into several ones. This could be done (in the input MyHDL code) in this specific case of ram inference. To make that work, what is missing in toVerilog is the capability to define the memory outside of a generator, as reported by others also. I´m currently thinking about a solution. > I also recognized that the 'clk' signal is specified as input [0:0] > whereas the 'we' signal is specified only as input. Probably this is because clk is defined as an intbv instead of a bool. 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 |
|
From: Jan D. <ja...@ja...> - 2005-08-02 20:42:51
|
Haitao Zhang wrote: > On 8/1/05, Jan Decaluwe <ja...@ja...> wrote: > Jan, > I generally agree with your comments against "syntax sugar" so I won't > argue about it. Also thanks for pointing out a less verbose way to > keep track. > > On the following point I want to point out a drawback: > when you group all assignments you are making all the assignments > sensitive to all signals on the RHS, and therefore whenever an event > happens every single assignment will be evaluated. That may or may not > be acceptable in terms of simulation efficiency, but it is not > equivalent to multiple concurrent assignment blocks. Or maybe I don't > understand what instances() and always_comb() do? With the current implementation, you are correct. However, this could be optimized. This is similar to the current discussion in another thread about conversion to Verilog assign statements. always_comb() inspects the function source code to infer a sensitivity list. It returns a single generator. It could be enhanced to detect the case in which the function only contains assignments (no control logic or declarations). In that case it could infer a sensitivity list and return a generator per individual assignment. 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 |
|
From: Jan D. <ja...@ja...> - 2005-08-02 20:30:30
|
(I think something went wrong with gmane yesterday, and the following message from Tom Dillon didn=B4t show up in gmane. So I repost it -- Jan Decaluwe) Tom Dillon wrote: > Jan, >=20 > How difficult to add the capability to handle the following? >=20 > memL =3D [intbv(0,min=3Ddout._min,max=3Ddout._max) for i in range(dept= h)] > def wrLogic() : > while 1: > yield posedge(clk) > if we: > memL[int(wr_addr)][:] =3D din >=20 > def rdLogic() : > while 1: > yield posedge(clk) > dout.next =3D memL[int(rd_addr)] >=20 > WL =3D wrLogic() > RL =3D rdLogic() > return WL,RL >=20 > This would allow true dual port capability like most FPGAs now have. >=20 > I overlooked this in my initial posting. Also may want a rd_clk and wr_= clk. >=20 > You would need to pull the reg definition out of the process and give a= =20 > unique name to it. >=20 > If I do this now, it generates everything correct but leaves out the re= g=20 > define. >=20 > Tom >=20 >=20 > Jan Decaluwe wrote: >=20 >> Tom Dillon wrote: >> >>> Jan, >>> >>> That works great, I use it with the following code: >>> >>> memL =3D [intbv(0,min=3Ddout._min,max=3Ddout._max) for i in range(de= pth)] >>> while 1: >>> yield posedge(clk) >>> if we: >>> memL[int(addr)][:] =3D din >>> # print "ram: wrote %d to %d"%(din,addr) >>> dout.next =3D memL[int(addr)] >>> >>> This synthesized into Virtex blockRAM using Mentor Precision just fin= e. >> >> >> >> Ok. The code was committed to the next release. >> >=20 >=20 > ------------------------------------------------------- > SF.Net email is sponsored by: Discover Easy Linux Migration Strategies > from IBM. Find simple to follow Roadmaps, straightforward articles, > informative Webcasts and more! Get everything you need to get up to > speed, fast. http://ads.osdn.com/?ad_id=3D7477&alloc_id=3D16492&op=3Dcl= ick > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list >=20 --=20 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 |
|
From: Jan D. <ja...@ja...> - 2005-08-02 20:24:59
|
(I think something went wrong with gmane yesterday, and the following message from Haitao Zhang didn=B4t show up in gmane. So I repost it -- Jan Decaluwe) Haitao Zhang wrote: > On 8/1/05, Jan Decaluwe <ja...@ja...> wrote: > Jan, > I generally agree with your comments against "syntax sugar" so I won't > argue about it. Also thanks for pointing out a less verbose way to > keep track. >=20 > On the following point I want to point out a drawback: > when you group all assignments you are making all the assignments > sensitive to all signals on the RHS, and therefore whenever an event > happens every single assignment will be evaluated. That may or may not > be acceptable in terms of simulation efficiency, but it is not > equivalent to multiple concurrent assignment blocks. Or maybe I don't > understand what instances() and always_comb() do? >=20 > Haitao >=20 >=20 >>It is true that MyHDL is more verbose and more explicit. But I think >>you are a little pessimistic. You could group all assigns in a single >>function, and use always_comb() and instances(), like so: >> >> ... >> def assignments(): >> a.next =3D b >> c.next =3D d >> ... >> assignments_inst =3D always_comb(assignments) >> .... >> return instances() >> >>That=B4s not too bad, I think. >> >=20 >=20 >=20 > ------------------------------------------------------- > SF.Net email is sponsored by: Discover Easy Linux Migration Strategies > from IBM. Find simple to follow Roadmaps, straightforward articles, > informative Webcasts and more! Get everything you need to get up to > speed, fast. http://ads.osdn.com/?ad_idt77&alloc_id=16492&op=3Dclick > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list >=20 --=20 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 |
|
From: Haitao Z. <ha...@gm...> - 2005-08-01 21:19:54
|
On 8/1/05, Jan Decaluwe <ja...@ja...> wrote: Jan, I generally agree with your comments against "syntax sugar" so I won't argue about it. Also thanks for pointing out a less verbose way to keep track. On the following point I want to point out a drawback: when you group all assignments you are making all the assignments sensitive to all signals on the RHS, and therefore whenever an event happens every single assignment will be evaluated. That may or may not be acceptable in terms of simulation efficiency, but it is not equivalent to multiple concurrent assignment blocks. Or maybe I don't understand what instances() and always_comb() do? Haitao > It is true that MyHDL is more verbose and more explicit. But I think > you are a little pessimistic. You could group all assigns in a single > function, and use always_comb() and instances(), like so: >=20 > ... > def assignments(): > a.next =3D b > c.next =3D d > ... > assignments_inst =3D always_comb(assignments) > .... > return instances() >=20 > That=B4s not too bad, I think. > |
|
From: Tom D. <td...@di...> - 2005-08-01 19:13:43
|
Jan,
How difficult to add the capability to handle the following?
memL = [intbv(0,min=dout._min,max=dout._max) for i in range(depth)]
def wrLogic() :
while 1:
yield posedge(clk)
if we:
memL[int(wr_addr)][:] = din
def rdLogic() :
while 1:
yield posedge(clk)
dout.next = memL[int(rd_addr)]
WL = wrLogic()
RL = rdLogic()
return WL,RL
This would allow true dual port capability like most FPGAs now have.
I overlooked this in my initial posting. Also may want a rd_clk and wr_clk.
You would need to pull the reg definition out of the process and give a
unique name to it.
If I do this now, it generates everything correct but leaves out the reg
define.
Tom
Jan Decaluwe wrote:
> Tom Dillon wrote:
>
>> Jan,
>>
>> That works great, I use it with the following code:
>>
>> memL = [intbv(0,min=dout._min,max=dout._max) for i in range(depth)]
>> while 1:
>> yield posedge(clk)
>> if we:
>> memL[int(addr)][:] = din
>> # print "ram: wrote %d to %d"%(din,addr)
>> dout.next = memL[int(addr)]
>>
>> This synthesized into Virtex blockRAM using Mentor Precision just fine.
>
>
> Ok. The code was committed to the next release.
>
|
|
From: Jan D. <ja...@ja...> - 2005-08-01 15:56:05
|
Günter Dannoritzer wrote: > My show stopper was that I did not really know how to implement the > assign statement. I searched through the mailing list archive and found > a post from March 2nd of this year with the subject "syntax sugar?" from > Haitao Zhang. I just posted a delayed answer to that post. Note that what Haitao asked for was MyHDL assign statements equivalent to Verilog. It is not immediately clear how to do that, but I think the MyHDL alternative is not that bad. See my answer there. What you ask for is assigns in generated Verilog. They are used already to implement constant value assignments. I think their usage could be extended to keep Xilinx tools happy without jeopardizing generality. A possible solution is as follows. It should be possible to detect simple always_comb blocks: those that consist of assignments only (no declarations or control logic.) Instead of converting them to an always block, they could be converted to a series of assigns statements. Regards, 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 |
|
From: Jan D. <ja...@ja...> - 2005-08-01 15:41:11
|
Tom Dillon wrote: > Jan, > > That works great, I use it with the following code: > > memL = [intbv(0,min=dout._min,max=dout._max) for i in range(depth)] > while 1: > yield posedge(clk) > if we: > memL[int(addr)][:] = din > # print "ram: wrote %d to %d"%(din,addr) > dout.next = memL[int(addr)] > > This synthesized into Virtex blockRAM using Mentor Precision just fine. Ok. The code was committed to the next release. -- 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 |
|
From: Jan D. <ja...@ja...> - 2005-08-01 15:31:08
|
Haitao Zhang wrote:
> One thing I miss in the MyHDL idiom is the simple concurrent statement:
> a <= expr
> or
> assign a = expr
>
> In myhdl one has to do
> def assign_blk():
> while 1:
> yield signals in expr
> a.next = expr
>
> or:
> def assign_blk():
> def blk():
> a.next = expr
> return always_comb(blk)
Why the overhead of an additional embedde function blk()?
You can just do:
def assign_blk():
a.next = expr
and use always_comb() when creating the instance.
>
> AND one needs to keep track of all the generators:
> assign_blk_list.append(assign_blk())
Are you aware of the MyHDL function instances()? It is supposed to
track down all instances for you so that you can simply say:
return instances()
> Now of course the regular HDL statement and the myhdl are semantically
> equivalent, so you may call the regular concurrent assignment simple
> syntax sugar. But it does hide the details from the user and it is a
> very good abstraction that can be consistently understood. In a real
> design when one does a fair amount of concurrent assignment the tedium
> of using the myhdl syntax could quickly add up.
It is true that MyHDL is more verbose and more explicit. But I think
you are a little pessimistic. You could group all assigns in a single
function, and use always_comb() and instances(), like so:
...
def assignments():
a.next = b
c.next = d
...
assignments_inst = always_comb(assignments)
....
return instances()
That´s not too bad, I think.
> I understand since myhdl is embedded in pure python it has to use all
> the defs to control the evaluation and the partial evaluation. One
> possibility is to add syntax sugar like the following:
> assign("a", "expr")
I don´t like this, as functionality is hidden in strings
outside the reassuring scope of the Python interpreter.
I want to rely on it as much as possible.
In general I also don´t like syntactic sugar. Python itself
shows that you don´t need it, and that explicit code doesn´t
necessarily mean verbose code.
Regards,
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
|
|
From: <dan...@we...> - 2005-07-29 09:25:17
|
Haitao, Haitao Zhang wrote: > Guenter, > > What I meant by keeping track is that you have to put all the logic > circuits of interest in a list and hand them over to whatever > processing routine. Remember your "def"s are only for Python and > Python does not know anything about the HDL you are using on top of > it, so the user instead of the tool needs to keep track of all his > stuff explicitly. > Thanks, now I understand. So I can use the combinatorial logic to resemble the assign statement, just have to have two defs, one for the memory part and one for the assign statement. Actually three, like one top that ties them together. > For memory I suggest the following design flow: > Because of my ASIC background I will always handle memory myself > (remember all that fancy features Xilinx give you do not all easily > translate into an ASIC flow. You want to rely as little on a specific > vendor as possible which means don't use features if you can avoid This is the nice part about the approach I am doing. I actually coding the memory in Verilog in a generic way. So it can be simulated and actually implemented with many tools. Following the template given by Xilinx, I have the benefit that XST will pick that code up and turn it into block RAM. The code will work with any other tool as well, just might not trigger that specific function as it does for XST. > them). This is what I would do: partition design into > Logic+Memory+TestBench. When doing Python/HDL behavioral sim, just > simulate all memories in test bench. Memory can be simulated with > either a simple array or a dictionary (esp. when it is sparse). Also > when using a dictionay you automatically get flagged on access before > initialization (key error raised by the dictionary). When you are > ready to implement everything in Verilog, create an additional > hiearchy: top= (logic, memory). In top you can instantiate the > translated module of logic and also instantiate all your memory > blocks. This last step can be easily customized and automated with > simple text processing (hint: print statements). While I do not > exactly use myHDL, this strategy has worked out well for me. > > Hope this helps all who are struggling with memory translations. > > Haitao Splitting up like that is a good idea for the time being and I will probably do it that way for now. I hope I can finally do the memory right out of myhdl. The disadvantage of the splitting method is, that you need to model the memory two times. One time for simulation, which granted, is not that big of a model. But then you have again the implementation. The advantage of being able to model it in myhdl and convert it to Verilog and in future maybe to VHDL is that you only have to model it one time. If changes are necessary, you only have to do them in the test bench and in the myhdl modeling. The rest follows automatically from that. So I can make an automated verification flow, were I generate my Verilog for example, use the test bench I used already for the myhdl model and do co-verification to make sure the generated Verilog is working, then run the implementation and generate a post-place+route simulation file and use the test bench again to check that. I think myhdl can help here to save work steps in the design flow that are otherwise necessary. Guenter |
|
From: Haitao Z. <ha...@gm...> - 2005-07-28 19:01:39
|
Python is as powerful as myhdl. You can easily describe however many memories you have in Python and have them either simulated in Python or generated to Verilog. It would be equivalent to your black box approach without having to burden myHDL. By using a lot of little memories you may already have tied the whole design with FPGA. In ASIC having a lot of little memories is a pain to handle for the backend and costs dearly in chip area (which is a sunken cost for FPGA but not for ASIC). Haitao On 7/28/05, Tom Dillon <td...@di...> wrote: > I disagree with that approach to use memories on the Verilog side by > bringing them up to the test bench level. Our designs use many memories a= nd > that would be way too tedious. > =20 > If it was too difficult to implement, I would much prefer a black box > approach that would leave the memories at the same place in the hierarchy= . > =20 > This would not make MyHDL specific to Xilinx by any means, as everything > needed for different architectures can be handled in MyHDL as long as we > have the ability to turn a list into a Verilog 2D array.=20 > =20 > Our synthesis tool, Mentor Precision, will take the same Verilog memory > structures and infer them and target them to any FPGA technology. Dependi= ng > on the structures available in the target technology, dictates how well i= t > does. Worst case you will use a lot of registers. > =20 > Even Xilinx XST can handle this these days. I would not limit MyHDL by t= he > ASIC flows that exist today.=20 > =20 > We will need the black box support before long which would solve the ASI= C > flow. > =20 > Tom >=20 > =20 > =20 > =20 > =20 > =20 > Haitao Zhang wrote:=20 > Guenter, >=20 > What I meant by keeping track is that you have to put all the logic > circuits of interest in a list and hand them over to whatever > processing routine. Remember your "def"s are only for Python and > Python does not know anything about the HDL you are using on top of > it, so the user instead of the tool needs to keep track of all his > stuff explicitly. >=20 > For memory I suggest the following design flow: > Because of my ASIC background I will always handle memory myself > (remember all that fancy features Xilinx give you do not all easily > translate into an ASIC flow. You want to rely as little on a specific > vendor as possible which means don't use features if you can avoid > them). This is what I would do: partition design into > Logic+Memory+TestBench. When doing Python/HDL behavioral sim, just > simulate all memories in test bench. Memory can be simulated with > either a simple array or a dictionary (esp. when it is sparse). Also > when using a dictionay you automatically get flagged on access before > initialization (key error raised by the dictionary). When you are > ready to implement everything in Verilog, create an additional > hiearchy: top=3D (logic, memory). In top you can instantiate the > translated module of logic and also instantiate all your memory > blocks. This last step can be easily customized and automated with > simple text processing (hint: print statements). While I do not > exactly use myHDL, this strategy has worked out well for me. >=20 > Hope this helps all who are struggling with memory translations. >=20 > Haitao >=20 > On 7/28/05, G=FCnter Dannoritzer <dan...@we...> wrote: > =20 > =20 > Hello, >=20 > Tom Dillon wrote: >=20 > ... >=20 >=20 > =20 > =20 > For a true dual port (dual clock) we need something like the following: >=20 > reg [7:0] mem [31:0]; >=20 > always @(posedge write_clock) > if (wea) > mem[addr_write] <=3D data_in; >=20 > always @(posedge read_clock) > data_out <=3D mem[addr_read]; >=20 > Tom > =20 > I tried to implement a dual-port RAM with synchronous read. The Xilinx > XST manual provides a Verilog template for that. Basically if the XST > finds a Verilog construct in the form of that template, it will > implement it as a dual-port RAM. >=20 > Following is the Verilog code for a dual-port RAM with synchronous read > (read through). >=20 > module raminfr (clk, we, a, dpra, di, spo, dpo); > input clk; > input we; > input [4:0] a; > input [4:0] dpra; > input [3:0] di; > output [3:0] spo; > output [3:0] dpo; >=20 > reg [3:0] ram [31:0]; > reg [4:0] read_a; > reg [4:0] read_dpra; >=20 > always @(posedge clk) begin >=20 > if (we) > ram[a] <=3D di; > read_a <=3D a; > read_dpra <=3D dpra; > end >=20 > assign spo =3D ram[read_a]; > assign dpo =3D ram[read_dpra]; >=20 > endmodule >=20 >=20 > Now I tried to implement that in myhdl so that toVerilog would create > the respective Verilog. >=20 > My show stopper was that I did not really know how to implement the > assign statement. I searched through the mailing list archive and found > a post from March 2nd of this year with the subject "syntax sugar?" from > Haitao Zhang. >=20 > He wrote: >=20 > =20 > =20 > assign a =3D expr >=20 > In myhdl one has to do > def assign_blk(): > while 1: > yield signals in expr > a.next =3D expr >=20 > or: > def assign_blk(): > def blk(): > a.next =3D expr > return always_comb(blk) >=20 > AND one needs to keep track of all the generators: > assign_blk_list.append(assign_blk()) > =20 > First that looked simple, just implement it as combinatorial logic, but > then there is that comment about needing to keep track of the generators > that I did not understand. Maybe somebody can give me some explanation > about why I need to keep track of the generators? Does it not work as a > combinatorial logic implementation by itself? >=20 > I tried to go on, without considering the assign statement for now and > ran into another issue with the two read_* registers. >=20 > Below is my myhdl code. When doing it as below I have the problem, that > toVerilog specifies the registers inside the always statement. I > commented about that already yesterday with the memory array. I tried to > avoid that by explicit initializing the python variables outside the > while loop, which is now commented out. But that only brought me a type > mismatch error message, probably because I am passing a signal to the > dp_ram_py() function. >=20 >=20 > def dp_ram_py(clk, we, addr, di, spo, dp_addr, dpo): >=20 > memL =3D [intbv(0)[d_width:] for i in range(a_width^2)] >=20 > #read_addr =3D intbv(0)[a_width:] > #read_dp_addr =3D intbv(0)[a_width:] >=20 > while 1: > yield posedge(clk) >=20 > if we: > memL[int(addr.val)][:] =3D di.val >=20 > read_addr =3D addr > read_dp_addr =3D dp_addr >=20 > spo.next =3D memL[int(read_addr.val)] > dpo.next =3D memL[int(read_dp_addr.val)] >=20 >=20 >=20 > I would appreciate any help how to solve that. >=20 > Thanks in advance. >=20 > Guenter >=20 >=20 >=20 >=20 >=20 > ------------------------------------------------------- > SF.Net email is Sponsored by the Better Software Conference & EXPO Septem= ber > 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices > Agile & Plan-Driven Development * Managing Projects & Teams * Testing & Q= A > Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list >=20 > =20 > =20 > ------------------------------------------------------- > SF.Net email is Sponsored by the Better Software Conference & EXPO Septem= ber > 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices > Agile & Plan-Driven Development * Managing Projects & Teams * Testing & Q= A > Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list >=20 > =20 > |
|
From: Tom D. <td...@di...> - 2005-07-28 18:46:58
|
I disagree with that approach to use memories on the Verilog side by=20 bringing them up to the test bench level. Our designs use many memories=20 and that would be way too tedious. If it was too difficult to implement, I would much prefer a black box=20 approach that would leave the memories at the same place in the hierarchy= . This would not make MyHDL specific to Xilinx by any means, as everything=20 needed for different architectures can be handled in MyHDL as long as we=20 have the ability to turn a list into a Verilog 2D array. Our synthesis tool, Mentor Precision, will take the same Verilog memory=20 structures and infer them and target them to any FPGA technology.=20 Depending on the structures available in the target technology, dictates=20 how well it does. Worst case you will use a lot of registers. Even Xilinx XST can handle this these days. I would not limit MyHDL by=20 the ASIC flows that exist today. We will need the black box support before long which would solve the=20 ASIC flow. Tom Haitao Zhang wrote: >Guenter, > >What I meant by keeping track is that you have to put all the logic >circuits of interest in a list and hand them over to whatever >processing routine. Remember your "def"s are only for Python and >Python does not know anything about the HDL you are using on top of >it, so the user instead of the tool needs to keep track of all his >stuff explicitly. > >For memory I suggest the following design flow: >Because of my ASIC background I will always handle memory myself >(remember all that fancy features Xilinx give you do not all easily >translate into an ASIC flow. You want to rely as little on a specific >vendor as possible which means don't use features if you can avoid >them). This is what I would do: partition design into >Logic+Memory+TestBench. When doing Python/HDL behavioral sim, just >simulate all memories in test bench. Memory can be simulated with >either a simple array or a dictionary (esp. when it is sparse). Also >when using a dictionay you automatically get flagged on access before >initialization (key error raised by the dictionary). When you are >ready to implement everything in Verilog, create an additional >hiearchy: top=3D (logic, memory). In top you can instantiate the >translated module of logic and also instantiate all your memory >blocks. This last step can be easily customized and automated with >simple text processing (hint: print statements). While I do not >exactly use myHDL, this strategy has worked out well for me. > >Hope this helps all who are struggling with memory translations. > >Haitao > >On 7/28/05, G=FCnter Dannoritzer <dan...@we...> wrote: > =20 > >>Hello, >> >>Tom Dillon wrote: >> >>... >> >> >> =20 >> >>>For a true dual port (dual clock) we need something like the following= : >>> >>> reg [7:0] mem [31:0]; >>> >>> always @(posedge write_clock) >>> if (wea) >>> mem[addr_write] <=3D data_in; >>> >>> always @(posedge read_clock) >>> data_out <=3D mem[addr_read]; >>> >>>Tom >>> =20 >>> >>I tried to implement a dual-port RAM with synchronous read. The Xilinx >>XST manual provides a Verilog template for that. Basically if the XST >>finds a Verilog construct in the form of that template, it will >>implement it as a dual-port RAM. >> >>Following is the Verilog code for a dual-port RAM with synchronous read >>(read through). >> >>module raminfr (clk, we, a, dpra, di, spo, dpo); >>input clk; >>input we; >>input [4:0] a; >>input [4:0] dpra; >>input [3:0] di; >>output [3:0] spo; >>output [3:0] dpo; >> >>reg [3:0] ram [31:0]; >>reg [4:0] read_a; >>reg [4:0] read_dpra; >> >>always @(posedge clk) begin >> >> if (we) >> ram[a] <=3D di; >> read_a <=3D a; >> read_dpra <=3D dpra; >> end >> >> assign spo =3D ram[read_a]; >> assign dpo =3D ram[read_dpra]; >> >>endmodule >> >> >>Now I tried to implement that in myhdl so that toVerilog would create >>the respective Verilog. >> >>My show stopper was that I did not really know how to implement the >>assign statement. I searched through the mailing list archive and found >>a post from March 2nd of this year with the subject "syntax sugar?" fro= m >>Haitao Zhang. >> >>He wrote: >> >> =20 >> >>>assign a =3D expr >>> >>>In myhdl one has to do >>>def assign_blk(): >>> while 1: >>> yield signals in expr >>> a.next =3D expr >>> >>>or: >>>def assign_blk(): >>> def blk(): >>> a.next =3D expr >>> return always_comb(blk) >>> >>>AND one needs to keep track of all the generators: >>>assign_blk_list.append(assign_blk()) >>> =20 >>> >>First that looked simple, just implement it as combinatorial logic, but >>then there is that comment about needing to keep track of the generator= s >>that I did not understand. Maybe somebody can give me some explanation >>about why I need to keep track of the generators? Does it not work as a >>combinatorial logic implementation by itself? >> >>I tried to go on, without considering the assign statement for now and >>ran into another issue with the two read_* registers. >> >>Below is my myhdl code. When doing it as below I have the problem, that >>toVerilog specifies the registers inside the always statement. I >>commented about that already yesterday with the memory array. I tried t= o >>avoid that by explicit initializing the python variables outside the >>while loop, which is now commented out. But that only brought me a type >>mismatch error message, probably because I am passing a signal to the >>dp_ram_py() function. >> >> >>def dp_ram_py(clk, we, addr, di, spo, dp_addr, dpo): >> >> memL =3D [intbv(0)[d_width:] for i in range(a_width^2)] >> >> #read_addr =3D intbv(0)[a_width:] >> #read_dp_addr =3D intbv(0)[a_width:] >> >> while 1: >> yield posedge(clk) >> >> if we: >> memL[int(addr.val)][:] =3D di.val >> >> read_addr =3D addr >> read_dp_addr =3D dp_addr >> >> spo.next =3D memL[int(read_addr.val)] >> dpo.next =3D memL[int(read_dp_addr.val)] >> >> >> >>I would appreciate any help how to solve that. >> >>Thanks in advance. >> >>Guenter >> >> >> >> >> >>------------------------------------------------------- >>SF.Net email is Sponsored by the Better Software Conference & EXPO Sept= ember >>19-22, 2005 * San Francisco, CA * Development Lifecycle Practices >>Agile & Plan-Driven Development * Managing Projects & Teams * Testing &= QA >>Security * Process Improvement & Measurement * http://www.sqe.com/bsce5= sf >>_______________________________________________ >>myhdl-list mailing list >>myh...@li... >>https://lists.sourceforge.net/lists/listinfo/myhdl-list >> >> =20 >> > > >------------------------------------------------------- >SF.Net email is Sponsored by the Better Software Conference & EXPO Septe= mber >19-22, 2005 * San Francisco, CA * Development Lifecycle Practices >Agile & Plan-Driven Development * Managing Projects & Teams * Testing & = QA >Security * Process Improvement & Measurement * http://www.sqe.com/bsce5s= f >_______________________________________________ >myhdl-list mailing list >myh...@li... >https://lists.sourceforge.net/lists/listinfo/myhdl-list > > =20 > |
|
From: Haitao Z. <ha...@gm...> - 2005-07-28 18:16:53
|
Guenter, What I meant by keeping track is that you have to put all the logic circuits of interest in a list and hand them over to whatever processing routine. Remember your "def"s are only for Python and Python does not know anything about the HDL you are using on top of it, so the user instead of the tool needs to keep track of all his stuff explicitly. For memory I suggest the following design flow: Because of my ASIC background I will always handle memory myself (remember all that fancy features Xilinx give you do not all easily translate into an ASIC flow. You want to rely as little on a specific vendor as possible which means don't use features if you can avoid them). This is what I would do: partition design into Logic+Memory+TestBench. When doing Python/HDL behavioral sim, just simulate all memories in test bench. Memory can be simulated with either a simple array or a dictionary (esp. when it is sparse). Also when using a dictionay you automatically get flagged on access before initialization (key error raised by the dictionary). When you are ready to implement everything in Verilog, create an additional hiearchy: top=3D (logic, memory). In top you can instantiate the translated module of logic and also instantiate all your memory blocks. This last step can be easily customized and automated with simple text processing (hint: print statements). While I do not exactly use myHDL, this strategy has worked out well for me. Hope this helps all who are struggling with memory translations. Haitao On 7/28/05, G=FCnter Dannoritzer <dan...@we...> wrote: > Hello, >=20 > Tom Dillon wrote: >=20 > ... >=20 >=20 > > > > For a true dual port (dual clock) we need something like the following: > > > > reg [7:0] mem [31:0]; > > > > always @(posedge write_clock) > > if (wea) > > mem[addr_write] <=3D data_in; > > > > always @(posedge read_clock) > > data_out <=3D mem[addr_read]; > > > > Tom >=20 > I tried to implement a dual-port RAM with synchronous read. The Xilinx > XST manual provides a Verilog template for that. Basically if the XST > finds a Verilog construct in the form of that template, it will > implement it as a dual-port RAM. >=20 > Following is the Verilog code for a dual-port RAM with synchronous read > (read through). >=20 > module raminfr (clk, we, a, dpra, di, spo, dpo); > input clk; > input we; > input [4:0] a; > input [4:0] dpra; > input [3:0] di; > output [3:0] spo; > output [3:0] dpo; >=20 > reg [3:0] ram [31:0]; > reg [4:0] read_a; > reg [4:0] read_dpra; >=20 > always @(posedge clk) begin >=20 > if (we) > ram[a] <=3D di; > read_a <=3D a; > read_dpra <=3D dpra; > end >=20 > assign spo =3D ram[read_a]; > assign dpo =3D ram[read_dpra]; >=20 > endmodule >=20 >=20 > Now I tried to implement that in myhdl so that toVerilog would create > the respective Verilog. >=20 > My show stopper was that I did not really know how to implement the > assign statement. I searched through the mailing list archive and found > a post from March 2nd of this year with the subject "syntax sugar?" from > Haitao Zhang. >=20 > He wrote: >=20 > > assign a =3D expr > > > > In myhdl one has to do > > def assign_blk(): > > while 1: > > yield signals in expr > > a.next =3D expr > > > > or: > > def assign_blk(): > > def blk(): > > a.next =3D expr > > return always_comb(blk) > > > > AND one needs to keep track of all the generators: > > assign_blk_list.append(assign_blk()) >=20 > First that looked simple, just implement it as combinatorial logic, but > then there is that comment about needing to keep track of the generators > that I did not understand. Maybe somebody can give me some explanation > about why I need to keep track of the generators? Does it not work as a > combinatorial logic implementation by itself? >=20 > I tried to go on, without considering the assign statement for now and > ran into another issue with the two read_* registers. >=20 > Below is my myhdl code. When doing it as below I have the problem, that > toVerilog specifies the registers inside the always statement. I > commented about that already yesterday with the memory array. I tried to > avoid that by explicit initializing the python variables outside the > while loop, which is now commented out. But that only brought me a type > mismatch error message, probably because I am passing a signal to the > dp_ram_py() function. >=20 >=20 > def dp_ram_py(clk, we, addr, di, spo, dp_addr, dpo): >=20 > memL =3D [intbv(0)[d_width:] for i in range(a_width^2)] >=20 > #read_addr =3D intbv(0)[a_width:] > #read_dp_addr =3D intbv(0)[a_width:] >=20 > while 1: > yield posedge(clk) >=20 > if we: > memL[int(addr.val)][:] =3D di.val >=20 > read_addr =3D addr > read_dp_addr =3D dp_addr >=20 > spo.next =3D memL[int(read_addr.val)] > dpo.next =3D memL[int(read_dp_addr.val)] >=20 >=20 >=20 > I would appreciate any help how to solve that. >=20 > Thanks in advance. >=20 > Guenter >=20 >=20 >=20 >=20 >=20 > ------------------------------------------------------- > SF.Net email is Sponsored by the Better Software Conference & EXPO Septem= ber > 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices > Agile & Plan-Driven Development * Managing Projects & Teams * Testing & Q= A > Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list > |
|
From: <dan...@we...> - 2005-07-28 13:21:35
|
Hello,
Tom Dillon wrote:
...
>
> For a true dual port (dual clock) we need something like the following:
>
> reg [7:0] mem [31:0];
>
> always @(posedge write_clock)
> if (wea)
> mem[addr_write] <= data_in;
>
> always @(posedge read_clock)
> data_out <= mem[addr_read];
>
> Tom
I tried to implement a dual-port RAM with synchronous read. The Xilinx
XST manual provides a Verilog template for that. Basically if the XST
finds a Verilog construct in the form of that template, it will
implement it as a dual-port RAM.
Following is the Verilog code for a dual-port RAM with synchronous read
(read through).
module raminfr (clk, we, a, dpra, di, spo, dpo);
input clk;
input we;
input [4:0] a;
input [4:0] dpra;
input [3:0] di;
output [3:0] spo;
output [3:0] dpo;
reg [3:0] ram [31:0];
reg [4:0] read_a;
reg [4:0] read_dpra;
always @(posedge clk) begin
if (we)
ram[a] <= di;
read_a <= a;
read_dpra <= dpra;
end
assign spo = ram[read_a];
assign dpo = ram[read_dpra];
endmodule
Now I tried to implement that in myhdl so that toVerilog would create
the respective Verilog.
My show stopper was that I did not really know how to implement the
assign statement. I searched through the mailing list archive and found
a post from March 2nd of this year with the subject "syntax sugar?" from
Haitao Zhang.
He wrote:
> assign a = expr
>
> In myhdl one has to do
> def assign_blk():
> while 1:
> yield signals in expr
> a.next = expr
>
> or:
> def assign_blk():
> def blk():
> a.next = expr
> return always_comb(blk)
>
> AND one needs to keep track of all the generators:
> assign_blk_list.append(assign_blk())
First that looked simple, just implement it as combinatorial logic, but
then there is that comment about needing to keep track of the generators
that I did not understand. Maybe somebody can give me some explanation
about why I need to keep track of the generators? Does it not work as a
combinatorial logic implementation by itself?
I tried to go on, without considering the assign statement for now and
ran into another issue with the two read_* registers.
Below is my myhdl code. When doing it as below I have the problem, that
toVerilog specifies the registers inside the always statement. I
commented about that already yesterday with the memory array. I tried to
avoid that by explicit initializing the python variables outside the
while loop, which is now commented out. But that only brought me a type
mismatch error message, probably because I am passing a signal to the
dp_ram_py() function.
def dp_ram_py(clk, we, addr, di, spo, dp_addr, dpo):
memL = [intbv(0)[d_width:] for i in range(a_width^2)]
#read_addr = intbv(0)[a_width:]
#read_dp_addr = intbv(0)[a_width:]
while 1:
yield posedge(clk)
if we:
memL[int(addr.val)][:] = di.val
read_addr = addr
read_dp_addr = dp_addr
spo.next = memL[int(read_addr.val)]
dpo.next = memL[int(read_dp_addr.val)]
I would appreciate any help how to solve that.
Thanks in advance.
Guenter
|