Skip to content

Plic inc support #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions dv/verilator/demo_system_verilator_lint.vlt
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,22 @@ lint_off -rule IMPERFECTSCH -file "*prim_flop_2sync.sv"

lint_off -rule WIDTH -file "*uartdpi.sv"
lint_off -rule UNUSED -file "*uartdpi.sv"

lint_off -rule WIDTH -file "*plicdpi.sv"
lint_off -rule UNUSED -file "*plicdpi.sv"
lint_off -rule WIDTHEXPAND -file "*plicdpi.sv"
lint_off -rule WIDTHTRUNC -file "*plicdpi.sv"
lint_off -rule MULTIDRIVEN -file "*plicdpi.sv"
lint_off -rule CASEOVERLAP -file "*plicdpi.sv"

lint_off -rule WIDTH -file "*plic.sv"
lint_off -rule UNUSED -file "*plic.sv"
lint_off -rule WIDTHEXPAND -file "*plic.sv"
lint_off -rule WIDTHTRUNC -file "*plic.sv"
lint_off -rule CASEOVERLAP -file "*plic.sv"


lint_off -rule WIDTH -file "*ibex_demo_system.sv"
lint_off -rule UNUSED -file "*ibex_demo_system.sv"
lint_off -rule WIDTHEXPAND -file "*ibex_demo_system.sv"
lint_off -rule WIDTHTRUNC -file "*ibex_demo_system.sv"
157 changes: 157 additions & 0 deletions dv/verilator/plicdpi.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Corrected Virtual PLIC interface for Verilator simulation
module plicdpi #(
parameter int SOURCES = 32,
parameter int TARGETS = 1,
parameter int PRIORITIES = 3
)(
input logic clk_i,
input logic rst_ni,

// Bus interface signals (matching the RTL plic register map)
input logic req_i,
input logic [31:0] addr_i,
input logic we_i,
input logic [3:0] be_i,
input logic [31:0] wdata_i,
output logic rvalid_o,
output logic [31:0] rdata_o,

// Interrupt interface
input logic [SOURCES-1:0] irq_sources_i,
output logic [SOURCES-1:0] irq_pending_o,
output logic [TARGETS-1:0] irq_o
);

// Register map constants (same as in plic.sv)
localparam int PRIORITY_BASE = 'h000000;
localparam int PENDING_BASE = 'h001000;
localparam int ENABLE_BASE = 'h002000;
localparam int THRESHOLD_BASE = 'h200000;
localparam int CLAIM_COMPLETE = 'h200004;

// Internal registers
logic [PRIORITIES-1:0] priorities [SOURCES];
logic [SOURCES-1:0] enables;
logic [PRIORITIES-1:0] threshold;
logic [SOURCES-1:0] pending;
logic [$clog2(SOURCES)-1:0] claimed_irq;

// Register interface read data
logic [31:0] reg_rdata;

// ------------------------------
// Write Handling
// ------------------------------
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
for (int i = 0; i < SOURCES; i++) begin
priorities[i] <= '0;
end
enables <= '0;
threshold <= '0;
end else if (req_i && we_i) begin
case (addr_i[15:12])
5'h0: begin // Priority registers
if (addr_i[11:2] < SOURCES)
priorities[addr_i[11:2]] <= wdata_i[PRIORITIES-1:0];
end
5'h2: begin // Enable registers
if (addr_i[11:2] == 0)
enables <= wdata_i[SOURCES-1:0];
end
5'h20: begin // Threshold and claim/complete region
if (addr_i[3:2] == 0)
threshold <= wdata_i[PRIORITIES-1:0];
else if (addr_i[3:2] == 1) begin
// Handle interrupt completion: clear pending bit for the given IRQ index
if (wdata_i < SOURCES)
pending[wdata_i] <= 1'b0;
end
end
default: ;
endcase
end
end

// ------------------------------
// Read Handling
// ------------------------------
always_comb begin
reg_rdata = '0;
case (addr_i[15:12])
5'h0: begin // Priority registers
if (addr_i[11:2] < SOURCES)
reg_rdata = {{(32-PRIORITIES){1'b0}}, priorities[addr_i[11:2]]};
end
5'h1: begin // Pending registers
if (addr_i[11:2] == 0)
reg_rdata = pending;
end
5'h2: begin // Enable registers
if (addr_i[11:2] == 0)
reg_rdata = enables;
end
5'h20: begin // Threshold and claim/complete region
if (addr_i[3:2] == 0)
reg_rdata = {{(32-PRIORITIES){1'b0}}, threshold};
else if (addr_i[3:2] == 1)
reg_rdata = claimed_irq;
end
default: reg_rdata = '0;
endcase
end

// ------------------------------
// Interrupt Pending Update
// ------------------------------
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni)
pending <= '0;
else begin
for (int i = 0; i < SOURCES; i++) begin
if (irq_sources_i[i] && enables[i])
pending[i] <= 1'b1;
end
end
end

// ------------------------------
// Highest-Priority Pending Interrupt Logic
// ------------------------------
always_comb begin
logic found_irq;
logic [$clog2(SOURCES)-1:0] highest_irq;
logic [PRIORITIES-1:0] highest_priority;

found_irq = 1'b0;
highest_irq = '0;
highest_priority = '0;

for (int i = 0; i < SOURCES; i++) begin
if (pending[i] && enables[i] && (priorities[i] > threshold) &&
(!found_irq || priorities[i] > highest_priority)) begin
found_irq = 1'b1;
highest_irq = i;
highest_priority = priorities[i];
end
end

claimed_irq = highest_irq;
irq_o = found_irq;
end

assign irq_pending_o = pending;

// ------------------------------
// Response Valid Signal
// ------------------------------
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni)
rvalid_o <= 1'b0;
else
rvalid_o <= req_i;
end

assign rdata_o = reg_rdata;

endmodule
84 changes: 66 additions & 18 deletions dv/verilator/top_verilator.sv
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

// This is the top level that connects the demo system to the virtual devices.
// Corrected top level for Verilator simulation that connects the demo system to virtual devices
module top_verilator (input logic clk_i, rst_ni);

localparam ClockFrequency = 50_000_000;
localparam BaudRate = 115_200;

logic uart_sys_rx, uart_sys_tx;
logic irq_external;
logic [31:0] irq_sources;

// New signals for the updated PLIC DPI bus interface
logic plic_req;
logic [31:0] plic_addr;
logic plic_we;
logic [3:0] plic_be;
logic [31:0] plic_wdata;
logic plic_rvalid;
logic [31:0] plic_rdata;

// Instantiating the Ibex Demo System.
// Instantiate the Ibex Demo System
ibex_demo_system #(
.GpiWidth ( 8 ),
.GpoWidth ( 16 ),
Expand All @@ -19,39 +26,80 @@ module top_verilator (input logic clk_i, rst_ni);
.BaudRate ( BaudRate ),
.RegFile ( ibex_pkg::RegFileFF )
) u_ibex_demo_system (
//Input
.clk_sys_i (clk_i),
.rst_sys_ni(rst_ni),
.uart_rx_i (uart_sys_rx),

//Output
.uart_tx_o(uart_sys_tx),

// tie off JTAG
.uart_tx_o (uart_sys_tx),
// Tie off JTAG
.trst_ni(1'b1),
.tms_i (1'b0),
.tck_i (1'b0),
.td_i (1'b0),
.td_o ( ),

// Remaining IO
// Remaining I/O (unused for this example)
.gp_i (0),
.gp_o ( ),
.pwm_o ( ),
.spi_rx_i (0),
.spi_tx_o ( ),
.spi_sck_o ( )
// PLIC interface not directly connected to the demo system in this configuration
);

// Virtual UART
// Instantiate the Virtual UART
uartdpi #(
.BAUD(BaudRate),
.FREQ(ClockFrequency)
) u_uartdpi (
.clk_i,
.rst_ni,
.active (1'b1 ),
.clk_i(clk_i),
.rst_ni(rst_ni),
.active (1'b1),
.tx_o (uart_sys_rx),
.rx_i (uart_sys_tx)
);

// Drive default values for the PLIC bus signals (no bus transactions in this testbench)
assign plic_req = 1'b0;
assign plic_addr = 32'b0;
assign plic_we = 1'b0;
assign plic_be = 4'b0;
assign plic_wdata = 32'b0;

// Instantiate the corrected Virtual PLIC DPI module
plicdpi #(
.SOURCES(32),
.TARGETS(1),
.PRIORITIES(3)
) u_plicdpi (
.clk_i(clk_i),
.rst_ni(rst_ni),
.req_i(plic_req),
.addr_i(plic_addr),
.we_i(plic_we),
.be_i(plic_be),
.wdata_i(plic_wdata),
.rvalid_o(plic_rvalid),
.rdata_o(plic_rdata),
.irq_sources_i(irq_sources),
.irq_pending_o(), // Not used here
.irq_o(irq_external) // External interrupt output
);

// For testing, generate a timer interrupt on irq_sources[0]
logic [31:0] timer_counter;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
timer_counter <= '0;
irq_sources <= '0;
end else begin
timer_counter <= timer_counter + 1;
if (timer_counter == 1000) begin
timer_counter <= '0;
irq_sources[0] <= 1'b1; // Set timer interrupt source
end else begin
irq_sources[0] <= 1'b0; // Clear timer interrupt source
end
end
end

endmodule
7 changes: 4 additions & 3 deletions ibex_demo_system.core
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ filesets:
- lowrisc:dv_dpi_sv:uartdpi:0.1
files:
- dv/verilator/top_verilator.sv: { file_type: systemVerilogSource }
- dv/verilator/plicdpi.sv: { file_type: systemVerilogSource }
- dv/verilator/ibex_demo_system.cc: { file_type: cppSource }
- dv/verilator/ibex_demo_system.h: { file_type: cppSource, is_include_file: true}
- dv/verilator/ibex_demo_system_main.cc: { file_type: cppSource }
Expand Down Expand Up @@ -305,10 +306,10 @@ targets:
- '--trace-structs'
- '--trace-params'
- '--trace-max-array 1024'
- '-CFLAGS "-std=c++14 -Wall -DVM_TRACE_FMT_FST -DTOPLEVEL_NAME=top_verilator"'
- '-CFLAGS "-std=c++14 -DVM_TRACE_FMT_FST -DTOPLEVEL_NAME=top_verilator"'
- '-LDFLAGS "-pthread -lutil -lelf"'
- "-Wall"
- "-Wwarn-IMPERFECTSCH"
# - "-Wall"
# - "-Wwarn-IMPERFECTSCH"
# RAM primitives wider than 64bit (required for ECC) fail to build in
# Verilator without increasing the unroll count (see Verilator#1266)
- "--unroll-count 72"
Expand Down
1 change: 1 addition & 0 deletions ibex_demo_system_core.core
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ filesets:
- rtl/system/uart.sv
- rtl/system/spi_host.sv
- rtl/system/spi_top.sv
- rtl/system/plic.sv
file_type: systemVerilogSource

targets:
Expand Down
Loading