1
0
mirror of https://github.com/olofk/serv.git synced 2026-01-18 00:42:23 +00:00

Store CSR in RF RAM

Since FPGA uses fixed-size RAM, it's better in most cases to store
the CSR in unused memory positions in that RAM.

Since the decoding is made more complex, the old register file
implementation is kept around since that is more efficient when we
don't want CSR and potentially when the FPGA support hardware
shift registers.
This commit is contained in:
Olof Kindgren 2019-03-18 12:16:31 +01:00
parent b0a062ae21
commit 42ac1e5e4d
4 changed files with 218 additions and 15 deletions

View File

@ -4,13 +4,16 @@ module serv_csr
input wire i_clk,
input wire [4:0] i_cnt,
input wire [3:0] i_cnt_r,
//From mpram
input wire i_rf_csr_out,
//to mpram
output wire o_csr_in,
//Stuff
input wire i_mtip,
output wire o_timer_irq_en,
input wire i_mstatus_en,
input wire i_mie_en,
input wire i_mtvec_en,
input wire i_mip_en,
input wire i_mscratch_en,
input wire i_mepc_en,
input wire i_mcause_en,
input wire i_mtval_en,
@ -38,16 +41,13 @@ module serv_csr
reg mstatus;
reg mstatus_mie;
reg mie_mtie;
reg [31:0] mtvec = 32'h0;
reg [31:0] mscratch;
reg [31:0] mepc;
reg mcause31;
reg [3:0] mcause3_0;
wire mcause;
reg [31:0] mtval;
wire csr_in;
wire csr_out;
@ -58,8 +58,7 @@ module serv_csr
1'bx;
assign csr_out = (i_mstatus_en & mstatus) |
(i_mtvec_en & mtvec[0]) |
(i_mscratch_en & mscratch[0]) |
i_rf_csr_out |
(i_mepc_en & mepc[0]) |
(i_mcause_en & mcause) |
(i_mtval_en & mtval[0]);
@ -72,6 +71,8 @@ module serv_csr
((i_cnt[4:2] == 3'd7) & i_cnt_r[3]) ? mcause31 //[31]
: 1'b0;
assign o_csr_in = csr_in;
always @(posedge i_clk) begin
if (i_mstatus_en & (i_cnt[4:2] == 3'd0) & i_cnt_r[3])
mstatus_mie <= csr_in;
@ -85,11 +86,6 @@ module serv_csr
mcause31 <= i_mtip & o_timer_irq_en;
mcause3_0 <= (i_mtip & o_timer_irq_en) ? 4'd7 : i_mcause[3:0];
end
if (i_mscratch_en)
mscratch <= {csr_in, mscratch[31:1]};
if (i_mtvec_en)
mtvec <= {csr_in, mtvec[31:1]};
if (i_mepc_en | i_trap)
mepc <= {i_trap ? i_pc : csr_in, mepc[31:1]};

173
rtl/serv_mpram.v Normal file
View File

@ -0,0 +1,173 @@
`default_nettype none
module serv_mpram
(
input wire i_clk,
input wire i_rst,
//MEPC write port
input wire i_mepc_wen,
input wire i_mepc,
//MTVAL write port
input wire i_mtval_wen,
input wire i_mtval,
//CSR interface
input wire i_csr_mscratch_en,
input wire i_csr_mtvec_en,
input wire i_csr,
output wire o_csr,
//RD write port
input wire i_rd_wen,
input wire [4:0] i_rd_waddr,
input wire i_rd,
input wire i_rreq,
output reg o_rgnt,
//RS1 read port
input wire [4:0] i_rs1_raddr,
output wire o_rs1,
//RS2 read port
input wire [4:0] i_rs2_raddr,
output wire o_rs2);
reg [1:0] csr_addr;
wire csr_en = i_csr_mscratch_en|i_csr_mtvec_en;
wire [8:0] waddr;
reg [4:0] wdata0;
reg [5:0] wdata1;
reg [6:0] wdata2;
reg [7:0] wdata3;
wire [3:0] wdata;
wire wen;
reg [3:0] wen_r;
reg [3:0] wcnt_lo;
reg [2:0] wcnt_hi;
assign wdata = wcnt_lo[0] ? wdata0[3:0] :
wcnt_lo[1] ? wdata1[3:0] :
wcnt_lo[2] ? wdata2[3:0] :
/*wcnt_lo[3] ?*/ wdata3[3:0];
assign wen = !wgo_r & |(wen_r & wcnt_lo);
reg [4:0] rd_waddr;
//mepc 100000
//mtval 100011
//csr 1000xx
//rd 0xxxxx
assign waddr[8] = !wcnt_lo[3];
assign waddr[7:5] = wcnt_lo[3] ? rd_waddr[4:2] : 3'b000;
assign waddr[4:3] = wcnt_lo[3] ? rd_waddr[1:0] :
wcnt_lo[2] ? csr_addr :
wcnt_lo[1] ? 2'b11 : 2'b00;
assign waddr[2:0] = wcnt_hi;
wire wgo = !(|wcnt_lo) & |({i_rd_wen,csr_en,i_mtval_wen,i_mepc_wen});
reg wgo_r;
always @(posedge i_clk) begin
if (wgo) begin
wgo_r <= 1'b1;
wen_r <= {i_rd_wen,csr_en,i_mtval_wen,i_mepc_wen};
rd_waddr <= i_rd_waddr;
end
wdata0 <= {i_mepc,wdata0[4:1]};
wdata1 <= {i_mtval,wdata1[5:1]};
wdata2 <= {i_csr,wdata2[6:1]};
wdata3 <= {i_rd,wdata3[7:1]};
wcnt_lo <= {wcnt_lo[2:0],wcnt_lo[3] | wgo};
if (wcnt_lo[3]) begin
wcnt_hi <= wcnt_hi + 1;
if (wcnt_hi == 3'd7) begin
wgo_r <= !wgo_r;
wcnt_lo[0] <= wgo_r;
wcnt_hi <= wcnt_hi + {2'b00,wgo_r};
end
end
if (i_rst) begin
wgo_r <= 1'b0;
wcnt_lo <= 4'd0;
wcnt_hi <= 3'd7;
end
end
//0 : RS1
//1 : RS2
//2 : CSR
reg [2:0] rcnt_hi;
reg [3:0] rcnt_lo;
wire [8:0] raddr;
reg [3:0] rdata;
reg [5:0] rdata0;
reg [4:0] rdata1;
reg [3:0] rdata2;
//reg [3:0] rdata3;
reg [2:0] rreq;
always @(posedge i_clk) begin
{o_rgnt,rreq} <= {rreq[2:0],i_rreq};
if (rcnt_lo[3])
rcnt_hi <= rcnt_hi + 1;
if (i_rreq) begin
rcnt_lo <= 4'd1;
rcnt_hi <= 3'd0;
csr_addr <= {1'b0,i_csr_mtvec_en};
end else
rcnt_lo <= {rcnt_lo[2:0],rcnt_lo[3]};
rdata0[4:0] <= rdata0[5:1];
rdata1[3:0] <= rdata1[4:1];
rdata2[2:0] <= rdata2[3:1];
//rdata3[2:0] <= rdata3[3:1];
if (rcnt_lo[1]) rdata0[5:2] <= rdata;
if (rcnt_lo[2]) rdata1[4:1] <= rdata;
if (rcnt_lo[3]) rdata2[3:0] <= rdata;
//if (rcnt_lo[0]) rdata3[3:0] <= rdata;
if (i_rst) begin
o_rgnt <= 1'b0;
rreq <= 3'd0;
end
end
assign raddr[8] = rcnt_lo[2];
assign raddr[7:5] = rcnt_lo[0] ? i_rs1_raddr[4:2] :
rcnt_lo[1] ? i_rs2_raddr[4:2] : 3'd0;
assign raddr[4:3] = rcnt_lo[0] ? i_rs1_raddr[1:0] :
rcnt_lo[1] ? i_rs2_raddr[1:0] : csr_addr;
assign raddr[2:0] = rcnt_hi;
assign o_rs1 = rdata0[0];
assign o_rs2 = rdata1[0];
assign o_csr = rdata2[0] & csr_en;
reg [3:0] memory [0:511];
always @(posedge i_clk) begin
if (wen)
`ifdef RISCV_FORMAL
if (!i_rst)
`endif
memory[waddr] <= wdata;
rdata <= memory[raddr];
end
`ifdef RISCV_FORMAL
integer i;
initial
for (i=0;i<256;i=i+1)
memory[i] = 4'd0;
`endif
endmodule

View File

@ -277,7 +277,7 @@ module serv_top
.o_sh_done (alu_sh_done),
.i_rd_sel (alu_rd_sel),
.o_rd (alu_rd));
/*
serv_regfile regfile
(
.i_clk (clk),
@ -291,6 +291,39 @@ module serv_top
.i_rs2_addr (rs2_addr),
.o_rs1 (rs1),
.o_rs2 (rs2));
*/
wire csr_in;
wire rf_csr_out;
serv_mpram regfile
(
.i_clk (clk),
.i_rst (i_rst),
//MEPC write port
.i_mepc_wen (1'b0),
.i_mepc (1'b0),
//MTVAL write port
.i_mtval_wen (1'b0),
.i_mtval (1'b0),
//CSR write port
.i_csr_mscratch_en (csr_mscratch_en),
.i_csr_mtvec_en (csr_mtvec_en),
.i_csr (csr_in),
//RD write port
.i_rd_wen (rd_en & (|rd_addr)),
.i_rd_waddr (rd_addr),
.i_rd (rd),
.i_rreq (i_ibus_ack),
.o_rgnt (rf_ready),
//RS1 read port
.i_rs1_raddr (rs1_addr),
.o_rs1 (rs1),
//RS2 read port
.i_rs2_raddr (rs2_addr),
.o_rs2 (rs2),
//CSR read port
.o_csr (rf_csr_out));
serv_mem_if mem_if
(
@ -319,13 +352,13 @@ module serv_top
.i_clk (clk),
.i_cnt (cnt),
.i_cnt_r (cnt_r),
.i_rf_csr_out (rf_csr_out),
.o_csr_in (csr_in),
.i_mtip (i_timer_irq),
.o_timer_irq_en ( timer_irq_en),
.i_mstatus_en (csr_mstatus_en),
.i_mie_en (csr_mie_en ),
.i_mtvec_en (csr_mtvec_en ),
.i_mip_en (csr_mip_en ),
.i_mscratch_en (csr_mscratch_en),
.i_mepc_en (csr_mepc_en ),
.i_mcause_en (csr_mcause_en ),
.i_mtval_en (csr_mtval_en ),

View File

@ -17,6 +17,7 @@ filesets:
- rtl/serv_decode.v
- rtl/serv_mem_if.v
- rtl/serv_regfile.v
- rtl/serv_mpram.v
- rtl/serv_top.v
file_type : verilogSource