Reputation: 57
I have this assignment where I am supposed to design an 8 bit 1's complement subtractor that doesn't use word-level operators like + or -.
I think that it is working (tested it manually on other values), but the last part of the assignment is to have the testbench iterate all the possible values and add them together (256*256 or 65,536 possible values) (not all the numbers added cumulatively to produce a very large number, but 0+1, 0+2, ... 1+1, 1+2, etc.) and check the calculated values with my other module and print the number of values that match the subtractor correctly and the number of values that are incorrect.
The last line of code should look like this:
$display("All cases tested; %d correct, %d failed", correct, failed);
I am not sure what is wrong. This is the error I am now receiving:
/home/kaos/IVER/5f5bd2824865.v:105: error: subtractionresult is not a valid l-value in testbench.
/home/kaos/IVER/5f5bd2824865.v:88: : subtractionresult is declared here as wire.
/home/kaos/IVER/5f5bd2824865.v:106: error: Unable to bind wire/reg/memory `refonesub.subtractionresult' in `testbench'
/home/kaos/IVER/5f5bd2824865.v:106: error: Unable to elaborate condition expression.
3 error(s) during elaboration.
Here is what I have:
module refonesub (
output [7:0] subtractionresult ,
output carryoverflow ,
input [7:0] A ,
input [7:0] B ,
input mode
);
wire B0;
wire B1;
wire B2;
wire B3;
wire B4;
wire B5;
wire B6;
wire B7;
wire C0;
wire C1;
wire C2;
wire C3;
wire C4;
wire C5;
wire C6;
wire C7;
xor(B0, B[0], mode);
xor(B1, B[1], mode);
xor(B2, B[2], mode);
xor(B3, B[3], mode);
xor(B4, B[4], mode);
xor(B5, B[5], mode);
xor(B6, B[6], mode);
xor(B7, B[7], mode);
onesub U0(A[0],B0,mode,C0,subtractionresult[0]);
onesub U1(A[1],B1,C0,C1,subtractionresult[1]);
onesub U2(A[2],B2,C1,C2,subtractionresult[2]);
onesub U3(A[3],B3,C2,C3,subtractionresult[3]);
onesub U4(A[4],B4,C3,C4,subtractionresult[4]);
onesub U5(A[5],B5,C4,C5,subtractionresult[5]);
onesub U6(A[6],B6,C5,C6,subtractionresult[6]);
onesub U7(A[7],B7,C6,C7,subtractionresult[7]);
xor (carryoverflow,C6,C7);
endmodule
module onesub ( A ,B ,Cin ,Cout ,S );
output Cout ;
output S ;
input A ;
wire A ;
input B ;
wire B ;
input Cin ;
wire Cin ;
reg Cout;
reg S;
always @(A or B or Cin) begin
case ({A,B,Cin})
0: begin Cout=0; S=0; end
1: begin Cout=0; S=1; end
2: begin Cout=0; S=1; end
3: begin Cout=1; S=0; end
4: begin Cout=0; S=1; end
5: begin Cout=1; S=0; end
6: begin Cout=1; S=0; end
7: begin Cout=1; S=1; end
endcase
end
endmodule
module testbench;
reg [7:0] A;
reg [7:0] B;
reg mode;
wire [7:0] subtractionresult;
wire carryoverflow;
refonesub sub(
.A(A),
.B(B),
.mode(mode),
.subtractionresult(subtractionresult),
.carryoverflow(carryoverflow) );
integer i, j;
initial begin
// Note that ++ operator does not exist in Verilog !
for (A = 0; i < 256; A = A + 1)
begin
for (B = 0; B < 256; B = B + 1)
begin
subtractionresult = A+B;
if (refonesub.subtractionresult == testbench.subtractionresult) begin
i = i + 1;
end
else begin
j = j + 1;
end
end
end
$display("All cases tested; %d correct, %d failed", i, j);
end
endmodule
Upvotes: 2
Views: 371
Reputation: 62096
Since subtractionresult
is already a module output, there is no need to scope down into the module. Instead, create a testbench signal for the comparison: subtractionresult_expect
. Since you are making a procedural assignment to it, it must be a reg
:
module testbench;
reg [7:0] A;
reg [7:0] B;
reg mode;
wire [7:0] subtractionresult;
reg [7:0] subtractionresult_expect;
wire carryoverflow;
refonesub sub(
.A(A),
.B(B),
.mode(mode),
.subtractionresult(subtractionresult),
.carryoverflow(carryoverflow) );
integer i, j;
initial begin
for (A = 0; i < 256; A = A + 1) begin
for (B = 0; B < 256; B = B + 1) begin
subtractionresult_expect = A+B;
if (subtractionresult == subtractionresult_expect) begin
i = i + 1;
end else begin
j = j + 1;
end
end
end
$display("All cases tested; %d correct, %d failed", i, j);
end
endmodule
The code in the original Question had another problem...
A $display
statement must be inside a procedural block, such as an initial
block. I think you meant to have it as the last line of your initial
block:
initial begin
for (A = 0; i < 256; A = A + 1) begin
for (B = 0; B < 256; B = B + 1) begin
subtractionresult = A+B;
if (refonesub.subtractionresult == testbench.subtractionresult) begin
i = i + 1;
end else begin
j = j + 1;
end
end
end
$display("All cases tested; %d correct, %d failed", i, j);
end
I used emacs
to automatically indent your code to make it a little easier to read.
Upvotes: 1