Verilog Calculation Error 8-bit 1's Complement Subtractor

Viewed 246

I am writing an 8 bit 1's complement subtractor that doesn't use word-level operators like + or -.

I believe 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.

I have written the following code and have no compilation errors, but it is still not displaying the number of correct or incorrect calculations. It shows an x for each number on my end.

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;
   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

It prints:

All cases tested;           x correct,           x failed
1 Answers

Multiple bugs in your testbench.

You need to initialize i and j (they default to x).

You probably wanted A < 255, not i < 256.

You need to check against 255, not 256.

I added #1 before the display to make sure something is printed

initial begin
    i = 0;
    j = 0;
    for (A = 0; A < 255; A = A + 1) begin
        for (B = 0; B < 255; 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
    #1 $display("All cases tested; %d correct, %d failed", i, j);   
end

I get a different display, but it's probably not what you wanted:

All cases tested;           0 correct,       65025 failed
Related