如何在Verilog中检查模块中的值与另一个模块中的值

问题描述

我有这个作业,应该设计一个不使用+或-等字级运算符的8位1的补码减法器。

我认为它正在工作(对其他值进行手动测试),但是分配的最后一部分是让测试台迭代所有可能的值并将它们加在一起(256 * 256或65,536个可能的值)(不是所有累加的数字都会产生一个非常大的数字,但0 + 1、0 + 2,... 1 + 1、1 + 2等),并与我的其他模块一起检查计算出的值并打印值的数量正确匹配减法器和不正确的值数。

最后一行代码应如下所示:

$display("All cases tested; %d correct,%d Failed",correct,Failed);

我不确定是什么问题。这是我现在收到的错误

/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.

这就是我所拥有的:

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,C1,subtractionresult[1]);
onesub U2(A[2],B2,C2,subtractionresult[2]);
onesub U3(A[3],B3,C3,subtractionresult[3]);
onesub U4(A[4],B4,C4,subtractionresult[4]);
onesub U5(A[5],B5,C5,subtractionresult[5]);
onesub U6(A[6],B6,C6,subtractionresult[6]);
onesub U7(A[7],B7,C7,subtractionresult[7]);  

xor (carryoverflow,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,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,i,j);
  end
endmodule

解决方法

由于subtractionresult已经是模块输出,因此无需缩小范围。而是创建一个用于比较的测试台信号:subtractionresult_expect。由于您要对其进行程序分配,因此它必须为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

原始问题中的代码还有另一个问题...

$display语句必须位于过程块(例如initial块)内。我认为您打算将其作为initial块的最后一行:

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,j);
end

我使用emacs自动缩进您的代码,使其更易于阅读。