| `default_nettype none |
| module serv_immdec |
| ( |
| input wire i_clk, |
| //State |
| input wire i_cnt_en, |
| input wire i_cnt_done, |
| //Control |
| input wire i_csr_imm_en, |
| input wire [3:0] i_ctrl, |
| output wire [4:0] o_rd_addr, |
| output wire [4:0] o_rs1_addr, |
| output wire [4:0] o_rs2_addr, |
| //Data |
| output wire o_csr_imm, |
| output wire o_imm, |
| //External |
| input wire i_wb_en, |
| input wire [31:7] i_wb_rdt); |
| |
| reg signbit; |
| |
| reg [8:0] imm19_12_20; |
| reg imm7; |
| reg [5:0] imm30_25; |
| reg [4:0] imm24_20; |
| reg [4:0] imm11_7; |
| |
| reg [4:0] rd_addr; |
| reg [4:0] rs1_addr; |
| reg [4:0] rs2_addr; |
| |
| assign o_rd_addr = rd_addr; |
| assign o_rs1_addr = rs1_addr; |
| assign o_rs2_addr = rs2_addr; |
| |
| assign o_imm = i_cnt_done ? signbit : i_ctrl[0] ? imm11_7[0] : imm24_20[0]; |
| assign o_csr_imm = imm19_12_20[4]; |
| |
| always @(posedge i_clk) begin |
| if (i_wb_en) begin |
| /* CSR immediates are always zero-extended, hence clear the signbit */ |
| signbit <= i_wb_rdt[31] & !i_csr_imm_en; |
| imm19_12_20 <= {i_wb_rdt[19:12],i_wb_rdt[20]}; |
| imm7 <= i_wb_rdt[7]; |
| imm30_25 <= i_wb_rdt[30:25]; |
| imm24_20 <= i_wb_rdt[24:20]; |
| imm11_7 <= i_wb_rdt[11:7]; |
| |
| rd_addr <= i_wb_rdt[11:7]; |
| rs1_addr <= i_wb_rdt[19:15]; |
| rs2_addr <= i_wb_rdt[24:20]; |
| end |
| if (i_cnt_en) begin |
| imm19_12_20 <= {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]}; |
| imm7 <= signbit; |
| imm30_25 <= {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]}; |
| imm24_20 <= {imm30_25[0], imm24_20[4:1]}; |
| imm11_7 <= {imm30_25[0], imm11_7[4:1]}; |
| end |
| end |
| endmodule |