clocked adder

M

Mahurshi Akilla

Guest
i am sort of a newbie, and the code i wrote in my school wasn't that
good (most of it was gate level and some behaviroal code that i never
really had time to improve on).

i want to start anew building good habits, now that i have time (and no
deadlines with assignments.)

i am trying to build a clocked adder. at every positive clock edge, it
will add the two inputs and store the output in a register.

the code i have written is as follows:


module simiple_adder_clked(a, b, clk, sum);
input [7:0] a;
input [7:0] b;
input clk;
output [8:0] sum;

reg [8:0] sum;

always @(posedge clk)
begin
sum <= a + b;
end

endmodule


i have simulated this and this "works"

the questions i have are:

1. is this code "correct"? (verilog rules wise)
2. is there anything i could have done better?
3. is this the right way of doing this? (design/synthesis wise)
4. what does this synthesize to?
5. this is relatively simple i guess. but i still couldn't figure
out. how do i take the MSB of sum and send it out seperately into a
"cout" output.
 
Mahurshi Akilla wrote:

module simiple_adder_clked(a, b, clk, sum);
input [7:0] a;
input [7:0] b;
input clk;
output [8:0] sum;

reg [8:0] sum;

always @(posedge clk)
begin
sum <= a + b;
end

endmodule

1. is this code "correct"? (verilog rules wise)
If it simulates, it is always correct. ;-)
It is also not only correct - it is quite good (because of the
non-blocking signal assignment "<=").


2. is there anything i could have done better?
You could implement a reset - or think about it, if you don't need one.


You could define well the bithlengths:

sum[8:0] <= {a[7],a[7:0]} + {b[7],b[7:0]}; // sign extension

This does not look nice, but helps in more complex designs to avoid
typing errors and define well if sign extension has to be used or not.
(Verilog does not warn you, if the vector widths are not equal.)


3. is this the right way of doing this? (design/synthesis wise)
4. what does this synthesize to?
9 flipflops plus an adder. The type of adder is chosen by the synthesis
tool. If you have no speed constraint, you will get a carry-ripple
adder, otherwise e.g. a carry-lookahead.


5. this is relatively simple i guess. but i still couldn't figure
out. how do i take the MSB of sum and send it out seperately into a
"cout" output.
assign cout = sum[8];

Ralf
 
thanks.

i am trying to implement your suggestions. i have the following code:

module simiple_adder_clked(a, b, cin, clk, reset, sum, cout);
input [7:0] a;
input [7:0] b;
input cin;
input clk;
input reset;
output [7:0] sum;
output cout;

reg [8:0] total;
reg [8:0] zero;

assign zero = 0;
assign sum = total[7:0];
assign cout = total[8];

if (reset != 1)
begin
always @(posedge clk)
begin
total <= a + b + cin;
end
end
else
begin
total <= zero;
end


endmodule



the above code doesn't work :-(

1. i have a "zero" register storing zero. my idea was to copy the
"zero" into the total register when reset is 1. directly saying "total
<= 8'b0000_0000" didn't help so i tried this. of course, this didn't
work either. so how do i implement this asynchronous reset ?

2. without the reset option, the code simulated and gave the expected
results in my simple testbench. i used the assign statements at the
top to connect the register to the outputs. is this the right way?
what do these assign statements synthesize to? wires connecting from
register to outputs ?

3. how do i clear the register? (i wish i could do reg.clear() as in
c++ :))

4. notice i used the if statement first and then nested the "always"
block inside of it. i have a funny feeling that this is not right. how
else would i do it?

ok, i guess these are a lot of questions, so i will stop here.

thanks
mahurshi akilla
 
ok. i have fixed the errors and the following code works:


module simiple_adder_clked(a, b, cin, clk, reset, sum, cout);
input [7:0] a;
input [7:0] b;
input cin;
input clk;
input reset;
output [7:0] sum;
output cout;

reg [8:0] total;

initial
begin
total <= 8'b0000_0000;
end

assign sum = total[7:0];
assign cout = total[8];

always @(posedge clk)
begin
if (reset != 1)
begin
total <= a + b + cin;
end
else
total <= 8'b0000_0000;
end

endmodule


are there any suggestions at this point? (of course, i still couldn't
implement the truly asynchronous reset)
 
Mahurshi Akilla wrote:


initial
begin
total <= 8'b0000_0000;
end
Why? - Remember, that initial is not synthesizable.


always @(posedge clk)
begin
if (reset != 1)
begin
total <= a + b + cin;
end
else
total <= 8'b0000_0000;
end

endmodule

are there any suggestions at this point?
Most HDL designers would write

always @(posedge clk)
begin
if (reset == 1)
total <= 8'b0000_0000;
else
begin
total <= a + b + cin; // auto. sign extension
end
end

which is often better readable for larger always-statements, but only a
question of style.
Again you do automatic sign extenstion. Note, that you should be careful
with this - especially if you want to force signed or unsigned sign
extension.


(of course, i still couldn't
implement the truly asynchronous reset)
For an async. reset have a look at:

always @(posedge reset or posedge clk)
begin
if (reset == 1) begin
total <= 8'b0000_0000;
end else /*if posedge clk*/ begin
total <= a + b + cin;
end // if
end // always

For such an adder a reset (sync. or async) may be useless. This depends
on your problem. It was only a suggestion to think about the reset problem.

Ralf
 
Ralf Hildebrandt wrote:
Most HDL designers would write

always @(posedge clk)
begin
if (reset == 1)
total <= 8'b0000_0000;
else
begin
total <= a + b + cin; // auto. sign extension
end
end

which is often better readable for larger always-statements, but only a
question of style.
Again you do automatic sign extenstion. Note, that you should be careful
with this - especially if you want to force signed or unsigned sign
extension.

Hi,

I am not quite sure he is doing an auto sign extension.
In contrast with VHDL
{cout, sum[N-1:0]} <= a[N-1:0] + b[N-1:0];
in verilog should simply implement a N+1 bit adder with carry out
(assigned to cout).

Andrea
 

Welcome to EDABoard.com

Sponsor

Back
Top