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:
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
Reference in New Issue
Block a user