I'm new at learning Verilog so some of my practices are based on already existing codes. I was reading the RISC-V implementation of arithmetic shift and didn't quite understand why it's that way when it can be a simple shift operator.

Since I'm a newbie at this topic I want to know if there's any practical difference between both implementations.

RISC-V Implementation snippet:

       // Shift Left
       `ALU_SHIFTL :
            if (alu_b_i[0] == 1'b1)
                shift_left_1_r = {alu_a_i[30:0],1'b0};
                shift_left_1_r = alu_a_i;

            if (alu_b_i[1] == 1'b1)
                shift_left_2_r = {shift_left_1_r[29:0],2'b00};
                shift_left_2_r = shift_left_1_r;

            if (alu_b_i[2] == 1'b1)
                shift_left_4_r = {shift_left_2_r[27:0],4'b0000};
                shift_left_4_r = shift_left_2_r;

            if (alu_b_i[3] == 1'b1)
                shift_left_8_r = {shift_left_4_r[23:0],8'b00000000};
                shift_left_8_r = shift_left_4_r;

            if (alu_b_i[4] == 1'b1)
                result_r = {shift_left_8_r[15:0],16'b0000000000000000};
                result_r = shift_left_8_r;

Almost equivalent snippet:

    always @ (posedge clk) begin
        data_out <= data_in <<< shift;

1 Answer 1


The RISC-V implementation explicitly creates a barrel shifter. A good Verilog compiler would create the same implementation from the <<< operator if that operator were used in a combinational procedural block. Since you didn't show us the entirety of the block I can't be sure about this. It's possible that this code could be part of a synchronous block, even though the code doesn't use non-blocking assignments, but I doubt it.

The code that you suggest is a synchronous block requiring that the shift be performed in a single cycle.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.