1
0
mirror of https://github.com/olofk/serv.git synced 2026-04-25 20:02:16 +00:00

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, output wire o_ibus_cyc,
input wire i_ibus_ack); input wire i_ibus_ack);
parameter RESET_PC = 32'd8; parameter RESET_PC = 32'd0;
parameter WITH_CSR = 1;
reg en_pc_r; reg en_pc_r;
@@ -66,7 +67,12 @@ module serv_ctrl
.o_par (o_ibus_adr[31:1]) .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 o_rd = (i_utype & pc_plus_offset_aligned) | (pc_plus_4 & i_jal_or_jalr);
assign offset_a = i_pc_rel & pc; assign offset_a = i_pc_rel & pc;

View File

@@ -42,12 +42,16 @@ module serv_rf_if
input wire [4:0] i_rs2_raddr, input wire [4:0] i_rs2_raddr,
output wire o_rs2); output wire o_rs2);
parameter WITH_CSR = 1;
`include "serv_params.vh" `include "serv_params.vh"
/* /*
********** Write side *********** ********** Write side ***********
*/ */
generate
if (WITH_CSR) begin
wire rd = (i_ctrl_rd ) | wire rd = (i_ctrl_rd ) |
(i_alu_rd & i_rd_alu_en) | (i_alu_rd & i_rd_alu_en) |
(i_csr_rd & i_rd_csr_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_wdata0 = i_trap ? mtval : rd;
assign o_wdata1 = i_trap ? i_mepc : i_csr; assign o_wdata1 = i_trap ? i_mepc : i_csr;
//port 0 rd mtval //port 0 rd mtval
//port 1 csr mepc //port 1 csr mepc
//mepc 100010 //mepc 100010
@@ -90,6 +94,28 @@ module serv_rf_if
assign o_csr = i_rdata1 & i_csr_en; assign o_csr = i_rdata1 & i_csr_en;
assign o_csr_pc = i_rdata1; 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 endmodule

View File

@@ -1,6 +1,7 @@
module serv_rf_ram module serv_rf_ram
#(parameter width=0, #(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 i_clk,
input wire [$clog2(depth)-1:0] i_waddr, input wire [$clog2(depth)-1:0] i_waddr,
input wire [width-1:0] i_wdata, input wire [width-1:0] i_wdata,

View File

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

View File

@@ -41,6 +41,7 @@ module serv_rf_top
input wire i_dbus_ack); input wire i_dbus_ack);
parameter RESET_PC = 32'd0; parameter RESET_PC = 32'd0;
parameter WITH_CSR = 1;
parameter RF_WIDTH = 2; parameter RF_WIDTH = 2;
localparam RF_L2W = $clog2(RF_WIDTH); localparam RF_L2W = $clog2(RF_WIDTH);
@@ -64,7 +65,10 @@ module serv_rf_top
wire [10-RF_L2W:0] raddr; wire [10-RF_L2W:0] raddr;
wire [RF_WIDTH-1:0] rdata; 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_clk (clk),
.i_rst (i_rst), .i_rst (i_rst),
.i_wreq (rf_wreq), .i_wreq (rf_wreq),
@@ -86,7 +90,10 @@ module serv_rf_top
.o_raddr (raddr), .o_raddr (raddr),
.i_rdata (rdata)); .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_clk (clk),
.i_waddr (waddr), .i_waddr (waddr),
.i_wdata (wdata), .i_wdata (wdata),
@@ -95,7 +102,8 @@ module serv_rf_top
.o_rdata (rdata)); .o_rdata (rdata));
serv_top serv_top
#(.RESET_PC (RESET_PC)) #(.RESET_PC (RESET_PC),
.WITH_CSR (WITH_CSR))
cpu cpu
( (
.clk (clk), .clk (clk),

View File

@@ -34,6 +34,8 @@ module serv_state
output reg o_cnt_done, output reg o_cnt_done,
output wire o_bufreg_hold); output wire o_bufreg_hold);
parameter WITH_CSR = 1;
localparam [1:0] localparam [1:0]
IDLE = 2'd0, IDLE = 2'd0,
INIT = 2'd1, INIT = 2'd1,
@@ -60,9 +62,6 @@ module serv_state
reg stage_two_pending; 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; 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; 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 //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_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 always @(posedge i_clk) begin
@@ -90,24 +87,11 @@ module serv_state
if (o_cnt_en) if (o_cnt_en)
stage_two_pending <= o_init; 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]; 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 //Need a strobe for the first cycle in the IDLE state after INIT
stage_two_req <= o_cnt_done & (state == 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_rf_ready && !o_cnt_en)
if (i_e_op | o_pending_irq | (stage_two_pending & trap_pending)) if (i_e_op | o_pending_irq | (stage_two_pending & trap_pending))
state <= TRAP; state <= TRAP;
@@ -132,4 +116,28 @@ module serv_state
end end
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 endmodule

View File

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

View File

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