diff --git a/Makefile b/Makefile index dc0c2382a..b598ad519 100755 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ dpi := $(patsubst tb/dpi/%.cc,work/%.o,$(wildcard tb/dpi/*.cc)) dpi_hdr := $(wildcard tb/dpi/*.h) # this list contains the standalone components src := $(wildcard src/*.sv) $(wildcard tb/common/*.sv) $(wildcard tb/common/*.v) \ - $(wildcard src/axi_slice/*.sv) \ + $(wildcard src/axi_slice/*.sv) $(wildcard src/clint/*.sv) \ $(wildcard src/axi_node/*.sv) $(wildcard src/axi_mem_if/src/*.sv) \ $(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) $(wildcard bootrom/*.sv) \ $(wildcard src/debug/debug_rom/*.sv) @@ -107,6 +107,7 @@ verilate_command := $(verilator) tb/ariane_testharness.sv \ $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \ $(wildcard src/axi_slice/*.sv) \ + $(wildcard src/clint/*.sv) \ $(filter-out src/debug/dm_pkg.sv, $(wildcard src/debug/*.sv)) \ src/debug/debug_rom/debug_rom.sv \ src/util/generic_fifo.sv \ diff --git a/src/clint/README.md b/src/clint/README.md index f82849afe..978181589 100644 --- a/src/clint/README.md +++ b/src/clint/README.md @@ -6,5 +6,6 @@ The CLINT plugs into an existing AXI Bus with an AXI 4 Lite interface. The IP mi | Address | Description | Note | |-------------------|-------------|------------------------------------------------| +| `BASE` + `0xo` | msip | Machine mode software interrupt (IPI) | | `BASE` + `0x4000` | mtimecmp | Machine mode timer compare register for Hart 0 | -| `BASE` + `0xC000` | mtime | Timer register | +| `BASE` + `0xBFF8` | mtime | Timer register | diff --git a/src/clint/clint.sv b/src/clint/clint.sv index f3a90dd3d..9254d6764 100644 --- a/src/clint/clint.sv +++ b/src/clint/clint.sv @@ -22,19 +22,21 @@ module clint #( parameter int unsigned AXI_ID_WIDTH = 10, parameter int unsigned NR_CORES = 1 // Number of cores therefore also the number of timecmp registers and timer interrupts )( - input logic clk_i, // Clock - input logic rst_ni, // Asynchronous reset active low + input logic clk_i, // Clock + input logic rst_ni, // Asynchronous reset active low AXI_BUS.Slave slave, - input logic halted_i, // cores are halted, also halt timer - input logic rtc_i, // Real-time clock in (usually 32.768 kHz) - output logic [63:0] time_o, // Global Time out, this is the time-base of the whole SoC - output logic [NR_CORES-1:0] irq_o // Timer interrupts + input logic halted_i, // cores are halted, also halt timer + input logic rtc_i, // Real-time clock in (usually 32.768 kHz) + output logic [63:0] time_o, // Global Time out, this is the time-base of the whole SoC + output logic [NR_CORES-1:0] timer_irq_o, // Timer interrupts + output logic [NR_CORES-1:0] ipi_o // software interrupt (a.k.a inter-process-interrupt) ); // register offset - localparam logic [1:0] REG_CMP = 2'h1; - localparam logic [1:0] REG_TIME = 2'h3; + localparam logic [15:0] MSIP_BASE = 16'h0; + localparam logic [15:0] MTIMECMP_BASE = 16'h4000; + localparam logic [15:0] MTIME_BASE = 16'hbff8; // signals from AXI 4 Lite logic [AXI_ADDR_WIDTH-1:0] address; logic en; @@ -43,12 +45,12 @@ module clint #( logic [63:0] rdata; // bit 11 and 10 are determining the address offset - logic [1:0] register_address; - assign register_address = address[11:10]; + logic [15:0] register_address; + assign register_address = address[15:0]; // actual registers logic [63:0] mtime_n, mtime_q; logic [NR_CORES-1:0][63:0] mtimecmp_n, mtimecmp_q; - + logic [NR_CORES-1:0] msip_n, misp_q; // increase the timer logic increase_timer; @@ -78,19 +80,25 @@ module clint #( always_comb begin mtime_n = mtime_q; mtimecmp_n = mtimecmp_q; - + msip_n = msip_q; // RTC says we should increase the timer if (increase_timer && !halted_i) mtime_n = mtime_q + 1; // written from APB bus - gets priority if (en && we) begin - case (register_address) - REG_TIME: - mtime_n = wdata; + case (register_address) inside + [MSIP_BASE:MSIP_BASE+8*NR_CORES]: begin + msip_n[$unsigned(address[NR_CORES-1+3:3])] = wdata[0]; + end - REG_CMP: + [MTIMECMP_BASE:MTIMECMP_BASE+8*NR_CORES]: begin mtimecmp_n[$unsigned(address[NR_CORES-1+3:3])] = wdata; + end + + MTIME_BASE: begin + mtime_n = wdata; + end default:; endcase end @@ -101,12 +109,18 @@ module clint #( rdata = 'b0; if (en && !we) begin - case (register_address) - REG_TIME: - rdata = mtime_q; + case (register_address) inside + [MSIP_BASE:MSIP_BASE+8*NR_CORES]: begin + rdata = misp_q[$unsigned(address[NR_CORES-1+3:3])]; + end - REG_CMP: + [MTIMECMP_BASE:MTIMECMP_BASE+8*NR_CORES]: begin rdata = mtimecmp_q[$unsigned(address[NR_CORES-1+3:3])]; + end + + MTIME_BASE: begin + rdata = mtime_q; + end default:; endcase end @@ -149,9 +163,11 @@ module clint #( if(~rst_ni) begin mtime_q <= 64'b0; mtimecmp_q <= 'b0; + misp_q <= '0; end else begin mtime_q <= mtime_n; mtimecmp_q <= mtimecmp_n; + misp_q <= msip_n; end end