module DecodUnit#(parameter xlen = 32)(
input clk, // posedge
input wire reset_n, // Active low; synchronous
input wire [xlen-1:0] current_instruction, // Received from Fetch unit
input wire [xlen-1:0] current_pc, // Received from Fetch unit
output reg [3:0] operation, // sent to the EX
output reg [$clog2(xlen)-1:0] src1_addr, // Sent to the Register file
output reg [$clog2(xlen)-1:0] src2_addr, // Sent to the Register file
output reg [$clog2(xlen)-1:0] dest_addr, // Sent to the Register file
output reg [xlen-1:0] imm, // sent to the EX
output reg use_imm, // sent to the EX
output reg is_load_store // Sent to the memory and writeback unit
);
// Intermediate signals for instruction decoding
reg [6:0] opcode;
reg [2:0] funct3;
reg [6:0] funct7;
// Enum definition for operations
typedef enum logic [4:0] {
ADD,
SUB,
SLT,
SLTU,
XOR,
OR,
AND,
SLL,
SRA,
SRL,
ADDI,
SLTI,
SLTIU,
XORI,
ORI,
ANDI,
SLLI,
SRLI,
SRAI
} operation_t;
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
// Synchronous reset
operation <= 0;
src1_addr <= 0;
src2_addr <= 0;
dest_addr <= 0;
imm <= 0;
use_imm <= 0;
is_load_store <= 0;
end
else begin
// Extract instruction fields
opcode <= current_instruction[6:0];
dest_addr <= current_instruction[11:7];
funct3 <= current_instruction[14:12];
src1_addr <= current_instruction[19:15];
src2_addr <= current_instruction[24:20];
funct7 <= current_instruction[31:25];
// Decode the instruction
case (opcode)
7'b0110011: begin // R-Type
use_imm <= 0;
case (funct3)
3'b000: operation <= (funct7 == 7'b0000000) ? ADD : SUB;
3'b001: operation <= SLL;
3'b010: operation <= SLT;
3'b011: operation <= SLTU;
3'b100: operation <= XOR;
3'b101: operation <= (funct7 == 7'b0000000) ? SRL : SRA;
3'b110: operation <= OR;
3'b111: operation <= AND;
default: operation <= 0;
endcase
end
7'b0010011: begin // I-Type
use_imm <= 1;
imm <= {{20{current_instruction[31]}}, current_instruction[31:20]}; //
Immediate value with sign extension
case (funct3)
3'b000: operation <= ADDI;
3'b010: operation <= SLTI;
3'b011: operation <= SLTIU;
3'b100: operation <= XORI;
3'b110: operation <= ORI;
3'b111: operation <= ANDI;
3'b001: operation <= SLLI;
3'b101: operation <= (funct7 == 7'b0000000) ? SRLI : SRAI;
default: operation <= 0;
endcase
end
default: begin
// Handle other opcodes like load/store here
operation <= 0;
use_imm <= 0;
is_load_store <= 0;
end
endcase
end
end
endmodule