diff --git a/Makefile b/Makefile index 3b6c897..0553133 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ DEVICE = 8k PACKAGE = ct256 PCF = ice40hx8k-b-evn.pcf FREQ_OSC = 12 -FREQ_PLL = 32 +FREQ_PLL = 24 TARGET = riscv64-unknown-elf AS = $(TARGET)-as ASFLAGS = -march=rv32i -mabi=ilp32 diff --git a/rv32.sv b/rv32.sv index 89f76e4..f5ea86c 100644 --- a/rv32.sv +++ b/rv32.sv @@ -51,6 +51,7 @@ module rv32 ( logic decode_mem_fence_unreg; /* decode -> execute control */ + logic decode_valid; logic [4:0] decode_rs1; logic [4:0] decode_rs2; logic [2:0] decode_alu_op; @@ -62,6 +63,9 @@ module rv32 ( logic [1:0] decode_mem_width; logic decode_mem_zero_extend; logic decode_mem_fence; + logic decode_csr_read; + logic decode_csr_write; + logic [1:0] decode_csr_write_op; logic [1:0] decode_branch_op; logic decode_branch_pc_src; logic [4:0] decode_rd; @@ -72,10 +76,15 @@ module rv32 ( logic [31:0] decode_rs1_value; logic [31:0] decode_rs2_value; logic [31:0] decode_imm_value; + logic [11:0] decode_csr; /* execute -> mem control */ + logic execute_valid; logic execute_mem_read; logic execute_mem_write; + logic execute_csr_read; + logic execute_csr_write; + logic [1:0] execute_csr_write_op; logic [1:0] execute_mem_width; logic execute_mem_zero_extend; logic execute_mem_fence; @@ -86,6 +95,7 @@ module rv32 ( /* execute -> mem data */ logic [31:0] execute_result; logic [31:0] execute_rs2_value; + logic [11:0] execute_csr; logic [31:0] execute_branch_pc; /* mem -> writeback control */ @@ -109,6 +119,7 @@ module rv32 ( .decode_mem_read_in(decode_mem_read), .decode_mem_fence_in(decode_mem_fence), + .decode_csr_read_in(decode_csr_read), .decode_rd_in(decode_rd), .decode_rd_write_in(decode_rd_write), @@ -188,6 +199,7 @@ module rv32 ( .mem_fence_unreg_out(decode_mem_fence_unreg), /* control out */ + .valid_out(decode_valid), .rs1_out(decode_rs1), .rs2_out(decode_rs2), .alu_op_out(decode_alu_op), @@ -199,6 +211,9 @@ module rv32 ( .mem_width_out(decode_mem_width), .mem_zero_extend_out(decode_mem_zero_extend), .mem_fence_out(decode_mem_fence), + .csr_read_out(decode_csr_read), + .csr_write_out(decode_csr_write), + .csr_write_op_out(decode_csr_write_op), .branch_op_out(decode_branch_op), .branch_pc_src_out(decode_branch_pc_src), .rd_out(decode_rd), @@ -208,7 +223,8 @@ module rv32 ( .pc_out(decode_pc), .rs1_value_out(decode_rs1_value), .rs2_value_out(decode_rs2_value), - .imm_value_out(decode_imm_value) + .imm_value_out(decode_imm_value), + .csr_out(decode_csr) ); rv32_execute execute ( @@ -219,6 +235,7 @@ module rv32 ( .flush_in(execute_flush), /* control in */ + .valid_in(decode_valid), .rs1_in(decode_rs1), .rs2_in(decode_rs2), .alu_op_in(decode_alu_op), @@ -230,6 +247,9 @@ module rv32 ( .mem_width_in(decode_mem_width), .mem_zero_extend_in(decode_mem_zero_extend), .mem_fence_in(decode_mem_fence), + .csr_read_in(decode_csr_read), + .csr_write_in(decode_csr_write), + .csr_write_op_in(decode_csr_write_op), .branch_op_in(decode_branch_op), .branch_pc_src_in(decode_branch_pc_src), .rd_in(decode_rd), @@ -244,16 +264,21 @@ module rv32 ( .rs1_value_in(decode_rs1_value), .rs2_value_in(decode_rs2_value), .imm_value_in(decode_imm_value), + .csr_in(decode_csr), /* data in (from writeback) */ .writeback_rd_value_in(mem_rd_value), /* control out */ + .valid_out(execute_valid), .mem_read_out(execute_mem_read), .mem_write_out(execute_mem_write), .mem_width_out(execute_mem_width), .mem_zero_extend_out(execute_mem_zero_extend), .mem_fence_out(execute_mem_fence), + .csr_read_out(execute_csr_read), + .csr_write_out(execute_csr_write), + .csr_write_op_out(execute_csr_write_op), .branch_op_out(execute_branch_op), .rd_out(execute_rd), .rd_write_out(execute_rd_write), @@ -261,6 +286,7 @@ module rv32 ( /* data out */ .result_out(execute_result), .rs2_value_out(execute_rs2_value), + .csr_out(execute_csr), .branch_pc_out(execute_branch_pc) ); @@ -272,10 +298,14 @@ module rv32 ( .flush_in(mem_flush), /* control in */ + .valid_in(execute_valid), .read_in(execute_mem_read), .write_in(execute_mem_write), .width_in(execute_mem_width), .zero_extend_in(execute_mem_zero_extend), + .csr_read_in(execute_csr_read), + .csr_write_in(execute_csr_write), + .csr_write_op_in(execute_csr_write_op), .branch_op_in(execute_branch_op), .rd_in(execute_rd), .rd_write_in(execute_rd_write), @@ -283,6 +313,7 @@ module rv32 ( /* data in */ .result_in(execute_result), .rs2_value_in(execute_rs2_value), + .csr_in(execute_csr), .branch_pc_in(execute_branch_pc), /* data in (from memory bus) */ diff --git a/rv32_alu.sv b/rv32_alu.sv index a5c7936..93c8cf2 100644 --- a/rv32_alu.sv +++ b/rv32_alu.sv @@ -16,7 +16,8 @@ `define RV32_ALU_SRC2_REG 2'b00 `define RV32_ALU_SRC2_IMM 2'b01 -`define RV32_ALU_SRC2_FOUR 2'b10 +`define RV32_ALU_SRC2_ZERO 2'b10 +`define RV32_ALU_SRC2_FOUR 2'b11 module rv32_alu ( /* control in */ @@ -63,8 +64,8 @@ module rv32_alu ( case (src2_in) `RV32_ALU_SRC2_REG: src2 = rs2_value_in; `RV32_ALU_SRC2_IMM: src2 = imm_value_in; + `RV32_ALU_SRC2_ZERO: src2 = 0; `RV32_ALU_SRC2_FOUR: src2 = 4; - default: src2 = 32'bx; endcase end diff --git a/rv32_control.sv b/rv32_control.sv index 3eb3aec..ac3eb7f 100644 --- a/rv32_control.sv +++ b/rv32_control.sv @@ -2,6 +2,7 @@ `define RV32_CONTROL `include "rv32_alu.sv" +`include "rv32_csrs.sv" `include "rv32_branch.sv" `include "rv32_imm.sv" `include "rv32_mem.sv" @@ -11,6 +12,10 @@ module rv32_control_unit ( /* data in */ input [31:0] instr_in, + /* control in */ + input [4:0] rs1_in, + input [4:0] rd_in, + /* control out */ output logic valid_out, output logic [2:0] imm_out, @@ -23,6 +28,9 @@ module rv32_control_unit ( output logic [1:0] mem_width_out, output logic mem_zero_extend_out, output logic mem_fence_out, + output logic csr_read_out, + output logic csr_write_out, + output logic [1:0] csr_write_op_out, output logic [1:0] branch_op_out, output logic branch_pc_src_out, output logic rd_write_out @@ -39,6 +47,9 @@ module rv32_control_unit ( mem_width_out = 2'bx; mem_zero_extend_out = 1'bx; mem_fence_out = 0; + csr_read_out = 0; + csr_write_out = 0; + csr_write_op_out = 2'bx; branch_op_out = `RV32_BRANCH_OP_NEVER; branch_pc_src_out = 1'bx; rd_write_out = 0; @@ -410,27 +421,72 @@ module rv32_control_unit ( end `RV32_INSTR_CSRRW: begin valid_out = 1; - // TODO + alu_op_out = `RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out = 0; + alu_src1_out = `RV32_ALU_SRC1_REG; + alu_src2_out = `RV32_ALU_SRC2_ZERO; + csr_read_out = |rd_in; + csr_write_out = 1; + csr_write_op_out = `RV32_CSR_WRITE_OP_RW; + rd_write_out = |rd_in; end `RV32_INSTR_CSRRS: begin valid_out = 1; - // TODO + alu_op_out = `RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out = 0; + alu_src1_out = `RV32_ALU_SRC1_REG; + alu_src2_out = `RV32_ALU_SRC2_ZERO; + csr_read_out = 1; + csr_write_out = |rs1_in; + csr_write_op_out = `RV32_CSR_WRITE_OP_RS; + rd_write_out = 1; end `RV32_INSTR_CSRRC: begin valid_out = 1; - // TODO + alu_op_out = `RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out = 0; + alu_src1_out = `RV32_ALU_SRC1_REG; + alu_src2_out = `RV32_ALU_SRC2_ZERO; + csr_read_out = 1; + csr_write_out = |rs1_in; + csr_write_op_out = `RV32_CSR_WRITE_OP_RC; + rd_write_out = 1; end `RV32_INSTR_CSRRWI: begin valid_out = 1; - // TODO + imm_out = `RV32_IMM_ZIMM; + alu_op_out = `RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out = 0; + alu_src1_out = `RV32_ALU_SRC1_ZERO; + alu_src2_out = `RV32_ALU_SRC2_IMM; + csr_read_out = |rd_in; + csr_write_out = 1; + csr_write_op_out = `RV32_CSR_WRITE_OP_RW; + rd_write_out = |rd_in; end `RV32_INSTR_CSRRSI: begin valid_out = 1; - // TODO + imm_out = `RV32_IMM_ZIMM; + alu_op_out = `RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out = 0; + alu_src1_out = `RV32_ALU_SRC1_ZERO; + alu_src2_out = `RV32_ALU_SRC2_IMM; + csr_read_out = 1; + csr_write_out = |rs1_in; + csr_write_op_out = `RV32_CSR_WRITE_OP_RS; + rd_write_out = 1; end `RV32_INSTR_CSRRCI: begin valid_out = 1; - // TODO + imm_out = `RV32_IMM_ZIMM; + alu_op_out = `RV32_ALU_OP_ADD_SUB; + alu_sub_sra_out = 0; + alu_src1_out = `RV32_ALU_SRC1_ZERO; + alu_src2_out = `RV32_ALU_SRC2_IMM; + csr_read_out = 1; + csr_write_out = |rs1_in; + csr_write_op_out = `RV32_CSR_WRITE_OP_RC; + rd_write_out = 1; end endcase end diff --git a/rv32_csrs.sv b/rv32_csrs.sv new file mode 100644 index 0000000..1b190d0 --- /dev/null +++ b/rv32_csrs.sv @@ -0,0 +1,73 @@ +`ifndef RV32_CSRS +`define RV32_CSRS + +/* |rw|pl| id | */ +`define RV32_CSR_CYCLE 12'b11_00_00000000 +`define RV32_CSR_TIME 12'b11_00_00000001 +`define RV32_CSR_INSTRET 12'b11_00_00000010 +`define RV32_CSR_CYCLEH 12'b11_00_10000000 +`define RV32_CSR_TIMEH 12'b11_00_10000001 +`define RV32_CSR_INSTRETH 12'b11_00_10000010 + +`define RV32_CSR_WRITE_OP_RW 2'b00 +`define RV32_CSR_WRITE_OP_RS 2'b01 +`define RV32_CSR_WRITE_OP_RC 2'b10 + +module rv32_csrs ( + input clk, + + /* control in (from hazard) */ + input stall_in, + + /* control in */ + input read_in, + input write_in, + input [1:0] write_op_in, + + /* control in (from writeback) */ + input instr_retired_in, + + /* data in */ + input [31:0] result_in, + input [11:0] csr_in, + + /* data out */ + output logic [31:0] read_value_out +); + logic [31:0] write_value; + + logic [31:0] cycleh; + logic [31:0] cycle; + + logic [31:0] instreth; + logic [31:0] instret; + + always_comb begin + case (csr_in) + `RV32_CSR_CYCLE: read_value_out = cycle; + `RV32_CSR_TIME: read_value_out = cycle; + `RV32_CSR_INSTRET: read_value_out = instret; + `RV32_CSR_CYCLEH: read_value_out = cycleh; + `RV32_CSR_TIMEH: read_value_out = cycleh; + `RV32_CSR_INSTRETH: read_value_out = instreth; + default: read_value_out = 32'bx; + endcase + + case (write_op_in) + `RV32_CSR_WRITE_OP_RW: write_value = result_in; + `RV32_CSR_WRITE_OP_RS: write_value = read_value_out | result_in; + `RV32_CSR_WRITE_OP_RC: write_value = read_value_out & ~result_in; + default: write_value = 32'bx; + endcase + end + + always_ff @(posedge clk) begin + cycleh <= cycleh + &cycle; + cycle <= cycle + 1; + + instreth <= instreth + &instret; + instret <= instret + instr_retired_in; + end +endmodule + +`endif diff --git a/rv32_decode.sv b/rv32_decode.sv index c4113ce..0aa2049 100644 --- a/rv32_decode.sv +++ b/rv32_decode.sv @@ -28,6 +28,7 @@ module rv32_decode ( output logic mem_fence_unreg_out, /* control out */ + output logic valid_out, output logic [4:0] rs1_out, output logic [4:0] rs2_out, output logic [2:0] alu_op_out, @@ -39,6 +40,9 @@ module rv32_decode ( output logic [1:0] mem_width_out, output logic mem_zero_extend_out, output logic mem_fence_out, + output logic csr_read_out, + output logic csr_write_out, + output logic [1:0] csr_write_op_out, output logic [1:0] branch_op_out, output logic branch_pc_src_out, output logic [4:0] rd_out, @@ -48,7 +52,8 @@ module rv32_decode ( output logic [31:0] pc_out, output logic [31:0] rs1_value_out, output logic [31:0] rs2_value_out, - output logic [31:0] imm_value_out + output logic [31:0] imm_value_out, + output logic [11:0] csr_out ); logic [4:0] rs2; logic [4:0] rs1; @@ -90,6 +95,9 @@ module rv32_decode ( logic [1:0] mem_width; logic mem_zero_extend; logic mem_fence; + logic csr_read; + logic csr_write; + logic [1:0] csr_write_op; logic [1:0] branch_op; logic branch_pc_src; logic rd_write; @@ -100,6 +108,10 @@ module rv32_decode ( /* data in */ .instr_in(instr_in), + /* control in */ + .rs1_in(rs1), + .rd_in(rd), + /* control out */ .valid_out(valid), .imm_out(imm), @@ -112,6 +124,9 @@ module rv32_decode ( .mem_width_out(mem_width), .mem_zero_extend_out(mem_zero_extend), .mem_fence_out(mem_fence), + .csr_read_out(csr_read), + .csr_write_out(csr_write), + .csr_write_op_out(csr_write_op), .branch_op_out(branch_op), .branch_pc_src_out(branch_pc_src), .rd_write_out(rd_write) @@ -130,8 +145,13 @@ module rv32_decode ( .imm_value_out(imm_value) ); + logic [11:0] csr; + + assign csr = instr_in[31:20]; + always_ff @(posedge clk) begin if (!stall_in) begin + valid_out <= valid; rs1_out <= rs1; rs2_out <= rs2; alu_op_out <= alu_op; @@ -143,6 +163,9 @@ module rv32_decode ( mem_width_out <= mem_width; mem_zero_extend_out <= mem_zero_extend; mem_fence_out <= mem_fence; + csr_read_out <= csr_read; + csr_write_out <= csr_write; + csr_write_op_out <= csr_write_op; branch_op_out <= branch_op; branch_pc_src_out <= branch_pc_src; rd_out <= rd; @@ -150,10 +173,14 @@ module rv32_decode ( pc_out <= pc_in; imm_value_out <= imm_value; + csr_out <= csr; if (flush_in) begin + valid_out <= 0; mem_read_out <= 0; mem_write_out <= 0; + csr_read_out <= 0; + csr_write_out <= 0; branch_op_out <= `RV32_BRANCH_OP_NEVER; rd_write_out <= 0; end diff --git a/rv32_execute.sv b/rv32_execute.sv index fdcbceb..4045ee8 100644 --- a/rv32_execute.sv +++ b/rv32_execute.sv @@ -12,6 +12,7 @@ module rv32_execute ( input flush_in, /* control in */ + input valid_in, input [4:0] rs1_in, input [4:0] rs2_in, input [2:0] alu_op_in, @@ -23,6 +24,9 @@ module rv32_execute ( input [1:0] mem_width_in, input mem_zero_extend_in, input mem_fence_in, + input csr_read_in, + input csr_write_in, + input [1:0] csr_write_op_in, input [1:0] branch_op_in, input branch_pc_src_in, input [4:0] rd_in, @@ -37,16 +41,21 @@ module rv32_execute ( input [31:0] rs1_value_in, input [31:0] rs2_value_in, input [31:0] imm_value_in, + input [11:0] csr_in, /* data in (from writeback) */ input [31:0] writeback_rd_value_in, /* control out */ + output logic valid_out, output logic mem_read_out, output logic mem_write_out, output logic [1:0] mem_width_out, output logic mem_zero_extend_out, output logic mem_fence_out, + output logic csr_read_out, + output logic csr_write_out, + output logic [1:0] csr_write_op_out, output logic [1:0] branch_op_out, output logic [4:0] rd_out, output logic rd_write_out, @@ -54,6 +63,7 @@ module rv32_execute ( /* data out */ output logic [31:0] result_out, output logic [31:0] rs2_value_out, + output logic [11:0] csr_out, output logic [31:0] branch_pc_out ); logic [31:0] rs1_value; @@ -111,21 +121,29 @@ module rv32_execute ( always_ff @(posedge clk) begin if (!stall_in) begin + valid_out <= valid_in; mem_read_out <= mem_read_in; mem_write_out <= mem_write_in; mem_width_out <= mem_width_in; mem_zero_extend_out <= mem_zero_extend_in; mem_fence_out <= mem_fence_in; + csr_read_out <= csr_read_in; + csr_write_out <= csr_write_in; + csr_write_op_out <= csr_write_op_in; branch_op_out <= branch_op_in; rd_out <= rd_in; rd_write_out <= rd_write_in; result_out <= result; rs2_value_out <= rs2_value; + csr_out <= csr_in; branch_pc_out <= branch_pc; if (flush_in) begin + valid_out <= 0; mem_read_out <= 0; mem_write_out <= 0; + csr_read_out <= 0; + csr_write_out <= 0; branch_op_out <= `RV32_BRANCH_OP_NEVER; rd_write_out <= 0; end diff --git a/rv32_hazard.sv b/rv32_hazard.sv index 35d455d..079b887 100644 --- a/rv32_hazard.sv +++ b/rv32_hazard.sv @@ -9,6 +9,7 @@ module rv32_hazard_unit ( input decode_mem_read_in, input decode_mem_fence_in, + input decode_csr_read_in, input [4:0] decode_rd_in, input decode_rd_write_in, @@ -42,7 +43,7 @@ module rv32_hazard_unit ( logic mem_wait_for_bus; assign fetch_wait_for_bus = instr_read_in && !instr_ready_in; - assign fetch_wait_for_mem_read = (decode_rs1_unreg_in == decode_rd_in || decode_rs2_unreg_in == decode_rd_in) && |decode_rd_in && decode_mem_read_in && decode_rd_write_in; + assign fetch_wait_for_mem_read = (decode_rs1_unreg_in == decode_rd_in || decode_rs2_unreg_in == decode_rd_in) && |decode_rd_in && (decode_mem_read_in || decode_csr_read_in) && decode_rd_write_in; assign fetch_wait_for_mem_fence = decode_mem_fence_unreg_in || decode_mem_fence_in || execute_mem_fence_in; assign mem_wait_for_bus = (data_read_in || data_write_in) && !data_ready_in; diff --git a/rv32_mem.sv b/rv32_mem.sv index 213d98a..aed6302 100644 --- a/rv32_mem.sv +++ b/rv32_mem.sv @@ -15,10 +15,14 @@ module rv32_mem ( input flush_in, /* control in */ + input valid_in, input read_in, input write_in, input [1:0] width_in, input zero_extend_in, + input csr_read_in, + input csr_write_in, + input [1:0] csr_write_op_in, input [1:0] branch_op_in, input [4:0] rd_in, input rd_write_in, @@ -26,12 +30,14 @@ module rv32_mem ( /* data in */ input [31:0] result_in, input [31:0] rs2_value_in, + input [11:0] csr_in, input [31:0] branch_pc_in, /* data in (from data memory bus) */ input [31:0] data_read_value_in, /* control out */ + output logic valid_out, output logic branch_taken_out, output logic [4:0] rd_out, output logic rd_write_out, @@ -49,6 +55,7 @@ module rv32_mem ( output logic [31:0] data_address_out, output logic [31:0] data_write_value_out ); + /* branch unit */ rv32_branch_unit branch_unit ( /* control in */ .op_in(branch_op_in), @@ -62,11 +69,40 @@ module rv32_mem ( assign branch_pc_out = branch_pc_in; + /* csr file */ + logic [31:0] csr_read_value; + + rv32_csrs csrs ( + .clk(clk), + + /* control in (from hazard) */ + .stall_in(stall_in), + + /* control in */ + .read_in(csr_read_in), + .write_in(csr_write_in), + .write_op_in(csr_write_op_in), + + /* control in (from writeback) */ + .instr_retired_in(valid_out), + + /* data in */ + .result_in(result_in), + .csr_in(csr_in), + + /* data out */ + .read_value_out(csr_read_value) + ); + + logic [31:0] mem_read_value; + + /* memory access unit */ assign data_read_out = read_in; assign data_write_out = write_in; assign data_address_out = result_in; always_comb begin + /* write port */ if (write_in) begin case (width_in) `RV32_MEM_WIDTH_WORD: begin @@ -114,42 +150,53 @@ module rv32_mem ( data_write_value_out = 32'bx; data_write_mask_out = 4'b0; end + + /* read port */ + if (read_in) begin + case (width_in) + `RV32_MEM_WIDTH_WORD: begin + mem_read_value = data_read_value_in; + end + `RV32_MEM_WIDTH_HALF: begin + case (result_in[0]) + 1'b0: mem_read_value = {{16{zero_extend_in ? 1'b0 : data_read_value_in[15]}}, data_read_value_in[15:0]}; + 1'b1: mem_read_value = {{16{zero_extend_in ? 1'b0 : data_read_value_in[31]}}, data_read_value_in[31:16]}; + endcase + end + `RV32_MEM_WIDTH_BYTE: begin + case (result_in[1:0]) + 2'b00: mem_read_value = {{24{zero_extend_in ? 1'b0 : data_read_value_in[7]}}, data_read_value_in[7:0]}; + 2'b01: mem_read_value = {{24{zero_extend_in ? 1'b0 : data_read_value_in[15]}}, data_read_value_in[15:8]}; + 2'b10: mem_read_value = {{24{zero_extend_in ? 1'b0 : data_read_value_in[23]}}, data_read_value_in[23:16]}; + 2'b11: mem_read_value = {{24{zero_extend_in ? 1'b0 : data_read_value_in[31]}}, data_read_value_in[31:24]}; + endcase + end + default: begin + mem_read_value = 32'bx; + end + endcase + end else begin + mem_read_value = 32'bx; + end end always_ff @(posedge clk) begin if (!stall_in) begin + valid_out <= valid_in; rd_out <= rd_in; rd_write_out <= rd_write_in; - if (read_in) begin - case (width_in) - `RV32_MEM_WIDTH_WORD: begin - rd_value_out <= data_read_value_in; - end - `RV32_MEM_WIDTH_HALF: begin - case (result_in[0]) - 1'b0: rd_value_out <= {{16{zero_extend_in ? 1'b0 : data_read_value_in[15]}}, data_read_value_in[15:0]}; - 1'b1: rd_value_out <= {{16{zero_extend_in ? 1'b0 : data_read_value_in[31]}}, data_read_value_in[31:16]}; - endcase - end - `RV32_MEM_WIDTH_BYTE: begin - case (result_in[1:0]) - 2'b00: rd_value_out <= {{24{zero_extend_in ? 1'b0 : data_read_value_in[7]}}, data_read_value_in[7:0]}; - 2'b01: rd_value_out <= {{24{zero_extend_in ? 1'b0 : data_read_value_in[15]}}, data_read_value_in[15:8]}; - 2'b10: rd_value_out <= {{24{zero_extend_in ? 1'b0 : data_read_value_in[23]}}, data_read_value_in[23:16]}; - 2'b11: rd_value_out <= {{24{zero_extend_in ? 1'b0 : data_read_value_in[31]}}, data_read_value_in[31:24]}; - endcase - end - default: begin - rd_value_out <= 32'bx; - end - endcase - end else begin + if (csr_read_in) + rd_value_out <= csr_read_value; + else if (read_in) + rd_value_out <= mem_read_value; + else rd_value_out <= result_in; - end - if (flush_in) + if (flush_in) begin + valid_out <= 0; rd_write_out <= 0; + end end end endmodule