문제

I'm studying Verilog and here's my first ALU.
I can't understand why the output does not display in the tester block. Sample outputs(scroll horizontally):

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

Why isn't z calculated?

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

MULTIPLEXORS:

// 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   
도움이 되었습니까?

해결책

Your yMux4to1 does not drive the z output, so that's why you see 'zzz' as the output.

This means undriven/high-impedance.

You should be able to use a waveform viewer/simulator to trace your outputs (much better than using print statements).

다른 팁

You are getting a high-impedance signal out on Z. This means that your output Z is not driven. You should step through your design in simulation and put traces on your control signals and Z. Your IDE should support this. You most likely do not have the design wired up correctly so it's important to check your datapath and make sure all inputs/outputs are properly connected.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top