From b8f5133267047de6460f442c785e44b752b5f24b Mon Sep 17 00:00:00 2001 From: Olof Kindgren Date: Fri, 23 Nov 2018 13:59:07 +0100 Subject: [PATCH] Random optimizations --- rtl/serv_csr.v | 14 ++++--- rtl/serv_decode.v | 95 +++++++++++++++++++++------------------------- rtl/serv_mem_if.v | 95 +++++++++++++++++++++++++++------------------- rtl/serv_params.vh | 6 --- rtl/serv_top.v | 23 +++++++---- 5 files changed, 121 insertions(+), 112 deletions(-) diff --git a/rtl/serv_csr.v b/rtl/serv_csr.v index ec7ec87..e60cb48 100644 --- a/rtl/serv_csr.v +++ b/rtl/serv_csr.v @@ -14,12 +14,14 @@ module serv_csr `include "serv_params.vh" /* - mtvec RW - mepc RW - mstatus RWSC - mcause R - mip CWi - mie SCWi + 304 mie SCWi + 305 mtvec RW + 340 mscratch + 341 mepc RW + 300 mstatus RWSC + 342 mcause R + 343 mtval + 344 mip CWi */ reg [31:0] mtvec = 32'h0; diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index bab38ba..316e68b 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -35,7 +35,7 @@ module serv_decode output wire o_mem_en, output wire o_mem_cmd, output wire o_mem_init, - output reg o_mem_dat_valid, + output wire [1:0] o_mem_bytecnt, input wire i_mem_dbus_ack, input wire i_mem_misalign, output wire o_csr_en, @@ -47,7 +47,10 @@ module serv_decode output reg [2:0] o_funct3, output wire o_imm, output wire o_op_b_source, - output wire [1:0] o_rd_source); + output wire o_rd_ctrl_en, + output wire o_rd_alu_en, + output wire o_rd_csr_en, + output wire o_rd_mem_en); `include "serv_params.vh" @@ -89,27 +92,26 @@ module serv_decode assign o_ibus_active = (state == IDLE); - assign mem_op = (opcode == OP_LOAD) | (opcode == OP_STORE); + assign mem_op = !opcode[4] & !opcode[2] & !opcode[0]; + assign shift_op = ((opcode == OP_OPIMM) & (o_funct3[1:0] == 2'b01)) | ((opcode == OP_OP ) & (o_funct3[1:0] == 2'b01)); - assign slt_op = (((opcode == OP_OPIMM) | (opcode == OP_OP)) & - (o_funct3[2:1] == 2'b01)); + assign slt_op = (!opcode[4] & opcode[2] & !opcode[0]) & + (o_funct3[2:1] == 2'b01); - assign branch_op = (opcode == OP_BRANCH); + assign branch_op = (opcode[4:2] == 3'b110) & !opcode[0]; - assign e_op = (opcode == OP_SYSTEM) & !(|o_funct3); + assign e_op = (opcode[4:2] == 3'b111) & !(|o_funct3); assign o_ctrl_pc_en = running | o_ctrl_trap; - assign o_ctrl_jump = (opcode == OP_JAL) | - (opcode == OP_JALR) | - (branch_op & i_alu_cmp); + assign o_ctrl_jump = (opcode[4:2] == 3'b110) & (opcode[0] | i_alu_cmp); - assign o_ctrl_jalr = (opcode == OP_JALR); + assign o_ctrl_jalr = opcode[4] & (opcode[2:0] == 3'b001); assign o_ctrl_auipc = (opcode == OP_AUIPC); - assign o_ctrl_mret = (opcode == OP_SYSTEM) & imm[21] & !(|o_funct3); + assign o_ctrl_mret = (opcode == OP_SYSTEM) & op[21] & !(|o_funct3); assign o_rf_rd_en = running & !o_ctrl_trap & (opcode != OP_STORE) & @@ -137,7 +139,9 @@ module serv_decode assign o_csr_en = ((((opcode == OP_SYSTEM) & (|o_funct3)) | o_ctrl_mret) & running) | o_ctrl_trap; - always @(o_funct3, imm) begin + wire [3:0] csr_sel = {op[26],op[22:20]}; + + always @(o_funct3, op, csr_sel) begin casez (o_funct3) 3'b00? : o_alu_cmp_sel = ALU_CMP_EQ; 3'b01? : o_alu_cmp_sel = ALU_CMP_LT; @@ -174,17 +178,19 @@ module serv_decode if (((o_rf_rs1_addr == 5'd0) & o_funct3[1]) | o_ctrl_trap | o_ctrl_mret) o_csr_source = CSR_SOURCE_CSR; - casez(imm[31:20]) - 12'h305 : o_csr_sel = CSR_SEL_MTVEC; - 12'h340 : o_csr_sel = CSR_SEL_MSCRATCH; - 12'h341 : o_csr_sel = CSR_SEL_MEPC; - 12'h342 : o_csr_sel = CSR_SEL_MCAUSE; - 12'h343 : o_csr_sel = CSR_SEL_MTVAL; - //12'hf14 : o_csr_sel = CSR_SEL_MHARTID; + casez(csr_sel) + //4'b0_000 : o_csr_sel = CSR_SEL_MSTATUS; + //4'b0_100 : o_csr_sel = CSR_SEL_MIE; + 4'b0_101 : o_csr_sel = CSR_SEL_MTVEC; + 4'b1_000 : o_csr_sel = CSR_SEL_MSCRATCH; + 4'b1_001 : o_csr_sel = CSR_SEL_MEPC; + 4'b1_010 : o_csr_sel = CSR_SEL_MCAUSE; + 4'b1_011 : o_csr_sel = CSR_SEL_MTVAL; + //4'b1_100 : o_csr_sel = CSR_SEL_MIP; default : begin o_csr_sel = 3'bxxx; /*if (o_csr_en) begin - $display("%0t: CSR %03h not implemented", $time, imm[31:20]); + $display("%0t: CSR %03h not implemented", $time, op[31:20]); //#100 $finish; end*/ end @@ -206,11 +212,12 @@ module serv_decode assign o_mem_cmd = opcode[3]; assign o_mem_init = mem_op & (state == INIT); + assign o_mem_bytecnt = cnt[4:3]; - wire jal_misalign = imm[21] & (opcode == OP_JAL); + wire jal_misalign = op[21] & (opcode == OP_JAL); reg [4:0] opcode; - reg [31:0] imm; + reg [31:0] op; reg signbit; reg [8:0] imm19_12_20; @@ -227,15 +234,15 @@ module serv_decode o_funct3 <= i_wb_rdt[14:12]; imm30 <= i_wb_rdt[30]; opcode <= i_wb_rdt[6:2]; - imm <= i_wb_rdt; + op <= i_wb_rdt; signbit <= i_wb_rdt[31]; end if (cnt_done | go | i_mem_dbus_ack) begin - imm19_12_20 <= {imm[19:12],imm[20]}; - imm7 <= imm[7]; - imm30_25 <= imm[30:25]; - imm24_20 <= imm[24:20]; - imm11_7 <= imm[11:7]; + imm19_12_20 <= {op[19:12],op[20]}; + imm7 <= op[7]; + imm30_25 <= op[30:25]; + imm24_20 <= op[24:20]; + imm11_7 <= op[11:7]; end else begin imm19_12_20 <= {m3 ? signbit : imm24_20[0], imm19_12_20[8:1]}; @@ -268,26 +275,10 @@ module serv_decode (opcode == OP_OP) ? OP_B_SOURCE_RS2 : 1'bx; - always @(o_funct3, cnt) begin - o_mem_dat_valid = 1'b0; - casez(o_funct3[1:0]) - 2'b00 : o_mem_dat_valid = (cnt < 8); - 2'b01 : o_mem_dat_valid = (cnt < 16); - 2'b10 : o_mem_dat_valid = 1'b1; - default: o_mem_dat_valid = 1'b0; - endcase - end - - - - assign o_rd_source = (opcode == OP_JAL) ? RD_SOURCE_CTRL : - (opcode == OP_OPIMM) ? RD_SOURCE_ALU : - (opcode == OP_OP) ? RD_SOURCE_ALU : - (opcode == OP_LUI) ? RD_SOURCE_CTRL : - (opcode == OP_AUIPC) ? RD_SOURCE_CTRL : - (opcode == OP_JALR) ? RD_SOURCE_CTRL : - (opcode == OP_SYSTEM) ? RD_SOURCE_CSR : - RD_SOURCE_MEM; + assign o_rd_ctrl_en = opcode[0]; + assign o_rd_alu_en = !opcode[0] & opcode[2] & !opcode[4]; + assign o_rd_csr_en = opcode[2] & opcode[4]; + assign o_rd_mem_en = !opcode[2] & !opcode[4]; always @(posedge clk) begin go <= i_wb_en; @@ -302,15 +293,15 @@ module serv_decode assign o_ctrl_trap = (state == TRAP); - always @(i_mem_misalign, o_mem_cmd, e_op, imm) begin + always @(i_mem_misalign, o_mem_cmd, e_op, op) begin o_csr_mcause[3:0] = 4'd0; if (i_mem_misalign & !o_mem_cmd) o_csr_mcause[3:0] = 4'd4; if (i_mem_misalign & o_mem_cmd) o_csr_mcause[3:0] = 4'd6; - if (e_op & !imm[20]) + if (e_op & !op[20]) o_csr_mcause[3:0] = 4'd11; - if (e_op & imm[20]) + if (e_op & op[20]) o_csr_mcause[3:0] = 4'd3; end diff --git a/rtl/serv_mem_if.v b/rtl/serv_mem_if.v index 412a8bd..41539b6 100644 --- a/rtl/serv_mem_if.v +++ b/rtl/serv_mem_if.v @@ -5,8 +5,8 @@ module serv_mem_if input wire i_rst, input wire i_en, input wire i_init, - input wire i_dat_valid, input wire i_cmd, + input wire [1:0] i_bytecnt, input wire [2:0] i_funct3, input wire i_rs1, input wire i_rs2, @@ -16,7 +16,7 @@ module serv_mem_if input wire i_trap, //External interface output wire [31:0] o_wb_adr, - output reg [31:0] o_wb_dat = 32'd0, + output wire [31:0] o_wb_dat, output wire [3:0] o_wb_sel, output wire o_wb_we , output reg o_wb_cyc = 1'b0, @@ -28,9 +28,18 @@ module serv_mem_if reg en_r; reg en_2r; wire adr; - reg [31:0] dat = 32'd0; reg signbit = 1'b0; + reg [7:0] dat0; + reg [7:0] dat1; + reg [7:0] dat2; + reg [7:0] dat3; + wire dat0_en; + wire dat1_en; + wire dat2_en; + wire dat3_en; + + ser_add ser_add_rs1_plus_imm ( .clk (i_clk), @@ -50,8 +59,14 @@ module serv_mem_if .o_par (o_wb_adr[31:1]) ); + wire dat_cur = (dat_sel == 3) ? dat3[0] : + (dat_sel == 2) ? dat2[0] : + (dat_sel == 1) ? dat1[0] : dat0[0]; + wire is_signed = ~i_funct3[2]; - assign o_rd = i_dat_valid ? dat[0] : signbit & is_signed; + assign o_rd = dat_valid ? dat_cur : signbit & is_signed; + + wire dat_valid = is_word | (i_bytecnt == 2'b00) | (is_half & !i_bytecnt[1]); wire is_word = i_funct3[1]; wire is_half = i_funct3[0]; @@ -62,35 +77,47 @@ module serv_mem_if wire upper_half = bytepos[1]; - assign o_wb_sel = (is_word ? 4'b1111 : - is_half ? {{2{upper_half}}, ~{2{upper_half}}} : - 4'd1 << bytepos); + wire [3:0] o_wb_sel = (is_word ? 4'b1111 : + is_half ? {{2{upper_half}}, ~{2{upper_half}}} : + 4'd1 << bytepos); +/* + assign o_wb_sel[3] = is_word | (is_half & bytepos[1]) | (bytepos == 2'b11); + assign o_wb_sel[2] = (bytepos == 2'b10) | is_word; + assign o_wb_sel[1] = ((is_word | is_half) & !bytepos[1]) | (bytepos == 2'b01); + assign o_wb_sel[0] = (bytepos == 2'b00); +*/ assign o_wb_we = i_cmd; reg [1:0] bytepos; - reg [4:0] cnt = 5'd0; - reg dat_en; - - always @(i_funct3, cnt, bytepos) - casez(i_funct3[1:0]) - 2'b1? : dat_en = 1'b1; - 2'b01 : dat_en = bytepos[1] ? (cnt<16) : 1'b1; - 2'b00 : dat_en = (bytepos == 2'd3) ? (cnt <8) : - (bytepos == 2'd2) ? (cnt < 16) : - (bytepos == 2'd1) ? (cnt < 24) : 1'b1; - endcase reg init_2r = 1'b0; reg [1:0] misalign = 2'b00; - always @(posedge i_clk) begin - //Async? - if (init_r) begin - o_wb_dat[7:0] <= dat[7:0]; - o_wb_dat[15:8] <= (is_word | is_half) ? dat[15:8] : dat[7:0]; - o_wb_dat[23:16] <= is_word ? dat[23:16] : dat[7:0]; - o_wb_dat[31:24] <= is_word ? dat[31:24] : is_half ? dat[15:8] : dat[7:0]; - end + wire wbyte0 = (i_bytecnt == 2'b00); + wire wbyte1 = ((i_bytecnt == 2'b01) & !bytepos[0]); + wire wbyte2 = ((i_bytecnt == 2'b10) & !bytepos[1]); + wire wbyte3 = ((i_bytecnt == 2'b11) & !bytepos[1]); + assign dat0_en = i_en & (i_init ? wbyte0 : (dat_sel == 2'd0)); + assign dat1_en = i_en & (i_init ? (wbyte0 | wbyte1) : (dat_sel == 2'd1)); + assign dat2_en = i_en & (i_init ? (wbyte0 | wbyte2) : (dat_sel == 2'd2)); + assign dat3_en = i_en & (i_init ? (wbyte0 | wbyte1 | wbyte3) : (dat_sel == 2'd3)); + + assign o_wb_dat = {dat3,dat2,dat1,dat0}; + + wire [1:0] dat_sel = i_bytecnt[1] ? i_bytecnt : (i_bytecnt | bytepos); + + always @(posedge i_clk) begin + if (dat0_en) + dat0 <= {i_rs2, dat0[7:1]}; + if (dat1_en) + dat1 <= {i_rs2, dat1[7:1]}; + if (dat2_en) + dat2 <= {i_rs2, dat2[7:1]}; + if (dat3_en) + dat3 <= {i_rs2, dat3[7:1]}; + + if (wb_en) + {dat3,dat2,dat1,dat0} <= i_wb_rdt; if (i_init & !init_r) misalign[0] <= (!is_byte & adr); @@ -104,18 +131,9 @@ module serv_mem_if if (en_r & !en_2r) bytepos[1] <= adr; - if (i_dat_valid) - signbit <= dat[0]; + if (dat_valid) + signbit <= dat_cur; - if (wb_en & !o_wb_we) begin - dat[31:16] <= i_wb_rdt[31:16]; - dat[15:8] <= (is_half & upper_half) ? i_wb_rdt[31:24] : i_wb_rdt[15:8]; - dat[7:0] <= (is_byte & (bytepos == 2'b11)) ? i_wb_rdt[31:24] : - (is_byte & (bytepos == 2'b10)) ? i_wb_rdt[23:16] : - (is_half & upper_half) ? i_wb_rdt[23:16] : - (is_byte & (bytepos == 2'b01)) ? i_wb_rdt[15:8] : - i_wb_rdt[7:0]; - end en_r <= i_en; en_2r <= en_r; @@ -126,8 +144,5 @@ module serv_mem_if else if (init_r & !i_init & !i_trap) begin //Optimize? o_wb_cyc <= 1'b1; end - - if (i_en & dat_en) - dat <= {i_rs2,dat[31:1]}; end endmodule diff --git a/rtl/serv_params.vh b/rtl/serv_params.vh index c218de7..0b8e0ac 100644 --- a/rtl/serv_params.vh +++ b/rtl/serv_params.vh @@ -1,9 +1,3 @@ -localparam [1:0] - RD_SOURCE_CTRL = 2'd0, - RD_SOURCE_ALU = 2'd1, - RD_SOURCE_MEM = 2'd2, - RD_SOURCE_CSR = 2'd3; - localparam [0:0] OFFSET_SOURCE_IMM = 1'd0, OFFSET_SOURCE_RS1 = 1'd1; diff --git a/rtl/serv_top.v b/rtl/serv_top.v index f1ba88f..fcff494 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -50,7 +50,10 @@ module serv_top wire [4:0] rs1_addr; wire [4:0] rs2_addr; - wire [1:0] rd_source; + wire rd_ctrl_en; + wire rd_alu_en; + wire rd_csr_en; + wire rd_mem_en; wire ctrl_rd; wire alu_rd; wire mem_rd; @@ -93,7 +96,7 @@ module serv_top wire mem_en; wire mem_cmd; - wire mem_dat_valid; + wire [1:0] mem_bytecnt; wire mem_init; wire mem_misalign; @@ -149,7 +152,7 @@ module serv_top .o_mem_en (mem_en), .o_mem_cmd (mem_cmd), .o_mem_init (mem_init), - .o_mem_dat_valid (mem_dat_valid), + .o_mem_bytecnt (mem_bytecnt), .i_mem_dbus_ack (i_dbus_ack), .i_mem_misalign (mem_misalign), .o_csr_en (csr_en), @@ -160,7 +163,10 @@ module serv_top .o_csr_d_sel (csr_d_sel), .o_imm (imm), .o_op_b_source (op_b_source), - .o_rd_source (rd_source)); + .o_rd_ctrl_en (rd_ctrl_en), + .o_rd_alu_en (rd_alu_en), + .o_rd_csr_en (rd_csr_en), + .o_rd_mem_en (rd_mem_en)); serv_ctrl #(.RESET_PC (RESET_PC)) @@ -186,9 +192,10 @@ module serv_top .o_ibus_cyc (o_ibus_cyc), .i_ibus_ack (i_ibus_ack)); - assign rd = (rd_source == RD_SOURCE_CTRL) ? ctrl_rd : - (rd_source == RD_SOURCE_ALU) ? alu_rd : - (rd_source == RD_SOURCE_MEM) ? mem_rd : csr_rd; + assign rd = (rd_ctrl_en & ctrl_rd) | + (rd_alu_en & alu_rd ) | + (rd_csr_en & csr_rd ) | + (rd_mem_en & mem_rd); assign op_b = (op_b_source == OP_B_SOURCE_IMM) ? imm : rs2; @@ -229,8 +236,8 @@ module serv_top .i_rst (i_rst), .i_en (mem_en), .i_init (mem_init), - .i_dat_valid (mem_dat_valid), .i_cmd (mem_cmd), + .i_bytecnt (mem_bytecnt), .i_funct3 (funct3), .i_rs1 (rs1), .i_rs2 (rs2),