Thread: Re: [myhdl-list] Re: toVerilog and memories (Page 2)
Brought to you by:
jandecaluwe
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-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: 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-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: 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 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 > |