136 lines
3.9 KiB
Verilog
136 lines
3.9 KiB
Verilog
`timescale 1ns / 1ps
|
|
module InstDecode (
|
|
input clk,
|
|
input reset,
|
|
// From prev stage
|
|
input [31:0] prev_fetched_instruction,
|
|
input [31:0] prev_PC_plus_4,
|
|
// For hazard unit
|
|
input 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 PC_plus_4 = IFID_PC_plus_4;
|
|
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 [1:0] 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),
|
|
.reset(reset),
|
|
.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
|
|
if (reset) begin
|
|
IFID_instruction <= 32'h00000000;
|
|
IFID_PC_plus_4 <= 32'h00000000;
|
|
end else begin
|
|
if (IFIDSrc == 1'b1) begin
|
|
IFID_instruction <= 32'h00000000;
|
|
IFID_PC_plus_4 <= 32'h00000000;
|
|
end else begin
|
|
IFID_instruction <= prev_fetched_instruction;
|
|
IFID_PC_plus_4 <= prev_PC_plus_4;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|