diff options
author | Sergey Bikovsky <bsv.serg@gmail.com> | 2015-09-17 02:13:38 +0300 |
---|---|---|
committer | Sergey Bikovsky <bsv.serg@gmail.com> | 2015-09-17 02:13:38 +0300 |
commit | b3d9beada656bce070e8aeb2d74a859a29a54b56 (patch) | |
tree | a08f6563de32c4751461549d34e80a0f764b8f67 /hdl/ex_stage.v | |
download | MIPSLabs-b3d9beada656bce070e8aeb2d74a859a29a54b56.zip MIPSLabs-b3d9beada656bce070e8aeb2d74a859a29a54b56.tar.gz MIPSLabs-b3d9beada656bce070e8aeb2d74a859a29a54b56.tar.bz2 |
init repo
Diffstat (limited to 'hdl/ex_stage.v')
-rw-r--r-- | hdl/ex_stage.v | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/hdl/ex_stage.v b/hdl/ex_stage.v new file mode 100644 index 0000000..cca87e9 --- /dev/null +++ b/hdl/ex_stage.v @@ -0,0 +1,120 @@ +module ex_stage( + input clk, + input rst, + + input wb_reg_write, + input wb_mem_to_reg, + + input mem_read, + input mem_write, + + input ex_imm_command, + input ex_alu_src_b, + input ex_dst_reg_sel, + input [1:0] ex_alu_op, + + input [31:0] A, + input [31:0] B, + input [31:0] sign_extend_offset, + input [4:0] rt, // target register + input [4:0] rd, // destination register + input [5:0] opcode, + input [1:0] rs_fwd_sel, // forwarding muxes control + input [1:0] rt_fwd_sel, // forwarding muxes control + input [31:0] mem_fwd_val, // forwarding from EX_MEM + input [31:0] wb_fwd_val, // forwarding from WB + + // outputs + output [4:0] ex_dst_reg, + output [5:0] ex_opcode, + + output reg [31:0] EX_MEM_alu_result, + output reg [31:0] EX_MEM_B_value, + output reg [4:0] EX_MEM_dst_reg, + output reg [5:0] EX_MEM_opcode, + output reg EX_MEM_mem_read, + output reg EX_MEM_mem_write, + output reg EX_MEM_wb_reg_write, + output reg EX_MEM_wb_mem_to_reg +); + + + wire [5:0] func_field; // func code field in instruction + wire [5:0] func_code; // func code for ALU control + wire [4:0] alu_ctl; // ALU control lines + + reg [31:0] alu_a_in; + wire [31:0] alu_b_in; + reg[31:0] b_value; + + wire [31:0] alu_result; + wire zero; + + + always @* + begin + case(rs_fwd_sel) + 0: alu_a_in = A; + 1: alu_a_in = mem_fwd_val; + 2: alu_a_in = wb_fwd_val; + endcase + end + + always @* + begin + case(rt_fwd_sel) + 0: b_value = B; + 1: b_value = mem_fwd_val; + 2: b_value = wb_fwd_val; + endcase + end + + assign alu_b_in = ex_alu_src_b ? sign_extend_offset : b_value; + assign func_field = sign_extend_offset [5:0]; // looks wierd, but func code is encoded there + assign func_code = ex_imm_command ? {{2'b10},{~opcode[2] & opcode[1] & ~opcode[0]},opcode[2:0]} : func_field; + assign ex_opcode = opcode; + assign ex_dst_reg = ex_dst_reg_sel ? rd : rt; + + + + alu_ctrl aluctl_inst( + .alu_op (ex_alu_op), + .func_code (func_code), + .alu_ctl (alu_ctl) + ); + + alu alu_inst ( + .alu_ctl (alu_ctl), + .a_in (alu_a_in), + .b_in (alu_b_in), + .result (alu_result), + .zero_flag (zero) + ); + + // EX/MEM Pipeline register + always @(posedge clk) begin + if (rst) + begin + EX_MEM_alu_result <= 0; + EX_MEM_B_value <= 0; + EX_MEM_dst_reg <= 0; + EX_MEM_mem_read <= 0; + EX_MEM_mem_write <= 0; + EX_MEM_wb_reg_write <= 0; + EX_MEM_wb_mem_to_reg <= 0; + end + else + begin + EX_MEM_alu_result <= alu_result; + EX_MEM_B_value <= b_value; + EX_MEM_dst_reg <= ex_dst_reg; + EX_MEM_opcode <= opcode; + EX_MEM_mem_read <= mem_read; + EX_MEM_mem_write <= mem_write; + EX_MEM_wb_reg_write <= wb_reg_write; + EX_MEM_wb_mem_to_reg <= wb_mem_to_reg; + end + end + + +endmodule |