mirror of
https://github.com/olofk/serv.git
synced 2026-01-30 21:16:14 +00:00
Random optimizations
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user