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:
parent
b0a062ae21
commit
42ac1e5e4d
@ -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
173
rtl/serv_mpram.v
Normal 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
|
||||
@ -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 ),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user