0
votes

For a lab in a digital design course I am designing a partial ALU. I have defined its operations, and am required to use a casez statement to govern which function (either addition of a & b w/ overflow checking, bitwise inversion of b, a AND b, and a OR b) is selected by the four 2-bit combos of sel:

module eightbit_palu(input  wire[7:0] a, b,
                     input  wire[1:0] sel,
                     output wire[7:0] f,
                     output wire ovf);
                     
    wire[7:0] sum, bitInv, bitAnd, bitOr;
    wire sumOvf;
    
    assign sum = a + b;
    assign sumOvf = (a+b>127)||(a+b<-128) ? 1 : 0;
    assign bitInv = !b;
    assign bitAnd = a & b;
    assign bitOr = a | b;
    
    always @(a or b or sel) begin
        casez(sel)
            2'b00: f = sum; ovf = sumOvf;
            2'b01: f = bitInv; ovf = 0;
            2'b10: f = bitAnd; ovf = 0;
            2'b11: f = bitOr; ovf = 0;
        endcase
    end
    
endmodule

I have embdedded the casez statement within an always @ but I am getting a syntax error that I believe might be due to the outputs being wires; but I am not sure how to work around that seemingly simple issue. I tried turning the variables declared before the assign statements into regs, but then there was a problem converting them to wires. Would really appreaciate some insight as to how Verilog works—unfortunately my professor is teaching in SystemVerilog yet our labs are required to be in Verilog!

Thanks.

1
There's no specific need to use casez here if your truth table is correct.Light
! is a logical negation operator. Since you're doing bitwise inversion, you need use ~ instead.Light

1 Answers

1
votes

Yes, you should change your output wires to reg since you are making procedural assignments to them (inside an always block).

The other error is that you need to add begin/end keywords around multiple statements in each case item. Here is code that compiles cleanly for me:

module eightbit_palu(input  wire[7:0] a, b,
                     input  wire[1:0] sel,
                     output reg [7:0] f,
                     output reg ovf);
                     
    wire[7:0] sum, bitInv, bitAnd, bitOr;
    wire sumOvf;
    
    assign sum = a + b;
    assign sumOvf = (a+b>127)||(a+b<-128) ? 1 : 0;
    assign bitInv = !b;
    assign bitAnd = a & b;
    assign bitOr = a | b;
    
    always @(a or b or sel) begin
        casez(sel)
            2'b00: begin f = sum;    ovf = sumOvf; end
            2'b01: begin f = bitInv; ovf = 0;      end
            2'b10: begin f = bitAnd; ovf = 0;      end
            2'b11: begin f = bitOr;  ovf = 0;      end
        endcase
    end
    
endmodule

You also have a problem with this line:

always @(a or b or sel) begin

A sensitivity list should include only signals on the RHS of assignments within the block. Your list incorrectly includes a and b, and it misses others like sum. You should use an implicit sensitivity list which automatically includes the appropriate signals.

always @*