Created
August 30, 2025 02:53
-
-
Save neilzheng/6c6d138c584fa762f34a3ce5e6bbcfbb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Description: Implements various bitwise shift and rotate operations | |
// (logical, arithmetic, rotate). | |
module shift_unit | |
import cpu_defines::*; | |
( | |
// Inputs | |
input logic [XLEN-1:0] shift_in_data, // Data to be shifted/rotated | |
input logic [SHIFT_WIDTH-1:0] shift_amount, // Number of bit positions to shift/rotate | |
input shift_ops_t shift_op, // Type of shift/rotate operation | |
// Outputs | |
output logic [XLEN-1:0] shift_out_data, // Result of the operation | |
output logic carry_out_flag, // Last bit shifted out or wrapped around | |
output logic zero_flag, // 1 if alu_result is all zeros | |
output logic negative_flag // 1 if MSB of alu_result is 1 (signed negative) | |
); | |
// Combinational logic block: outputs update immediately with input changes. | |
always_comb begin | |
// Default outputs (when disabled or for unhandled cases) | |
shift_out_data = '0; | |
carry_out_flag = '0; | |
// Handle zero shift amount as a special case | |
if (shift_amount == 0) begin | |
shift_out_data = shift_in_data; // Data remains unchanged | |
end else begin | |
// Handle shift amounts greater than zero | |
case (shift_op) | |
SLL_OP: begin | |
// Shift Left Logical: Zeros fill from LSB | |
// 4 bit number should never greater than or equal to 16 | |
shift_out_data = shift_in_data << shift_amount; | |
carry_out_flag = shift_in_data[SHIFT_WIDTH'(XLEN) - shift_amount]; // Last bit shifted out | |
end | |
SRL_OP: begin | |
// Shift Right Logical: Zeros fill from MSB | |
shift_out_data = shift_in_data >> shift_amount; | |
carry_out_flag = shift_in_data[shift_amount - SHIFT_WIDTH'(1)]; // Last bit shifted out | |
end | |
SRA_OP: begin | |
// Shift Right Arithmetic: Sign bit fills from MSB | |
shift_out_data = $signed(shift_in_data) >>> shift_amount; | |
carry_out_flag = shift_in_data[shift_amount - 1]; // Last bit shifted out | |
end | |
ROR_OP: begin | |
// Rotate Right: Bits wrap around from LSB to MSB | |
shift_out_data = (shift_in_data >> shift_amount) | | |
(shift_in_data << (SHIFT_WIDTH'(XLEN) - shift_amount)); | |
carry_out_flag = shift_in_data[shift_amount - 1]; // Bit that wrapped | |
end | |
default: ; | |
endcase | |
end | |
zero_flag = (shift_out_data == '0); | |
negative_flag = shift_out_data[XLEN-1]; | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment