Skip to content

Commit

Permalink
Change: testbench runs now randomly external IRQ. Add also software IRQ
Browse files Browse the repository at this point in the history
  • Loading branch information
dpretet committed Oct 29, 2023
1 parent 966305b commit ce407a0
Show file tree
Hide file tree
Showing 10 changed files with 463 additions and 368 deletions.
1 change: 1 addition & 0 deletions doc/project_mgt_sw.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ Minimalistic Unix
- [ ] Support Linux / FreeBSD / NetBSD
- https://github.com/cnlohr/mini-rv32ima
- https://popovicu.com/posts/789-kb-linux-without-mmu-riscv/
- https://popovicu.com/posts/making-a-micro-linux-distro/
- [ ] Code Pong with AI for auto game
- [ ] Run Doom: https://www.youtube.com/watch?v=uZMNK17VCMU&list=WL&index=1&t=2s
- [ ] Code the game of life
Expand Down
41 changes: 36 additions & 5 deletions rtl/friscv_csr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ module friscv_csr
logic timer_irq_sync;
logic sw_irq_sync;

logic ext_irq_pulse;
logic timer_irq_pulse;
logic sw_irq_pulse;

// External source of CSRs
logic ctrl_mepc_wr;
logic [XLEN -1:0] ctrl_mepc;
Expand Down Expand Up @@ -407,7 +411,8 @@ module friscv_csr
assign ready = 1'b1;

//////////////////////////////////////////////////////////////////////////
// Synchronize the IRQs in the core's clock domain
// Synchronize the IRQs in the core's clock domain and transoform them
// into a single pulse
//////////////////////////////////////////////////////////////////////////

friscv_bit_sync
Expand Down Expand Up @@ -449,6 +454,32 @@ module friscv_csr
.bit_o (sw_irq_sync)
);

friscv_pulser eirq_pulse
(
.aclk (aclk),
.aresetn (aresetn),
.srst (srst),
.intp (ext_irq_sync),
.pulse (ext_irq_pulse)
);

friscv_pulser tirq_pulse
(
.aclk (aclk),
.aresetn (aresetn),
.srst (srst),
.intp (timer_irq_sync),
.pulse (timer_irq_pulse)
);

friscv_pulser sirq_pulse
(
.aclk (aclk),
.aresetn (aresetn),
.srst (srst),
.intp (sw_irq_sync),
.pulse (sw_irq_pulse)
);

//////////////////////////////////////////////////////////////////////////
// ISA register Write Stage
Expand Down Expand Up @@ -811,21 +842,21 @@ module friscv_csr
end else if (srst) begin
mip <= {XLEN{1'b0}};
end else begin
if (ext_irq_sync || timer_irq_sync || sw_irq_sync || ctrl_clr_meip) begin
if (ext_irq_pulse || timer_irq_pulse || sw_irq_pulse || ctrl_clr_meip) begin
// external interrupt enable && external interrupt pin asserted
if ( ext_irq_sync) begin
if (ext_irq_pulse) begin
mip[11] <= 1'b1;
end else if (ctrl_clr_meip) begin
mip[11] <= 1'b0;
end
// software interrupt enable && software interrupt pin asserted
if (mie[3] && sw_irq_sync) begin
if (sw_irq_pulse) begin
mip[3] <= 1'b1;
end else begin
mip[3] <= 1'b0;
end
// timer interrupt enable && timer interrupt pin asserted
if (mie[7] && timer_irq_sync) begin
if (timer_irq_pulse) begin
mip[7] <= 1'b1;
end else begin
mip[7] <= 1'b0;
Expand Down
40 changes: 40 additions & 0 deletions rtl/friscv_pulser.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// distributed under the mit license
// https://opensource.org/licenses/mit-license.php

`timescale 1 ns / 1 ps
`default_nettype none

/*
* Used to transform a signal like an interrupt which spans over several
* clock cycles into a single pulse.
*/
module friscv_pulser

(
input wire aclk,
input wire aresetn,
input wire srst,
input wire intp,
output logic pulse
);

logic intp_reg;

always @ (posedge aclk or negedge aresetn) begin
if (!aresetn) begin
intp_reg <= 1'b0;
pulse <= 1'b0;
end else if (srst) begin
intp_reg <= 1'b0;
pulse <= 1'b0;
end else begin
intp_reg <= intp;
pulse <= intp & !intp_reg;
end
end


endmodule

`resetall

1 change: 1 addition & 0 deletions syn/friscv_rv32i.ys
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ read -sv2012 ../rtl/friscv_rv32i_core.sv
read -sv2012 ../rtl/friscv_axi_or_tracker.sv
read -sv2012 ../rtl/friscv_mpu.sv
read -sv2012 ../rtl/friscv_pmp_region.sv
read -sv2012 ../rtl/friscv_pulser.sv

# synthsize the core
synth -top friscv_rv32i_core
Expand Down
1 change: 1 addition & 0 deletions test/common/files.f
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
../../rtl/friscv_memfy.sv
../../rtl/friscv_registers.sv
../../rtl/friscv_csr.sv
../../rtl/friscv_pulser.sv
../../rtl/friscv_scfifo.sv
../../rtl/friscv_ram.sv
../../rtl/friscv_rambe.sv
Expand Down
77 changes: 49 additions & 28 deletions test/common/friscv_testbench.sv
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ module friscv_testbench(
parameter PMPADDR13_INIT = `PMPADDR13_INIT;
parameter PMPADDR14_INIT = `PMPADDR14_INIT;
parameter PMPADDR15_INIT = `PMPADDR15_INIT;
`else
`else
// PMP / PMA supported
// = 0, no PMP
// = 1, PMP available but fixed at boot time
Expand Down Expand Up @@ -215,7 +215,7 @@ module friscv_testbench(
// Minimum program counter value a test needs to reach
parameter MIN_PC = `MIN_PC;
`ifdef WFI_TW
// Timeout applied for WFI
// Timeout applied for WFI
parameter WFI_TW = `WFI_TW;
`else
parameter WFI_TW = 0;
Expand Down Expand Up @@ -329,30 +329,53 @@ module friscv_testbench(
assign imem_bready = 1'b1;

initial ext_irq = 1'b0;
initial sw_irq = 1'b0;

`ifdef GEN_EIRQ
generate
if (`GEN_EIRQ>0) begin
always @ (posedge aclk or negedge aresetn) begin
integer cnt;
if (!aresetn) begin
ext_irq <= 1'b0;
cnt <= 0;
end else if (srst) begin
ext_irq <= 1'b0;
cnt <= 0;

generate if (`GEN_EIRQ>0) begin

integer cnt;
logic [31:0] xirq_lfsr;
logic [7 :0] irq_reset;
logic [3 :0] next_eirq;
logic [3 :0] next_sirq;

lfsr32
#(
.KEY ('1)
)
irq_lsfr
(
.aclk (aclk),
.aresetn (aresetn),
.srst (srst),
.en (1'b1),
.lfsr (xirq_lfsr)
);

always @ (posedge aclk or negedge aresetn) begin
if (!aresetn) begin
cnt <= 0;
end else if (srst) begin
cnt <= 0;
end else begin
if (cnt == irq_reset) begin
irq_reset <= xirq_lfsr[7:0];
next_eirq <= xirq_lfsr[8+:4];
next_sirq <= xirq_lfsr[16+:4];
cnt <= 'h0;
end else begin
if (cnt == 100) begin
cnt <= 0;
ext_irq <= 1'b1;
end else begin
cnt <= cnt + 1;
ext_irq <= 1'b0;
end
cnt <= cnt + 1;
end
end
end
endgenerate

assign ext_irq = (cnt >= (irq_reset-next_eirq));
assign sw_irq = (cnt >= (irq_reset-next_sirq));

end
endgenerate
`endif

// Run the testbench by using only the CPU core
Expand All @@ -361,7 +384,6 @@ module friscv_testbench(
if (TB_CHOICE=="CORE") begin

assign timer_irq = 1'b0;
assign sw_irq = 1'b0;

friscv_rv32i_core
#(
Expand All @@ -378,7 +400,7 @@ module friscv_testbench(
.SUPERVISOR_MODE (SUPERVISOR_MODE),
.USER_MODE (USER_MODE),
.PROCESSING_BUS_PIPELINE (PROCESSING_BUS_PIPELINE),
.WFI_TW (WFI_TW),
.WFI_TW (WFI_TW),
.AXI_ADDR_W (AXI_ADDR_W),
.AXI_ID_W (AXI_ID_W),
.AXI_IMEM_W (AXI_IMEM_W),
Expand Down Expand Up @@ -463,9 +485,9 @@ module friscv_testbench(
axi4l_ram
#(
`ifdef RAM_MODE_PERF
.MODE ("performance"),
.MODE ("performance"),
`else
.MODE ("compliance"),
.MODE ("compliance"),
`endif
.INIT ("test.v"),
.AXI_ADDR_W (AXI_ADDR_W),
Expand Down Expand Up @@ -530,7 +552,6 @@ module friscv_testbench(
end else if (TB_CHOICE=="PLATFORM") begin

assign timer_irq = 1'b0;
assign sw_irq = 1'b0;
assign rtc = aclk;

// Can't use interactive mode with Verilator
Expand Down Expand Up @@ -589,7 +610,7 @@ module friscv_testbench(
.SUPERVISOR_MODE (SUPERVISOR_MODE),
.USER_MODE (USER_MODE),
.PROCESSING_BUS_PIPELINE (PROCESSING_BUS_PIPELINE),
.WFI_TW (WFI_TW),
.WFI_TW (WFI_TW),
.AXI_ADDR_W (AXI_ADDR_W),
.AXI_ID_W (AXI_ID_W),
.AXI_DATA_W (AXI_DATA_W),
Expand Down Expand Up @@ -667,9 +688,9 @@ module friscv_testbench(
axi4l_ram
#(
`ifdef RAM_MODE_PERF
.MODE ("performance"),
.MODE ("performance"),
`else
.MODE ("compliance"),
.MODE ("compliance"),
`endif
.INIT ("test.v"),
.AXI_ADDR_W (AXI_ADDR_W),
Expand Down
Loading

0 comments on commit ce407a0

Please sign in to comment.