1
0
mirror of https://github.com/olofk/serv.git synced 2026-01-30 13:06:17 +00:00
Files
olofk.serv/rtl/serv_csr.v
Olof Kindgren 42ac1e5e4d 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.
2019-06-07 19:39:18 +02:00

105 lines
2.4 KiB
Verilog

`default_nettype none
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_mip_en,
input wire i_mepc_en,
input wire i_mcause_en,
input wire i_mtval_en,
input wire [1:0] i_csr_source,
input wire i_trap,
input wire i_pc,
input wire i_mtval,
input wire [3:0] i_mcause,
input wire i_d,
output wire o_q);
`include "serv_params.vh"
/*
300 mstatus RWSC
304 mie SCWi
305 mtvec RW
344 mip CWi
340 mscratch
341 mepc RW
342 mcause R
343 mtval
*/
reg mstatus;
reg mstatus_mie;
reg mie_mtie;
reg [31:0] mepc;
reg mcause31;
reg [3:0] mcause3_0;
wire mcause;
reg [31:0] mtval;
wire csr_in;
wire csr_out;
assign csr_in = (i_csr_source == CSR_SOURCE_EXT) ? i_d :
(i_csr_source == CSR_SOURCE_SET) ? csr_out | i_d :
(i_csr_source == CSR_SOURCE_CLR) ? csr_out & ~i_d :
(i_csr_source == CSR_SOURCE_CSR) ? csr_out :
1'bx;
assign csr_out = (i_mstatus_en & mstatus) |
i_rf_csr_out |
(i_mepc_en & mepc[0]) |
(i_mcause_en & mcause) |
(i_mtval_en & mtval[0]);
assign o_q = csr_out;
assign o_timer_irq_en = mstatus_mie & mie_mtie;
assign mcause = (i_cnt[4:2] == 3'd0) ? mcause3_0[0] : //[3:0]
((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;
if (i_mie_en & (i_cnt[4:2] == 3'd1) & i_cnt_r[3])
mie_mtie <= csr_in;
mstatus <= (i_cnt[4:2] == 0) & i_cnt_r[2] & mstatus_mie;
if (i_trap) begin
mcause31 <= i_mtip & o_timer_irq_en;
mcause3_0 <= (i_mtip & o_timer_irq_en) ? 4'd7 : i_mcause[3:0];
end
if (i_mepc_en | i_trap)
mepc <= {i_trap ? i_pc : csr_in, mepc[31:1]};
if (i_mcause_en) begin
if (i_cnt[4:2] == 3'd0)
mcause3_0 <= {csr_in, mcause3_0[3:1]};
if ((i_cnt[4:2] == 3'd7) & i_cnt_r[3])
mcause31 <= csr_in;
end
if (i_mtval_en | i_trap)
mtval <= {i_trap ? i_mtval : csr_in, mtval[31:1]};
end
endmodule