From a614e427b8deb47484c24a6b4e49d9de3f6d0488 Mon Sep 17 00:00:00 2001 From: Olof Kindgren Date: Fri, 12 Jun 2020 22:23:02 +0200 Subject: [PATCH] Move immediate decoder to separate module --- rtl/serv_decode.v | 39 +++++++-------------------------------- rtl/serv_immdec.v | 41 +++++++++++++++++++++++++++++++++++++++++ rtl/serv_top.v | 15 +++++++++++++-- serv.core | 1 + 4 files changed, 62 insertions(+), 34 deletions(-) create mode 100644 rtl/serv_immdec.v diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index d66a1e0..1dbfdef 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -4,7 +4,6 @@ module serv_decode input wire clk, //Input input wire i_cnt_en, - input wire i_cnt_done, input wire [31:2] i_wb_rdt, input wire i_wb_en, input wire i_alu_cmp, @@ -54,7 +53,7 @@ module serv_decode output wire o_csr_d_sel, output wire o_csr_imm, //To top - output wire o_imm, + output wire [3:0] o_immdec_ctrl, output wire o_op_b_source, output wire o_rd_csr_en, output wire o_rd_alu_en); @@ -172,20 +171,14 @@ module serv_decode assign o_alu_bool_op = funct3[1:0]; - 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; - - wire [1:0] m2; + //True for S (STORE) or B (BRANCH) type instructions + //False for J type instructions + assign o_immdec_ctrl[0] = opcode[3:0] == 4'b1000; //True for OP-IMM, LOAD, STORE, JALR //False for LUI, AUIPC, JAL - assign m2[0] = (opcode[1:0] == 2'b00) | (opcode[2:1] == 2'b00); - assign m2[1] = opcode[4] & !opcode[0]; - wire m3 = opcode[4]; + assign o_immdec_ctrl[1] = (opcode[1:0] == 2'b00) | (opcode[2:1] == 2'b00); + assign o_immdec_ctrl[2] = opcode[4] & !opcode[0]; + assign o_immdec_ctrl[3] = opcode[4]; assign o_alu_rd_sel[0] = (funct3 == 3'b000); // Add/sub assign o_alu_rd_sel[1] = (funct3[1:0] == 2'b01); //Shift @@ -204,31 +197,13 @@ module serv_decode op22 <= i_wb_rdt[22]; op26 <= i_wb_rdt[26]; - //Immediate decoder - signbit <= i_wb_rdt[31]; - 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]; end if (i_cnt_en) begin - imm19_12_20 <= {m3 ? signbit : imm24_20[0], imm19_12_20[8:1]}; - imm7 <= signbit; - imm30_25 <= {m2[1] ? imm7 : m2[0] ? 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]}; if (csr_op & o_csr_d_sel) o_rf_rs1_addr <= {1'b0,o_rf_rs1_addr[4:1]}; end end - //True for S (STORE) or B (BRANCH) type instructions - //False for J type instructions - wire m1 = opcode[3:0] == 4'b1000; - - assign o_imm = i_cnt_done ? signbit : m1 ? imm11_7[0] : imm24_20[0]; - //0 (OP_B_SOURCE_IMM) when OPIMM //1 (OP_B_SOURCE_RS2) when BRANCH or OP assign o_op_b_source = opcode[3]; diff --git a/rtl/serv_immdec.v b/rtl/serv_immdec.v new file mode 100644 index 0000000..1e6d61a --- /dev/null +++ b/rtl/serv_immdec.v @@ -0,0 +1,41 @@ +`default_nettype none +module serv_immdec + ( + input wire i_clk, + //Input + input wire i_cnt_en, + input wire [31:2] i_wb_rdt, + input wire i_wb_en, + input wire i_cnt_done, + input wire [3:0] i_ctrl, + output wire o_imm); + + 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; + + + assign o_imm = i_cnt_done ? signbit : i_ctrl[0] ? imm11_7[0] : imm24_20[0]; + + always @(posedge i_clk) begin + if (i_wb_en) begin + signbit <= i_wb_rdt[31]; + 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]; + 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 diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 65b59b0..2e1a988 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -61,6 +61,8 @@ module serv_top wire [4:0] rs1_addr; wire [4:0] rs2_addr; + wire [3:0] immdec_ctrl; + wire take_branch; wire e_op; wire ebreak; @@ -198,7 +200,6 @@ module serv_top .clk (clk), //Input .i_cnt_en (cnt_en), - .i_cnt_done (cnt_done), .i_wb_rdt (i_ibus_rdt[31:2]), .i_wb_en (o_ibus_cyc & i_ibus_ack), .i_alu_cmp (alu_cmp), @@ -249,10 +250,20 @@ module serv_top .o_csr_d_sel (csr_d_sel), .o_csr_imm (csr_imm), //To top - .o_imm (imm), + .o_immdec_ctrl (immdec_ctrl), .o_rd_csr_en (rd_csr_en), .o_rd_alu_en (rd_alu_en)); + serv_immdec immdec + ( + .i_clk (clk), + .i_cnt_en (cnt_en), + .i_wb_rdt (i_ibus_rdt[31:2]), + .i_wb_en (o_ibus_cyc & i_ibus_ack), + .i_ctrl (immdec_ctrl), + .i_cnt_done (cnt_done), + .o_imm (imm)); + serv_bufreg bufreg ( .i_clk (clk), diff --git a/serv.core b/serv.core index a0c2fa4..c848468 100644 --- a/serv.core +++ b/serv.core @@ -12,6 +12,7 @@ filesets: - rtl/serv_csr.v - rtl/serv_ctrl.v - rtl/serv_decode.v + - rtl/serv_immdec.v - rtl/serv_mem_if.v - rtl/serv_rf_if.v - rtl/serv_rf_ram_if.v