Add parameter to disable CSR/interrupts

Also disables timer in servant if CSR/interrupts are disabled
This commit is contained in:
Olof Kindgren 2019-12-01 20:54:54 +01:00
parent fca1527dd7
commit b48b02b8df
8 changed files with 137 additions and 62 deletions

View file

@ -25,7 +25,8 @@ module serv_ctrl
output wire o_ibus_cyc,
input wire i_ibus_ack);
parameter RESET_PC = 32'd8;
parameter RESET_PC = 32'd0;
parameter WITH_CSR = 1;
reg en_pc_r;
@ -66,7 +67,12 @@ module serv_ctrl
.o_par (o_ibus_adr[31:1])
);
assign new_pc = i_trap ? (i_csr_pc & en_pc_r) : i_jump ? pc_plus_offset_aligned : pc_plus_4;
generate
if (WITH_CSR)
assign new_pc = i_trap ? (i_csr_pc & en_pc_r) : i_jump ? pc_plus_offset_aligned : pc_plus_4;
else
assign new_pc = i_jump ? pc_plus_offset_aligned : pc_plus_4;
endgenerate
assign o_rd = (i_utype & pc_plus_offset_aligned) | (pc_plus_4 & i_jal_or_jalr);
assign offset_a = i_pc_rel & pc;

View file

