Verilog:ALU输出错误

时间:2014-03-11 00:17:55

标签: logic verilog alu

我正在学习Verilog,这是我的第一个ALU 我无法理解为什么输出不会显示在测试器块中。 样本输出(水平滚动):

FAIL: a=00010010000101010011010100100100, b=11000000100010010101111010000001, op=101,   z=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, expect=11010010100111010111111110100101
FAIL: a=10000100100001001101011000001001, b=10110001111100000101011001100011, op=101, z=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, expect=10110101111101001101011001101011

为什么不计算z?

ALU

module yAlu(z, ex, a, b, op);
input [31:0] a, b;
input [2:0] op;
output[31:0] z;
output ex;

wire [31:0] andRes, orRes, arithmRes, slt;
wire cout;

assign slt = 0; // not supported
assign ex = 0;  // not supported

and myand[31:0] (andRes, a, b);
or  myor[31:0](orRes, a, b);

//Instantiating yArith adder/subtractor from addSub.v
yArith addSub(arithmRes, cout, a, b, op[2]);

//Instantiating 4-to-1 32-bit multiplexor from 4to1Mux.v
yMux4to1 multiplexor(z,  andRes, orRes, arithmRes, slt, op[1:0]);

endmodule

多路复用器:

// 1-bit 2 to 1 selector
module yMux1(z, a, b, c);
output z;
input a, b, c;
wire notC, upper, lower;

not my_not(notC, c);
and upperAnd(upper, a, notC);
and lowerAnd(lower, c, b);
or  my_or(z, upper, lower);

endmodule
//--------------------------------------------
// n-bit 2 to 1 selector
module yMux(z, a, b, c);

parameter SIZE = 2;
output [SIZE-1:0] z;
input [SIZE-1:0] a, b;
input c;

yMux1 mine[SIZE-1:0] (z, a, b, c);

endmodule
//--------------------------------------------
// n-bit 4-to-1 multiplexor 
module yMux4to1(z, a0, a1, a2, a3, c);

parameter SIZE = 32;

output [SIZE-1:0] z;
input  [SIZE-1:0] a0, a1, a2, a3;
input  [1:0] c;
wire   [SIZE-1:0] zLo, zHi;

yMux #(.SIZE(32)) lo(zLo, a0, a1, c[0]);
yMux #(.SIZE(32)) hi(zLo, a2, a3, c[0]);
yMux #(.SIZE(32)) final(zLo, zLo, zHi, c[1]);

// c in array is important (see LabL4.v page)

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

ADDER / SUBTRACTOR BLOCK:

// A simple 1-bit full adder
module yAdder1(z, cout, a, b, cin);
output z, cout;
input  a, b, cin;

xor left_xor(tmp, a, b);
xor right_xor(z, cin, tmp);
and left_and(outL, a, b);
and right_and(outR, tmp, cin);
or  my_or(cout, outR, outL);

endmodule
//----------------------------------------------
// 32-bit adder with 1 bit carry
module yAdder(z, cout, a, b, cin);

output [31:0] z;
output cout;
input  [31:0] a, b;
input  cin;
wire   [31:0] in, out;

yAdder1 adder[31:0](z, out, a, b, in);
assign in[0] = cin;
assign in[1] = out[0];
assign in[2] = out[1];
assign in[3] = out[2];
assign in[4] = out[3];
assign in[5] = out[4];
assign in[6] = out[5];
assign in[7] = out[6];
assign in[8] = out[7];
assign in[9] = out[8];
assign in[10] = out[9];
assign in[11] = out[10];
assign in[12] = out[11];
assign in[13] = out[12];
assign in[14] = out[13];
assign in[15] = out[14];
assign in[16] = out[15];
assign in[17] = out[16];
assign in[18] = out[17];
assign in[19] = out[18];
assign in[20] = out[19];
assign in[21] = out[20];
assign in[22] = out[21];
assign in[23] = out[22];
assign in[24] = out[23];
assign in[25] = out[24];
assign in[26] = out[25];
assign in[27] = out[26];
assign in[28] = out[27];
assign in[29] = out[28];
assign in[30] = out[29];
assign in[31] = out[30];
assign cout = out[31];

endmodule
//----------------------------------------------
// Arithmetic module. Adds if ctrl = 0, subtracts if ctrl = 1
module yArith(z, cout, a, b, ctrl);
output [31:0] z;
output cout;
input  [31:0] a, b;
input  ctrl;
wire   [31:0] notB, tmp;
wire   cin;

assign notB = ~b;
assign cin = ctrl;
yMux #(.SIZE(32)) mux(tmp, b, notB, ctrl);

yAdder adderSubtractor(z, cout, a, tmp, cin);

endmodule

//----------------------------------------------

TESTER:

module labL;
reg [31:0] a, b;
reg [31:0] expect;
reg [2:0] op;
wire ex;
wire[31:0] z;
reg ok, flag;

yAlu mine(z, ex, a, b, op);

initial
begin
repeat(10)
begin
    a = $random;
    b = $random;
    op = 3'b101;
    //flag = $value$plusargs("op=%d", op);
    #10;
    // ERROR CASE
    if (op === 3'b011)
        $display("Error!");
    else if (op === 3'b111)
        $display("Error!");
    // ARITHM CASE
    else if(op === 3'b010)
        expect = a + b;
    else if(op === 3'b110)
        expect = a + ~b + 1;
    // AND CASE
    else if(op === 3'b000)
        expect = a & b;
    else if (op === 3'b100)
        expect = a & b;
    // OR CASE
    else if (op === 3'b001)
        expect = a | b;
    else if (op === 3'b101)
        expect = a | b;
    // DONE WITH CASES;
    #5;
    if (expect === z)
        $display("PASS: a=%b, b=%b, op=%b, z=%b", a, b, op, z, ex);
    else
        $display("FAIL: a=%b, b=%b, op=%b, z=%b, expect=%b", a, b, op, z,   expect);
end
$finish;
end
endmodule   

2 个答案:

答案 0 :(得分:2)

您的yMux4to1无法驱动z输出,因此您将'zzz'视为输出。

这意味着未驱动/高阻抗。

您应该能够使用波形查看器/模拟器来跟踪输出(比使用打印语句更好)。

答案 1 :(得分:1)

您在Z上获得高阻抗信号。这意味着您的输出Z未被驱动。您应该在模拟中逐步完成设计并在控制信号和Z上添加跟踪。您的IDE应该支持这一点。您很可能没有正确连接设计,因此检查数据路径并确保所有输入/输出都已正确连接非常重要。