I want to design a 8 bit adder-subtracter in verilog. when cin is 1, it should add 2 numbers, when 0, it should subtracts.
For performing subtraction, I said to add number1 and ~number2 and 1. here is the code:(when subtracting, cin = 0. so ~cin = 1. and it the 3 values will be added by a full_adder which works truly) this is done for all 8 bits.
`timescale 1ns/100ps
module full_adder(input a, b, cin, clock, output reg sum, cout);
always @(negedge clock) begin
sum = #7 a ^ b ^ cin;
cout = #7 (a & b) | (a & cin) | (b & cin);
end
endmodule
module adder_subtracter_8bit
(input [7:0] num1, num2, input cin, clock, output [7:0] result, output cout);
//1 is for adding, 0 for subtracting
wire w0, w1, w2, w3, w4, w5, w6;
assign #3 num2[0] = (num2[0] ~^ cin);
full_adder ADD0 (.a(num1[0]), .b(num2[0]), .cin(~cin), .clock(clock)
, .sum(result[0]), .cout(w0));
assign #3 num2[1] = (num2[1] ~^ w0);
full_adder ADD1 (.a(num1[1]), .b(num2[1]), .cin(w0), .clock(clock)
, .sum(result[1]), .cout(w1));
assign #3 num2[2] = (num2[2] ~^ w1);
full_adder ADD2 (.a(num1[2]), .b(num2[2]), .cin(w1), .clock(clock)
, .sum(result[2]), .cout(w2));
assign #3 num2[3] = (num2[3] ~^ w2);
full_adder ADD3 (.a(num1[3]), .b(num2[3]), .cin(w2), .clock(clock)
, .sum(result[3]), .cout(w3));
assign #3 num2[4] = (num2[4] ~^ w3);
full_adder ADD4 (.a(num1[4]), .b(num2[4]), .cin(w3), .clock(clock)
, .sum(result[4]), .cout(w4));
assign #3 num2[5] = (num2[5] ~^ w4);
full_adder ADD5 (.a(num1[5]), .b(num2[5]), .cin(w4), .clock(clock)
, .sum(result[5]), .cout(w5));
assign #3 num2[6] = (num2[6] ~^ w5);
full_adder ADD6 (.a(num1[6]), .b(num2[6]), .cin(w5), .clock(clock)
, .sum(result[6]), .cout(w6));
assign #3 num2[7] = (num2[7] ~^ w6);
full_adder ADD7 (.a(num1[7]), .b(num2[7]), .cin(w6), .clock(clock)
, .sum(result[7]), .cout(cout));
endmodule
however, this isn't work properly and the outputs(which are wires showing the result) are all X. Signals
testbench:
`timescale 1ns/100ps
module TEST_adder_subtracter_8bit();
reg [7:0] a, b;
reg clock, cin;
wire [7:0] result;
wire cout;
adder_subtracter_8bit UUT(.num1(a), .num2(b), .cin(cin), .clock(clock),
.result(result), .cout(cout));
initial repeat (2000) #7 clock = ~clock;
initial begin
a = 8'b0000_0000;
b = 8'b0000_0000;
clock = 0;
cin = 1;
#180;
a = 8'b0000_0001;
b = 8'b0000_0001;
#180;
a = 8'b0000_0111;
#180;
a = 8'b0000_0001;
b = 8'b0000_0111;
#180;
a = 8'b0001_1010;
b = 8'b0001_0011;
#180;
a = 8'b0000_0001;
b = 8'b1111_1111;
#180;
a = 8'b1111_1111;
b = 8'b0000_0001;
#180;
a = 8'b1111_0000;
b = 8'b1111_0110;
#180;
a = 8'b0111_0011;
b = 8'b0111_0111;
#180;
a = 8'b1111_1111;
b = 8'b1111_1111;
end
endmodule
Can anyone say how should I fix it?
1 Answer 1
what I feel as the mistake in your code is assign #3 num2[0] = (num2[0] ~^ cin)
and other similar expressions. Try changing the name of the net 'num2[0]' on the left-hand side. It will then work. Further, there is a mistake in your code for the expression series that involves 'num2'. All such expressions should be assign #3 NUM2[i] = (num2[i] ~^ cin), i = 1,...,7
. You may find my version of the Verilog code for the problem below.
Verilog Code:
`timescale 1 ns / 100 ps
module FullAdder (
input a, b, cin, Clk,
output reg s, cout
);
always @(negedge Clk)
begin
s = #7 a ^ b ^ cin;
cout = #7 (a & b) | (b & cin) | (cin & a);
end
endmodule
module AddSubtract (
input [7:0] a, b,
input Cin, Clk,
output [7:0] sum,
output Cout
);
genvar i;
wire [8:0] C;
wire [7:0] B;
assign C[0] = ~Cin;
generate
for (i = 0; i < 8; i = i + 1)
begin : AddSubArray
assign #3 B[i] = b[i] ~^ Cin;
FullAdder FA (.a(a[i]), .b(B[i]), .cin(C[i]), .Clk(Clk), .s(sum[i]), .cout(C[i + 1]));
end
endgenerate
assign Cout = C[8];
endmodule
-
1\$\begingroup\$ It may be worth clarifying that HDL are continuously evaluated (event triggered) rather than sequential like a lot of programming languages. \$\endgroup\$Sean Houlihane– Sean Houlihane2018年03月02日 17:34:56 +00:00Commented Mar 2, 2018 at 17:34
cin
is unknown, so you would expect the outputs to be unknown too. Try changing thecin = 1
tocin = 1'b1
in your test bench \$\endgroup\$