Thread: [myhdl-list] Adder/Subtractor design
Brought to you by:
jandecaluwe
From: John S. <jo...@sa...> - 2012-03-03 17:15:17
|
The standard logic expression for an adder/subtractor is a = b + c^d + Sub where d is a vector of length len(c) and where each bit takes the value of the Sub signal. In Verilog this would be a <= b + c ^ {n{Sub}} + Sub where n is len(c) and a, b & c are signed quantities. I've managed to do something similar in Myhdl (v0.7) as follows def foo(clk, a, b, c, Sub): x=[] for i in range(len(c)): x.append(Sub) # Sub is a Signal vec = ConcatSignal(x) @always(clk.posedge) def bar(): a.next = b + (c.signed()^vec.signed()) + Sub return bar Note that I had to hack on _ShadowSignal.py to enable ConcatSignal to take a list of signals as the sole parameter as well as the normal way - I need to be able to change the vector length for different instantiations of the adder/subtractor. This will simulate correctly, but the Verilog produced is a bit baroque, and I haven't yet simulated it, though it looks OK. Essentially 'vec' is a wire of width len(c) and there are then len(c) assignment statements to assign Sub to each bit. Now the question: Is there any facility in Myhdl to generate the {n{Sub}} construct, and with a correct simulation? John Sager john <at> sager <dot> me <dot> uk |
From: Jan C. <jan...@mu...> - 2012-03-03 22:12:17
|
On 03/03/12 16:40, John Sager wrote: . . . > > Now the question: Is there any facility in Myhdl to generate the {n{Sub}} > construct, and with a correct simulation? http://rosettacode.org/wiki/Four_bit_adder#MyHDL The second code sample here is Jan D's, and looks good to me. Jan Coombs. |
From: John S. <jo...@sa...> - 2012-03-04 07:28:01
|
Jan Coombs <jan.coombs_2009 <at> murray-microft.co.uk> writes: > > On 03/03/12 16:40, John Sager wrote: > . . . > > > > Now the question: Is there any facility in Myhdl to generate the > {n{Sub}} > > construct, and with a correct simulation? > > http://rosettacode.org/wiki/Four_bit_adder#MyHDL > > The second code sample here is Jan D's, and looks good to me. > > Jan Coombs. > Jan, Thanks for that. However it's a bit low level, really, having to synthesise an adder from basic logic rather than using Verilog's higher level operators. The useful thing in that was the ConcatSignal(*x) Python parameter passing idiom, of which I wasn't aware, which would have saved me the hack on _ShadowSignal.py John |
From: Jan C. <jan...@mu...> - 2012-03-04 13:12:14
|
On 04/03/12 07:27, John Sager wrote: > Jan Coombs<jan.coombs_2009<at> murray-microft.co.uk> writes: > >> >> On 03/03/12 16:40, John Sager wrote: >> . . . >> > >> > Now the question: Is there any facility in Myhdl to generate the >> {n{Sub}} >> > construct, and with a correct simulation? >> >> http://rosettacode.org/wiki/Four_bit_adder#MyHDL >> >> The second code sample here is Jan D's, and looks good to me. >> >> Jan Coombs. >> > > Jan, > > Thanks for that. However it's a bit low level, really, having to > synthesise an adder from basic logic rather than using Verilog's > higher level operators. The useful thing in that was the > ConcatSignal(*x) Python parameter passing idiom, of which I wasn't > aware, which would have saved me the hack on _ShadowSignal.py Sorry, replace the three defs in with: def Multibit_Adder(a, b, s): @always_comb def add(): s.next = a + b return add This seems to sim & convert ok. It was late and I assumed that breaking the signals into individual bits would be necessary, but it is not. Jan Coombs. |
From: Christopher F. <chr...@gm...> - 2012-03-04 14:30:22
|
On 3/4/12 1:27 AM, John Sager wrote: > Jan Coombs<jan.coombs_2009<at> murray-microft.co.uk> writes: > >> >> On 03/03/12 16:40, John Sager wrote: >> . . . >> > >> > Now the question: Is there any facility in Myhdl to generate the >> {n{Sub}} >> > construct, and with a correct simulation? >> >> http://rosettacode.org/wiki/Four_bit_adder#MyHDL >> >> The second code sample here is Jan D's, and looks good to me. >> >> Jan Coombs. >> > > Jan, > > Thanks for that. However it's a bit low level, really, having to > synthesise an adder from basic logic rather than using Verilog's > higher level operators. The useful thing in that was the > ConcatSignal(*x) Python parameter passing idiom, of which I wasn't > aware, which would have saved me the hack on _ShadowSignal.py > > John > > Wait, that's contradictory to this thread. If you don't want to represent low-level description (which is good) simply use "c = a+b" you don't need to worry about anything else. The synthesis tools will gladly create correct/valid adders. Regards, Chris |
From: John S. <jo...@sa...> - 2012-03-04 17:37:40
|
Christopher Felton <chris.felton <at> gmail.com> writes: > > > > Jan, > > > > Thanks for that. However it's a bit low level, really, having to > > synthesise an adder from basic logic rather than using Verilog's > > higher level operators. The useful thing in that was the > > ConcatSignal(*x) Python parameter passing idiom, of which I wasn't > > aware, which would have saved me the hack on _ShadowSignal.py > > > > John > > > > > > Wait, that's contradictory to this thread. If you don't want to > represent low-level description (which is good) simply use "c = a+b" you > don't need to worry about anything else. The synthesis tools will > gladly create correct/valid adders. > > Regards, > Chris > The real question I asked was whether myhdl would support generating the {n{flag}} construct to produce 'cleaner' Verilog. what I get out is something like wire [15:0] x; assign x[15] = flag; assign x[14] = flag; ... assign x[1] = flag; assign x[0] = flag; and then used in a <= b + c^x + flag I suppose I shouldn't really worry about what the Verilog looks like. My code simulates correctly in both myhdl and co-simulated with Icarus now anyway. J > ------------------------------------------------------------------------------ > Virtualization & Cloud Management Using Capacity Planning > Cloud computing makes use of virtualization - but cloud computing > also focuses on allowing computing to be delivered as a service. > http://www.accelacomm.com/jaw/sfnl/114/51521223/ > |
From: Christopher F. <chr...@gm...> - 2012-03-04 20:20:40
|
On 3/4/12 11:37 AM, John Sager wrote: > Christopher Felton<chris.felton<at> gmail.com> writes: > >>> >>> Jan, >>> >>> Thanks for that. However it's a bit low level, really, having to >>> synthesise an adder from basic logic rather than using Verilog's >>> higher level operators. The useful thing in that was the >>> ConcatSignal(*x) Python parameter passing idiom, of which I wasn't >>> aware, which would have saved me the hack on _ShadowSignal.py >>> >>> John >>> >>> >> >> Wait, that's contradictory to this thread. If you don't want to >> represent low-level description (which is good) simply use "c = a+b" you >> don't need to worry about anything else. The synthesis tools will >> gladly create correct/valid adders. >> >> Regards, >> Chris >> > > The real question I asked was whether myhdl would support generating the > {n{flag}} construct to produce 'cleaner' Verilog. > > what I get out is something like > > wire [15:0] x; > > assign x[15] = flag; > assign x[14] = flag; > ... > assign x[1] = flag; > assign x[0] = flag; > > and then used in > > a<= b + c^x + flag > > I suppose I shouldn't really worry about what the Verilog looks like. My code > simulates correctly in both myhdl and co-simulated with Icarus now anyway. > > J The goal of MyHDL is not make "clean" looking Verilog/VHDL (as in clean to the human reader) but Verilog and VHDL are the intermediate formats that the syntehsizers understand (optimized for syntheized results). In an ideal flow the MyHDL created Verilog/VHDL would not need to be looked at (by a human). With that said the Verilog/VHDL is not obfuscated if it doesn't need to be. Couple things, If you want a single module that is an adder/subtractor you can directory add or subtract. def AdderSubtractor(clk, a,b,c, Subtract=False): assert len(a) >= max(len(b),len(c))+1 @always(clk.posedge) def hdl_add_sub(): if Subtract: c.next = a - b else: c.next = a + b return hdl_ad_sub The above is completely scalable for the different bit widths. You might not need to define a AdderSubtractor module just use '+' and '-' unless you are multiplexing the adder/subtractor in the datapath. Second, I think the problem here is trying to write the MyHDL in a Verilog form. Best I can tell from the question you want to find away to initialize a bit-vector, that is variable size, either set it to all 0s or all 1s. all 0s: vec = Signal(intbv(0)[N:]) all 1s: vec = Signal(intbv(2**N-1)[N:]) Or you could use the ConcatSignal or concat x = concat(*[intbv(1)[1:] for ii in range(N)]) or x = ConcatSignal(*[Signal(True) for ii in range(N)]) No hacking required :) Regards, Chris |
From: John S. <jo...@sa...> - 2012-03-06 11:34:52
|
Christopher Felton <chris.felton <at> gmail.com> writes: ... > > Couple things, If you want a single module that is an adder/subtractor > you can directory add or subtract. > > def AdderSubtractor(clk, a,b,c, Subtract=False): > assert len(a) >= max(len(b),len(c))+1 > @always(clk.posedge) > def hdl_add_sub(): > if Subtract: > c.next = a - b > else: > c.next = a + b > > return hdl_ad_sub > > The above is completely scalable for the different bit widths. You > might not need to define a AdderSubtractor module just use '+' and '-' > unless you are multiplexing the adder/subtractor in the datapath. > ... > > Regards, > Chris In fact I started off with the if-then-else construct on the Subtract flag but I thought that the xor/plus logic would be more efficient. I ran them both through the Quartus II compiler (Cyclone III target) yesterday and I found that the circuit design using if-then-else uses considerably less logic for the same functionality (on the complete circuit which instantiates many add/subtract functions). That was completely against my expectation, but then I'm a long-time software guy just starting out with hardware design. To that end I'm finding Myhdl to be an excellent tool to help me get to grips with it all. J |
From: Christopher F. <chr...@gm...> - 2012-03-06 12:03:38
|
On 3/6/12 5:34 AM, John Sager wrote: > Christopher Felton<chris.felton<at> gmail.com> writes: > > ... >> >> Couple things, If you want a single module that is an adder/subtractor >> you can directory add or subtract. >> >> def AdderSubtractor(clk, a,b,c, Subtract=False): >> assert len(a)>= max(len(b),len(c))+1 >> @always(clk.posedge) >> def hdl_add_sub(): >> if Subtract: >> c.next = a - b >> else: >> c.next = a + b >> >> return hdl_ad_sub >> >> The above is completely scalable for the different bit widths. You >> might not need to define a AdderSubtractor module just use '+' and '-' >> unless you are multiplexing the adder/subtractor in the datapath. >> > ... >> >> Regards, >> Chris > > In fact I started off with the if-then-else construct on the Subtract flag but I > thought that the xor/plus logic would be more efficient. I ran them both through > the Quartus II compiler (Cyclone III target) yesterday and I found that the > circuit design using if-then-else uses considerably less logic for the same > functionality (on the complete circuit which instantiates many add/subtract > functions). That was completely against my expectation, but then I'm a long-time > software guy just starting out with hardware design. > > To that end I'm finding Myhdl to be an excellent tool to help me get to grips > with it all. > > J > Awesome! I hope the adventure continues to be excellent. If you have any questions or issues feel free to post. Regards, Chris |
From: Christopher L. <loz...@fr...> - 2012-04-19 22:33:39
|
Here is a web page describing why one should use MyHDL. http://ejr0.x.rootbsd.net:8080 In the long run, it will be moved to wiki.myhdlclass.com It is in moinmoin, implemented in Python. I once made a mistake, and so am not allowed to edit the MyHDL wiki. Jan politely suggested I put up a new page. Great idea. Anyhow you are all welcome to make edits to the page or add new pages. Let me know if you have any troubles. Why am I doing this? I had thought of offering a MyHDL class. But the first thing is to get the high level arguments right. A class is transient, the documentation lives longer. Your comments are most appreciated. -- Regards Christopher Lozinski |
From: Jan D. <ja...@ja...> - 2012-04-20 08:11:12
|
On 04/20/2012 12:33 AM, Christopher Lozinski wrote: > Here is a web page describing why one should use MyHDL. > > http://ejr0.x.rootbsd.net:8080 > > In the long run, it will be moved to > > wiki.myhdlclass.com > > It is in moinmoin, implemented in Python. > > I once made a mistake, and so am not allowed to edit the MyHDL wiki. > Jan politely suggested I put up a new page. Great idea. > > Anyhow you are all welcome to make edits to the page or add new pages. > Let me know if you have any troubles. > > Why am I doing this? I had thought of offering a MyHDL class. But the > first thing is to > get the high level arguments right. A class is transient, the > documentation lives longer. > > Your comments are most appreciated. There are a number of errors and inaccuracies. Verilog is also based on the event-driven paradigm, as is VHDL. This is what MyHDL, Verilog and VHDL have in common, unlike most HDLs that have been proposed (and forgotten) historically. It is the winning solution. To put things in perspective: my critique on Verilog/VHDL is incremental, not fundamental. With all three HDLs, it is possible to do serious HDL-based design. Some language features in Verilog/VHDL just make it harder (or much harder) than necessary. But not impossible, like with the HDLs based on an inferior paradigm. The blocking/nonblocking issues in Verilog are an example: they make it harder for some designers to use procedural techniques as there is no strict separation between variables and signals. The fact that VHDL designers need a lot of casting is not because it is statically typed, but simply because it uses an inadequate type system (too low level.) Do integers like MyHDL does and a lot of the issues go away. Migen is definitely *not* based on MyHDL, it's not because someone says that they will fork that they do :-) In fact, it tries very hard to be the opposite. It dumps the event-driven paradigm. It has no support for procedural modelling. It makes no difference between variable/signal semantics, even less so than Verilog. And instead of following MyHDL's unique example of how integers should be done in an HDL, it re-introduces Verilog's broken way of handling unsigned and signeds. Migen ignores most of the lessons that MyHDL has to offer. Their good right of course - but it shows that I was right in not spending too much time/effort on the requests of its developer: he did not like (or understand) MyHDL fundamentally, as I suspected right from the start. One more issue. What you keep silent about, surprizingly, is the licensing scheme on your web pages. Before requesting edits, I think you owe it to all potential editors to tell them what will happen with their work. Please, let us avoid the confusion and frustration that happened the last time around. I am not asking for a discussion about pro's and con's of various licensing schemes - it is an endless discussion with no single good answer. Just tell us what you use so that every potential editor can decide. Finally, even it you had editing rights on myhdl.org, I'm not sure you would agree with its Terms of Use, which are crystal-clear by now: http://www.myhdl.org/doku.php/terms_of_use -- Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com Python as a HDL: http://www.myhdl.org VHDL development, the modern way: http://www.sigasi.com World-class digital design: http://www.easics.com |