mirror of
https://github.com/olofk/serv.git
synced 2025-04-20 11:57:07 -04:00
Add parameter to disable CSR/interrupts
Also disables timer in servant if CSR/interrupts are disabled
This commit is contained in:
parent
fca1527dd7
commit
b48b02b8df
8 changed files with 137 additions and 62 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue