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
|
Sep
|
Oct
|
Nov
|
Dec
|
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 |
From: Tom D. <td...@di...> - 2005-07-28 04:11:50
|
>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. > >Is it possible to change that with the toVerilog conversion? > > > Guenter makes a good point here. We will actually need the array to be defined outside the always block and accessible from multiple always blocks. 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 |
From: <dan...@we...> - 2005-07-27 16:09:12
|
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. 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. Is it possible to change that with the toVerilog conversion? I also recognized that the 'clk' signal is specified as input [0:0] whereas the 'we' signal is specified only as input. Regards Guenter Jan Decaluwe wrote: > Jan Decaluwe wrote: > >> Here is my proposed plan: >> >> I will work on an implementation of list comprehensions mapped to >> Verilog memories, along the lines described om my previous mail. I´ll >> post an alpha release to the newsgroup for you and others to test it >> before committing it to the next release. > > > Attached you find a patch to MyHDL to support Verilog memories. > > A list comprehension with intbv elements in a generator is > converted to a Verilog memory. > > To install the patch, replace the myhdl/_toVerilog directory > in a 0.4.1 installation by the attached directory. > > There are several constraints, but I'm not providing an example > in order to ensure that the error handling is tested also :-) > > Regards, > > Jan > |
From: Tom D. <td...@di...> - 2005-07-26 22:41:53
|
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(depth= )] =20 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 fine. Now, I should have thought of this earlier, but I am working=20 sequentially here. ROMs are also needed and easy to infer in synthesis. It would be very=20 good if the following would produce a case statement in Verilog: def rom(dout,addr,clk=3DNone,dataL=3DNone) : """ rom : rom module Inputs: addr : input address clk : clock for synchronous roms, =3D=3D None for async Outputs: dout : output port, width determines width of rom Params: dataL : list of values for rom, length is depth of rom """ memL =3D [intbv(data,min=3Ddout._min,max=3Ddout._max) for data in dataL= ] =20 while 1: yield posedge(clk) dout.next =3D memL[int(addr)] You would need to be able to figure out that the values in memL never=20 get modified after it is defined. The important thing here, is the memL define and the dout.next=20 assignment need to get mapped to a case statement: always @(posedge clk) case(addr) : 0 : dout <=3D dataL[0] ; 1 : dout <=3D dataL[1] ; . . . This also works in XST. Now you may also want some control around this, or possibly asynchronous=20 so only the list needs to become the case statement, that case statement=20 may end up inside come control statements. Possibly a clock enable. This is very helpful. There are also dual port ROMs, so you would need=20 two case statements on the same list, with a separate address into the li= st. You can also initialize the values of a RAM. This is more obscure and=20 I've never actually used it. But it too can be inferred from HDL. I will=20 forward the coding style when I find it. I could not find it today. Anyhow, thanks for the help thus far on the memories and let me know=20 what you think of the rom idea. Tom =20 Jan Decaluwe wrote: > Jan Decaluwe wrote: > >> Here is my proposed plan: >> >> I will work on an implementation of list comprehensions mapped to >> Verilog memories, along the lines described om my previous mail. I=B4l= l >> post an alpha release to the newsgroup for you and others to test it >> before committing it to the next release. > > > Attached you find a patch to MyHDL to support Verilog memories. > > A list comprehension with intbv elements in a generator is > converted to a Verilog memory. > > To install the patch, replace the myhdl/_toVerilog directory > in a 0.4.1 installation by the attached directory. > > There are several constraints, but I'm not providing an example > in order to ensure that the error handling is tested also :-) > > Regards, > > Jan > |
From: Jan D. <ja...@ja...> - 2005-07-20 13:01:40
|
Jan Decaluwe wrote: > Here is my proposed plan: > > I will work on an implementation of list comprehensions mapped to > Verilog memories, along the lines described om my previous mail. I´ll > post an alpha release to the newsgroup for you and others to test it > before committing it to the next release. Attached you find a patch to MyHDL to support Verilog memories. A list comprehension with intbv elements in a generator is converted to a Verilog memory. To install the patch, replace the myhdl/_toVerilog directory in a 0.4.1 installation by the attached directory. There are several constraints, but I'm not providing an example in order to ensure that the error handling is tested also :-) 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 |