diff --git a/rtl/serv_csr.v b/rtl/serv_csr.v index 7107292..ffabb05 100644 --- a/rtl/serv_csr.v +++ b/rtl/serv_csr.v @@ -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]}; diff --git a/rtl/serv_mpram.v b/rtl/serv_mpram.v new file mode 100644 index 0000000..c2b4b9c --- /dev/null +++ b/rtl/serv_mpram.v @@ -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 diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 8a2ec70..580b966 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -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 ), diff --git a/serv.core b/serv.core index fd7e74b..5de8795 100644 --- a/serv.core +++ b/serv.core @@ -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