diff --git a/rtl/serv_ctrl.v b/rtl/serv_ctrl.v index 5e55616..a095148 100644 --- a/rtl/serv_ctrl.v +++ b/rtl/serv_ctrl.v @@ -3,25 +3,26 @@ module serv_ctrl ( input wire clk, input wire i_rst, - input wire i_en, + //State input wire i_pc_en, input wire [4:2] i_cnt, input wire [2:1] i_cnt_r, input wire i_cnt_done, + //Control input wire i_jump, - input wire i_offset, - input wire i_rs1, - input wire i_jalr, input wire i_jal_or_jalr, input wire i_utype, - input wire i_lui, + input wire i_pc_rel, input wire i_trap, + //Data + input wire i_imm, + input wire i_buf, input wire i_csr_pc, output wire o_rd, output wire o_bad_pc, - output reg o_misalign = 1'b0, + //External output wire [31:0] o_ibus_adr, - output wire o_ibus_cyc, + output wire o_ibus_cyc, input wire i_ibus_ack); parameter RESET_PC = 32'd8; @@ -38,6 +39,7 @@ module serv_ctrl wire new_pc; wire offset_a; + wire offset_b; assign plus_4 = i_cnt_r[2] & (i_cnt[4:2] == 3'd0); @@ -71,15 +73,16 @@ module serv_ctrl assign new_pc = i_trap ? (i_csr_pc & en_pc_r) : i_jump ? pc_plus_offset_aligned : pc_plus_4; assign o_rd = (i_utype & pc_plus_offset_aligned) | (pc_plus_4 & i_jal_or_jalr); - assign offset_a = !i_lui & (i_jalr ? i_rs1 : pc); + assign offset_a = i_pc_rel & pc; + assign offset_b = i_utype ? i_imm : i_buf; ser_add ser_add_pc_plus_offset ( .clk (clk), .rst (i_rst), .a (offset_a), - .b (i_offset), - .clr (!i_en | i_cnt_done), + .b (offset_b), + .clr (!i_pc_en), .q (pc_plus_offset), .o_v ()); @@ -93,8 +96,6 @@ module serv_ctrl else if (o_ibus_cyc & i_ibus_ack) en_pc_r <= 1'b0; - if ((i_cnt[4:2] == 3'd0) & i_cnt_r[1]) - o_misalign <= pc_plus_offset; if (i_rst) begin en_pc_r <= 1'b1; end diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index eaf9397..6b52aca 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -11,15 +11,15 @@ module serv_decode output reg [3:0] o_cnt_r, output wire o_cnt_done, output reg o_bufreg_hold, + output wire o_bufreg_rs1_en, output wire o_bufreg_imm_en, output wire o_bufreg_loop, - output wire o_ctrl_en, output wire o_ctrl_pc_en, output reg o_ctrl_jump, output wire o_ctrl_jalr, output wire o_ctrl_jal_or_jalr, output wire o_ctrl_utype, - output wire o_ctrl_lui, + output wire o_ctrl_pc_rel, output wire o_ctrl_trap, output reg o_ctrl_mret, input wire i_ctrl_misalign, @@ -100,7 +100,13 @@ module serv_decode assign e_op = (opcode[4:2] == 3'b111) & !op21 & !(|o_funct3); + //jal,branch = imm + //jalr = rs1+imm + //mem = rs1+imm + //shift = rs1 + assign o_bufreg_rs1_en = !opcode[4] | (!opcode[1] & opcode[0]); assign o_bufreg_imm_en = !opcode[2]; + assign o_bufreg_loop = op_or_opimm & !(state == INIT); assign o_ctrl_pc_en = running | o_ctrl_trap; @@ -117,6 +123,12 @@ module serv_decode assign o_ctrl_utype = !opcode[4] & opcode[2] & opcode[0]; assign o_ctrl_jal_or_jalr = opcode[4] & opcode[0]; + //True for jal, b* auipc + //False for jalr, lui + assign o_ctrl_pc_rel = (opcode[2:0] == 3'b000) | + (opcode[1:0] == 2'b11) | + (opcode[4:3] == 2'b00); + wire mret = (i_wb_rdt[6] & i_wb_rdt[4] & i_wb_rdt[21] & !(|i_wb_rdt[14:12])); assign o_rf_rd_en = running & (opcode[2] | @@ -124,10 +136,6 @@ module serv_decode (!opcode[2] & !opcode[3] & !opcode[0])); assign o_alu_en = cnt_en; - assign o_ctrl_en = cnt_en; - - assign o_ctrl_lui = (opcode[0] & !opcode[4] & opcode[3]); - assign o_alu_init = (state == INIT); diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 707a0c8..20d39c9 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -54,9 +54,7 @@ module serv_top wire csr_rd; wire rd; - wire ctrl_en; wire ctrl_pc_en; - wire ctrl_misalign; wire jump; wire jalr; wire jal_or_jalr; @@ -64,6 +62,7 @@ module serv_top wire mret; wire imm; wire trap; + wire pc_rel; wire [4:0] cnt; wire [3:0] cnt_r; @@ -72,6 +71,7 @@ module serv_top wire [2:0] funct3; wire bufreg_hold; + wire bufreg_rs1_en; wire bufreg_imm_en; wire bufreg_loop; wire bufreg_q; @@ -121,8 +121,6 @@ module serv_top parameter RESET_PC = 32'd8; - wire lui; - wire new_irq; serv_decode decode @@ -137,18 +135,18 @@ module serv_top .o_cnt_r (cnt_r), .o_cnt_done (cnt_done), .o_bufreg_hold (bufreg_hold), + .o_bufreg_rs1_en (bufreg_rs1_en), .o_bufreg_imm_en (bufreg_imm_en), .o_bufreg_loop (bufreg_loop), - .o_ctrl_en (ctrl_en), .o_ctrl_pc_en (ctrl_pc_en), .o_ctrl_jump (jump), .o_ctrl_jalr (jalr), .o_ctrl_jal_or_jalr (jal_or_jalr), .o_ctrl_utype (utype), - .o_ctrl_lui (lui), + .o_ctrl_pc_rel (pc_rel), .o_ctrl_trap (trap), .o_ctrl_mret (mret), - .i_ctrl_misalign(ctrl_misalign), + .i_ctrl_misalign(lsb[1]), .o_funct3 (funct3), .o_alu_en (alu_en), .o_alu_init (alu_init), @@ -197,10 +195,10 @@ module serv_top .i_cnt (cnt[4:2]), .i_cnt_r (cnt_r[1:0]), .i_en (!(bufreg_hold | o_dbus_cyc)), - .i_clr (!mem_en), + .i_clr (!(mem_en | (jal_or_jalr & alu_init))), //FIXME .i_loop (bufreg_loop), .i_rs1 (rs1), - .i_rs1_en (1'b1), + .i_rs1_en (bufreg_rs1_en), .i_imm (imm), .i_imm_en (bufreg_imm_en), .o_lsb (lsb), @@ -213,23 +211,24 @@ module serv_top ( .clk (clk), .i_rst (i_rst), - .i_en (ctrl_en), + //State .i_pc_en (ctrl_pc_en), .i_cnt (cnt[4:2]), .i_cnt_r (cnt_r[2:1]), .i_cnt_done (cnt_done), + //Control .i_jump (jump), - .i_offset (imm), - .i_rs1 (rs1), - .i_jalr (jalr), - .i_jal_or_jalr (jal_or_jalr), + .i_jal_or_jalr (jal_or_jalr), .i_utype (utype), - .i_lui (lui), + .i_pc_rel (pc_rel), .i_trap (trap | mret), + //Data + .i_imm (imm), + .i_buf (bufreg_q), .i_csr_pc (csr_rd), .o_rd (ctrl_rd), .o_bad_pc (bad_pc), - .o_misalign (ctrl_misalign), + //External .o_ibus_adr (o_ibus_adr), .o_ibus_cyc (o_ibus_cyc), .i_ibus_ack (i_ibus_ack));