@ -42,12 +42,16 @@ module serv_rf_if
input wire [4:0] i_rs2_raddr,
output wire o_rs2);
parameter WITH_CSR = 1;
`include "serv_params.vh"
/*
********** Write side ***********
*/
generate
if (WITH_CSR) begin
wire rd = (i_ctrl_rd ) |
(i_alu_rd & i_rd_alu_en) |
(i_csr_rd & i_rd_csr_en) |
@ -57,7 +61,7 @@ module serv_rf_if
assign o_wdata0 = i_trap ? mtval : rd;
assign o_wdata1 = i_trap ? i_mepc : i_csr;
//port 0 rd mtval
//port 1 csr mepc
//mepc 100010
@ -90,6 +94,28 @@ module serv_rf_if
assign o_csr = i_rdata1 & i_csr_en;
assign o_csr_pc = i_rdata1;
end else begin
wire rd = (i_ctrl_rd ) |
(i_alu_rd & i_rd_alu_en) |
(i_mem_rd);
assign o_wdata0 = rd;
assign o_wdata1 = 1'b0;
assign o_wreg0 = {1'b0,i_rd_waddr};
assign o_wen0 =i_rd_wen;
assign o_wen1 = 1'b0;
/*
********** Read side ***********
*/
assign o_rreg0 = {1'b0, i_rs1_raddr};
assign o_rreg1 = {1'b0, i_rs2_raddr};
assign o_rs1 = i_rdata0;
assign o_rs2 = i_rdata1;
end // else: !if(WITH_CSR)
endgenerate
endmodule

View file

@ -1,6 +1,7 @@
module serv_rf_ram
#(parameter width=0,
parameter depth=32*36/width)
parameter csr_regs=4,
parameter depth=32*(32+csr_regs)/width)
(input wire i_clk,
input wire [$clog2(depth)-1:0] i_waddr,
input wire [width-1:0] i_wdata,

View file

@ -1,7 +1,8 @@
`default_nettype none
module serv_rf_ram_if
#(parameter width=8,
parameter depth=32*36/width)
parameter csr_regs=4,
parameter depth=32*(32+csr_regs)/width)
(
//SERV side
input wire i_clk,

View file

@ -41,6 +41,7 @@ module serv_rf_top
input wire i_dbus_ack);
parameter RESET_PC = 32'd0;
parameter WITH_CSR = 1;
parameter RF_WIDTH = 2;
localparam RF_L2W = $clog2(RF_WIDTH);
@ -64,7 +65,10 @@ module serv_rf_top
wire [10-RF_L2W:0] raddr;
wire [RF_WIDTH-1:0] rdata;
serv_rf_ram_if #(.width (RF_WIDTH)) rf_ram_if
serv_rf_ram_if
#(.width (RF_WIDTH),
.csr_regs (WITH_CSR*4))
rf_ram_if
(.i_clk (clk),
.i_rst (i_rst),
.i_wreq (rf_wreq),
@ -86,7 +90,10 @@ module serv_rf_top
.o_raddr (raddr),
.i_rdata (rdata));
serv_rf_ram #(.width (RF_WIDTH)) rf_ram
serv_rf_ram
#(.width (RF_WIDTH),
.csr_regs (WITH_CSR*4))
rf_ram
(.i_clk (clk),
.i_waddr (waddr),
.i_wdata (wdata),
@ -95,7 +102,8 @@ module serv_rf_top
.o_rdata (rdata));
serv_top
#(.RESET_PC (RESET_PC))
#(.RESET_PC (RESET_PC),
.WITH_CSR (WITH_CSR))
cpu
(
.clk (clk),

View file

@ -34,6 +34,8 @@ module serv_state
output reg o_cnt_done,
output wire o_bufreg_hold);
parameter WITH_CSR = 1;
localparam [1:0]
IDLE = 2'd0,
INIT = 2'd1,
@ -60,9 +62,6 @@ module serv_state
reg stage_two_pending;
reg irq_sync;
reg misalign_trap_sync;
assign o_dbus_cyc = (state == IDLE) & stage_two_pending & i_mem_op & !i_mem_misalign;
wire trap_pending = (o_ctrl_jump & i_ctrl_misalign) | i_mem_misalign;
@ -79,8 +78,6 @@ module serv_state
//Shift operations require bufreg to hold for one cycle between INIT and RUN before shifting
assign o_bufreg_hold = !o_cnt_en & (stage_two_req | ~i_shift_op);
assign o_ctrl_trap = i_e_op | o_pending_irq | misalign_trap_sync;
assign o_trap_taken = i_ibus_ack & o_ctrl_trap;
always @(posedge i_clk) begin
@ -90,24 +87,11 @@ module serv_state
if (o_cnt_en)
stage_two_pending <= o_init;
if (i_ibus_ack)
irq_sync <= 1'b0;
if (i_new_irq)
irq_sync <= 1'b1;
if (i_ibus_ack)
o_pending_irq <= irq_sync;
o_cnt_done <= (o_cnt[4:2] == 3'b111) & o_cnt_r[2];
//Need a strobe for the first cycle in the IDLE state after INIT
stage_two_req <= o_cnt_done & (state == INIT);
if (stage_two_req)
misalign_trap_sync <= trap_pending;
if (i_ibus_ack)
misalign_trap_sync <= 1'b0;
if (i_rf_ready && !o_cnt_en)
if (i_e_op | o_pending_irq | (stage_two_pending & trap_pending))
state <= TRAP;
@ -132,4 +116,28 @@ module serv_state
end
end
generate
if (WITH_CSR) begin
reg irq_sync;
reg misalign_trap_sync;
assign o_ctrl_trap = i_e_op | o_pending_irq | misalign_trap_sync;
assign o_trap_taken = i_ibus_ack & o_ctrl_trap;
always @(posedge i_clk) begin
if (i_ibus_ack)
irq_sync <= 1'b0;
if (i_new_irq)
irq_sync <= 1'b1;
if (i_ibus_ack)
o_pending_irq <= irq_sync;
if (stage_two_req)
misalign_trap_sync <= trap_pending;
if (i_ibus_ack)
misalign_trap_sync <= 1'b0;
end // always @ (posedge i_clk)
end // if (WITH_CSR)
endgenerate
endmodule

View file

@ -55,6 +55,8 @@ module serv_top
input wire [31:0] i_dbus_rdt,
input wire i_dbus_ack);
parameter WITH_CSR = 1;
wire [4:0] rd_addr;
wire [4:0] rs1_addr;
wire [4:0] rs2_addr;
@ -143,7 +145,9 @@ module serv_top
wire [1:0] lsb;
wire [31:0] bufreg_out;
serv_state state
serv_state
#(.WITH_CSR (WITH_CSR))
state
(
.i_clk (clk),
.i_rst (i_rst),
@ -262,7 +266,8 @@ module serv_top
.o_q (bufreg_q));
serv_ctrl
#(.RESET_PC (RESET_PC))
#(.RESET_PC (RESET_PC),
.WITH_CSR (WITH_CSR))
ctrl
(
.clk (clk),
@ -317,7 +322,9 @@ module serv_top
wire csr_in;
wire rf_csr_out;
serv_rf_if rf_if
serv_rf_if
#(.WITH_CSR (WITH_CSR))
rf_if
(//RF interface
.o_wreg0 (o_wreg0),
.o_wreg1 (o_wreg1),
@ -382,29 +389,38 @@ module serv_top
.i_wb_rdt (i_dbus_rdt),
.i_wb_ack (i_dbus_ack));
serv_csr csr
(
.i_clk (clk),
.i_en (cnt_en),
.i_cnt (cnt[4:2]),
.i_cnt_r (cnt_r[3:2]),
.i_e_op (e_op),
.i_ebreak (ebreak),
.i_mem_cmd (o_dbus_we),
.i_mem_misalign (mem_misalign),
.i_rf_csr_out (rf_csr_out),
.o_csr_in (csr_in),
.i_mtip (i_timer_irq),
.o_new_irq (new_irq),
.i_trap_taken (trap_taken),
.i_pending_irq (pending_irq),
.i_mstatus_en (csr_mstatus_en),
.i_mie_en (csr_mie_en ),
.i_mcause_en (csr_mcause_en ),
.i_csr_source (csr_source),
.i_mret (mret),
.i_d (csr_d_sel ? csr_imm : rs1),
.o_q (csr_rd));
generate
if (WITH_CSR) begin
serv_csr csr
(
.i_clk (clk),
.i_en (cnt_en),
.i_cnt (cnt[4:2]),
.i_cnt_r (cnt_r[3:2]),
.i_e_op (e_op),
.i_ebreak (ebreak),
.i_mem_cmd (o_dbus_we),
.i_mem_misalign (mem_misalign),
.i_rf_csr_out (rf_csr_out),
.o_csr_in (csr_in),
.i_mtip (i_timer_irq),
.o_new_irq (new_irq),
.i_trap_taken (trap_taken),
.i_pending_irq (pending_irq),
.i_mstatus_en (csr_mstatus_en),
.i_mie_en (csr_mie_en ),
.i_mcause_en (csr_mcause_en ),
.i_csr_source (csr_source),
.i_mret (mret),
.i_d (csr_d_sel ? csr_imm : rs1),
.o_q (csr_rd));
end else begin
assign csr_in = 1'b0;
assign csr_rd = 1'b0;
assign new_irq = 1'b0;
end
endgenerate
`ifdef RISCV_FORMAL
reg [31:0] pc = RESET_PC;

View file

@ -7,6 +7,7 @@ module servant
parameter memfile = "zephyr_hello.hex";
parameter memsize = 8192;
parameter with_csr = 1;
wire timer_irq;
@ -135,15 +136,22 @@ servant_arbiter servant_arbiter
.o_wb_rdt (wb_mem_rdt),
.o_wb_ack (wb_mem_ack));
servant_timer
#(.WIDTH (32))
timer
(.i_clk (wb_clk),
.o_irq (timer_irq),
.i_wb_cyc (wb_timer_cyc),
.i_wb_we (wb_timer_we) ,
.i_wb_dat (wb_timer_dat),
.o_wb_dat (wb_timer_rdt));
generate
if (with_csr) begin
servant_timer
#(.WIDTH (32))
timer
(.i_clk (wb_clk),
.o_irq (timer_irq),
.i_wb_cyc (wb_timer_cyc),
.i_wb_we (wb_timer_we) ,
.i_wb_dat (wb_timer_dat),
.o_wb_dat (wb_timer_rdt));
end else begin
assign wb_timer_rdt = 32'd0;
assign timer_irq = 1'b0;
end
endgenerate
servant_gpio gpio
(.i_wb_clk (wb_clk),
@ -154,7 +162,8 @@ servant_arbiter servant_arbiter
.o_gpio (q));
serv_rf_top
#(.RESET_PC (32'h0000_0000))
#(.RESET_PC (32'h0000_0000),
.WITH_CSR (with_csr))
cpu
(
.clk (wb_clk),