64 位 ALU 输出在 TestBench 波形上显示出高阻抗

问题描述

我必须制作一个 64 位 ALU,它接收 A 和 B 64 位输入、一个进位输入并输出一个 64 位结果和一个 1 位进位输出。还有一个 5 位功能选择 FS。其中 FS[0] 控制 B 是否反转(使用 2to1 多路复用器。)F[1] 对 A 执行相同的操作。FS[4:2] 确定哪个操作(加、减、逻辑运算等)使用 8to1 多路复用器。下面是 ALU 和测试平台的代码

我很确定我的测试平台很好,ALU 的所有独立组件也很好。我对我实例化和连接所有输入/输出的顶层不太有信心。波形中的高阻抗是什么原因造成的?

module ALU(A,B,FS,cin,cout,result); 
input [63:0] A,B;
input [4:0] FS;
input cin;
output cout;
output  [63:0] result;


eight_one_mux u7 (firstoutA & secoutB,firstoutA | secoutB,sum,firstoutA ^ secoutB,left,right,1'b0,FS[4:2],result);

adder u6 (firstoutA,secoutB,cout);

firstmux u1 (A,!A,FS[1],firstoutA);

secmux u2 (B,!B,FS[0],secoutB);

Alu_shifter u5 (A,right);


endmodule 
//--------------------------------------------------------------------------------//
//These are the two muxes to split into input and inverted input A,B
module firstmux(a,nota,firstS,firstoutA);
input [63:0] a,nota;
input firstS;
output reg [63:0] firstoutA;

always @(a or nota or firstS) 

begin

case(firstS)

0 : firstoutA = a;
1 : firstoutA = nota; 
default : firstoutA = 1'bx;

endcase
end

endmodule
//<><><><><><><>//
module secmux(b,notb,secS,secoutB);
input [63:0] b,notb;
input secS;
output reg [63:0] secoutB;

always @(b or notb or secS) 

begin

case(secS)

0 : secoutB = b;
1 : secoutB = notb; 
default : secoutB = 1'bx;

endcase
end

endmodule
//--------------------------------------------------------------------------------//


//This is the Shifter Blocks
module Alu_shifter (shiftA,left); //This shifter block shifts the A input once right or left
  input [63:0] shiftA;
  output [63:0] right;
  output [63:0] left;
  
  shift_right w1 (    //instantiate right shifter block
  .a_R(shiftA),.R(right)
  );
  
  shift_left w2 (   //instantiate left shifter block
  .a_L(shiftA),.L(left)
  );
  
endmodule
////////><><><><><><><><><><><><><><><///////
module shift_right (a_R,R); // right shifter block
input [63:0] a_R;
output [63:0] R;
assign R = a_R >> 1;  //shift A right once (shift in a 0)
 endmodule


module shift_left (a_L,L);  //left shifter block
input [63:0] a_L;
output [63:0] L;
assign L = a_L << 1; //shift A left once (shift in a 0)
endmodule
//End shifter blocks (3 total modules)
//----------------------------------------------------//////////////////////
//This is the Adder that Adds A,B and cin
module adder(addA,addB,nic,cout);
input [63:0] addA,addB;
input nic;
output [63:0] sum;
output cout;

assign {cout,sum} = addA + addB + nic;


endmodule

//----------------------------------------------------//////////////////////
//This is the 8to1 Mux that decides which operation is put forward
module eight_one_mux(D0,D1,D2,D3,D4,D5,D6,D7,S,out);
input [63:0] D0,D7;
input [2:0] S;
output reg [63:0] out;

always @(D0 or D1 or D2 or D3 or D4 or D5 or D6 or D7 or S) 

begin

case(S)

0 : out = D0; //And
1 : out = D1; //Or
2 : out = D2; //Adder
3 : out = D3; //xor
4 : out = D4; //lefter
5 : out = D5; //righter
6 : out = D6; //GND
7 : out = D7; //GND
default : out = 1'bx;

endcase
end

endmodule
////////////-------------------------------////////////////////////////////
module ALU_tb();

reg [63:0] A,B;
reg [4:0] FS;
reg cin;

wire cout;
wire [63:0] result;


     
     ALU dut (
     .A(A),.B(B),.FS(FS),.cin(cin),.cout(cout),.result(result)
                    );


initial begin
A = 8'b11001100;
B = 8'b11001101;
FS = 5'b01101;
cin = 1;
end

always
#5 cin <= ~cin;

always begin
#5
A <= A + 1;
B <= B + 2;
#5;
end

initial begin
#100 $finish;
end
endmodule
```

解决方法

意外的高阻抗 (z) 值通常是未驱动信号的结果,这就是您的代码的问题。

adder u6 (firstoutA,secoutB,cin,sum,cout);

在上面的行中,您将 1 位信号 firstoutA 连接到 64 位 addA 输入端口。这将 firstoutA 连接到 addA[0],使其他 63 位未驱动。因此,addA[63:1] 都是 z

firstoutA 是一个 1 位信号,因为您没有明确声明它。此外,未声明的信号被假定为 wire 类型,默认为 z。 声明所有信号是一种很好的做法。

要查找所有未声明的信号,请将其添加到代码顶部:

`default_nettype none

你应该得到如下编译错误:

Error-[IND] Identifier not declared
  Identifier 'firstoutA' has not been declared yet. If this error is not 
  expected,please check if you have set `default_nettype to none.

Error-[IND] Identifier not declared
  Identifier 'secoutB' has not been declared yet. If this error is not 
  expected,please check if you have set `default_nettype to none.
,

首先,您需要为模块之间的连接定义信号 (wire)。例如,您有 leftright 作为 Alu_shifter 模块的输出,它们连接到 firstmuxsecmux 模块;但是,它们并未在您的顶级模块中定义。您应该向 topmodule 添加以下信号定义:

wire [63:0] left,right;
wire [63:0] firstoutA;
wire [63:0] secoutB;
wire [63:0] sum;

此外,eight_one_mux 模块接受 8 个 64 位输入。但是,您将其中最后两个设置为 1'b0。您应该将它们更改为 64'b0,如下所示。

eight_one_mux u7 (firstoutA & secoutB,firstoutA | secoutB,firstoutA ^ secoutB,left,right,64'b0,FS[4:2],result);

最后,!A 不会反转 A 的所有位(B 也是如此)。它应用归约运算并生成一个 1 位信号(并且 firstmux 模块期望在其第二个输入端口中有一个 64 位信号)。