Files
MipsPipelineProcessor/PipelineProcessor.srcs/sources_1/new/InstDecode.v
2024-07-10 12:06:19 +08:00

139 lines
4.0 KiB
Verilog

`timescale 1ns / 1ps
module InstDecode (
input clk,
// From prev stage
input [31:0] prev_fetched_instruction,
input [31:0] prev_PC_plus_4,
// For hazard unit
input [1:0] IFIDSrc,
// From WB stage
input WB_write_enable,
input [4:0] WB_write_address,
input [31:0] WB_write_data,
// To IF stage
output [1:0] PC_jump,
output [31:0] jump_target,
output [31:0] jump_register_target,
// To hazard unit
output is_loadword,
// To next stage
output is_branch,
output WB_source,
output memory_write,
output [4:0] ALU_function,
output ALU_source1,
output ALU_source2,
output register_write_destination_source,
output register_write,
output [31:0] PC_plus_4,
output [31:0] register_file_read_A,
output [31:0] register_file_read_B,
output [4:0] shamt,
output [31:0] extended_immediate,
output [4:0] rs_address,
output [4:0] rt_address,
output [4:0] rd_address
);
reg [31:0] IFID_instruction;
reg [31:0] IFID_PC_plus_4;
wire [ 5:0] opcode;
wire [ 4:0] rs;
wire [ 4:0] rt;
wire [ 4:0] rd;
wire [ 5:0] funct;
wire [25:0] j_addr;
wire [15:0] immediate;
// Signals derived from instruction
assign opcode = IFID_instruction[31:26];
assign rs = IFID_instruction[25:21];
assign rt = IFID_instruction[20:16];
assign rd = IFID_instruction[15:11];
assign shamt = IFID_instruction[10:6];
assign funct = IFID_instruction[5:0];
assign j_addr = IFID_instruction[25:0];
assign immediate = IFID_instruction[15:0];
// This output is directly derived from IFID regs
assign jump_target = {IFID_PC_plus_4[31:28], j_addr, 2'b00};
assign rs_address = rs;
assign rt_address = rt;
assign rd_address = rd;
// Signals to connect from control unit to register file and immediate extend unit
wire write_ra;
wire ra_addr_source;
wire extendop;
ControlUnit control_unit (
.opcode(opcode),
.funct(funct),
.PC_jump(PC_jump),
.is_branch(is_branch),
.is_loadword(is_loadword),
.write_ra(write_ra),
.ra_addr_source(ra_addr_source),
.WB_source(WB_source),
.memory_write(memory_write),
.ALU_function(ALU_function),
.ALU_source1(ALU_source1),
.ALU_source2(ALU_source2),
.register_write(register_write),
.register_write_destination_source(register_write_destination_source),
.extendop(extendop)
);
// Signal for register file
wire [31:0] RF_read_A_out;
wire [ 4:0] write_ra_addr_after_mux;
assign write_ra_addr_after_mux = (ra_addr_source == 1'b0) ? 5'b11111 : rd;
RegisterFile register_file (
.clk(clk),
.read_addr1(rs),
.read_addr2(rt),
.write_enable(WB_write_enable),
.write_addr(WB_write_address),
.write_data(WB_write_data),
.write_ra(write_ra),
.write_ra_addr(write_ra_addr_after_mux),
.write_ra_data(IFID_PC_plus_4),
.read_output1(RF_read_A_out),
.read_output2(register_file_read_B)
);
assign register_file_read_A = RF_read_A_out;
assign jump_register_target = RF_read_A_out;
ImmediateExtender immediate_extender(
.immediate(immediate),
.extendop(extendop),
.extended_immediate(extended_immediate)
);
always @(posedge clk) begin
case (IFIDSrc)
2'b00: begin
IFID_instruction <= prev_fetched_instruction;
IFID_PC_plus_4 <= prev_PC_plus_4;
end
2'b01: begin
IFID_instruction <= 32'h00000000;
IFID_PC_plus_4 <= 32'h00000000;
end
2'b10: begin
IFID_instruction <= IFID_instruction;
IFID_PC_plus_4 <= IFID_PC_plus_4;
end
default: begin
IFID_instruction <= 32'h00000000;
IFID_PC_plus_4 <= 32'h00000000;
end
endcase
end
endmodule