1
0
mirror of https://github.com/olofk/serv.git synced 2026-01-30 21:16:14 +00:00

Random optimizations

This commit is contained in:
Olof Kindgren
2018-11-23 13:59:07 +01:00
parent 1bbf8e3ce9
commit b8f5133267
5 changed files with 121 additions and 112 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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),