Merge pull request #22 from CTSRD-CHERI/wip-aj443-WindCoreInterface
Wip aj443 wind core interface
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,3 +13,6 @@
|
||||
[submodule "libs/RISCV_HPM_Events"]
|
||||
path = libs/RISCV_HPM_Events
|
||||
url = https://github.com/CTSRD-CHERI/RISCV_HPM_Events.git
|
||||
[submodule "libs/WindCoreInterface"]
|
||||
path = libs/WindCoreInterface
|
||||
url = https://github.com/CTSRD-CHERI/WindCoreInterface.git
|
||||
|
||||
@@ -92,7 +92,7 @@ library RTL can be found in the directory `src_bsc_lib_RTL`.
|
||||
**Bluespec BSV** source code (which was used to generate the Verilog RTL) can be found in:
|
||||
|
||||
- `src_Core/`, for the CPU core, with sub-directories:
|
||||
- `Core/`: the top-level of the CPU Core (specifically, the files CoreW_IFC.bsv and CoreW.bsv)
|
||||
- `Core/`: the top-level of the CPU Core (specifically, CoreW.bsv)
|
||||
- `CPU/`: more CPU core sources
|
||||
- `RISCY_OOO/`: the bulk of the code, taken from MIT's riscy-ooo design, with local modifications.
|
||||
- `ISA/`: generic types/constants/functions for the RISC-V ISA (not CPU-implementation-specific)
|
||||
|
||||
@@ -11,6 +11,23 @@ EXTRA_DIRS = $(RISCY_HOME)/../../src_Verifier:$(RISCY_HOME)/../../src_Verifier/B
|
||||
# ================================================================
|
||||
# RISC-V config macros passed into Bluespec 'bsc' compiler
|
||||
|
||||
BSC_COMPILATION_FLAGS += \
|
||||
-D RV64 \
|
||||
-D ISA_PRIV_M -D ISA_PRIV_U -D ISA_PRIV_S \
|
||||
-D SV39 \
|
||||
-D ISA_I -D ISA_M -D ISA_A -D ISA_F -D ISA_D -D ISA_FD_DIV -D ISA_C \
|
||||
-D SHIFT_BARREL \
|
||||
-D MULT_SYNTH \
|
||||
-D Near_Mem_Caches \
|
||||
-D FABRIC64 \
|
||||
-D CheriBusBytes=8 \
|
||||
-D CheriMasterIDWidth=1 \
|
||||
-D CheriTransactionIDWidth=5 \
|
||||
-D CAP128 -D BLUESIM \
|
||||
-D MEM64 \
|
||||
-D RISCV \
|
||||
-D INCLUDE_GDB_CONTROL
|
||||
|
||||
# Default ISA test
|
||||
|
||||
TEST ?= rv64ui-p-add
|
||||
|
||||
@@ -54,13 +54,20 @@ CORE_DIRS = $(REPO)/src_Core/CPU:$(REPO)/src_Core/ISA:$(REPO)/src_Core/Core:$(RE
|
||||
|
||||
TESTBENCH_DIRS = $(REPO)/src_Testbench/Top:$(REPO)/src_Testbench/SoC
|
||||
|
||||
BLUESTUFF_DIRS = $(REPO)/libs/BlueStuff:$(REPO)/libs/BlueStuff/AXI:$(REPO)/libs/BlueStuff/BlueUtils:$(REPO)/libs/BlueStuff/BlueBasics
|
||||
BLUESTUFFDIR = $(REPO)/libs/BlueStuff
|
||||
BLUEAXI4DIR = $(BLUESTUFFDIR)/BlueAXI4
|
||||
BLUEAXI4DIRS = $(BLUEAXI4DIR):$(BLUEAXI4DIR)/AXI4:$(BLUEAXI4DIR)/AXI4Lite:$(BLUEAXI4DIR)/AXI4Stream:$(BLUEAXI4DIR)/BlueUnixBridges
|
||||
BLUEBASICSDIR = $(BLUESTUFFDIR)/BlueBasics
|
||||
BLUEUTILSDIR = $(BLUESTUFFDIR)/BlueUtils
|
||||
BLUESTUFF_DIRS = $(BLUESTUFFDIR):$(BLUEAXI4DIRS):$(BLUEBASICSDIR):$(BLUEUTILSDIR)
|
||||
|
||||
WINDCOREIFC_DIRS = $(REPO)/libs/WindCoreInterface
|
||||
|
||||
TAGCONTROLLER_DIRS = $(REPO)/libs/TagController/TagController:$(REPO)/libs/TagController/TagController/CacheCore
|
||||
|
||||
RISCV_HPM_Events_DIR = $(REPO)/libs/RISCV_HPM_Events
|
||||
|
||||
BSC_PATH = $(BLUESTUFF_DIRS):$(ALL_RISCY_DIRS):$(CORE_DIRS):$(TESTBENCH_DIRS):$(TAGCONTROLLER_DIRS):$(RISCV_HPM_Events_DIR):+
|
||||
BSC_PATH = $(BLUESTUFF_DIRS):$(WINDCOREIFC_DIRS):$(ALL_RISCY_DIRS):$(CORE_DIRS):$(TESTBENCH_DIRS):$(TAGCONTROLLER_DIRS):$(RISCV_HPM_Events_DIR):+
|
||||
|
||||
# ----------------
|
||||
# Top-level file and module
|
||||
|
||||
Submodule libs/BlueStuff updated: 8a36aa9af4...ea96432eb2
Submodule libs/TagController updated: 2e2198b05f...0af8406ac6
1
libs/WindCoreInterface
Submodule
1
libs/WindCoreInterface
Submodule
Submodule libs/WindCoreInterface added at 5af81c8abb
Submodule libs/cheri-cap-lib updated: b80c1b3c59...806b687e8a
@@ -66,9 +66,9 @@ interface MMIO_AXI4_Adapter_IFC;
|
||||
interface Server #(MMIOCRq, MMIODataPRs) core_side;
|
||||
|
||||
// Fabric master interface for IO
|
||||
interface AXI4_Master #(Wd_MId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) mmio_master;
|
||||
interface AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User) mmio_master;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
@@ -127,7 +127,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// necessary; the AXI4 fabric should return a DECERR for illegal
|
||||
// addrs; but not all AXI4 fabrics do the right thing.
|
||||
if (soc_map.m_is_IO_addr (req.addr, False)) begin
|
||||
let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_2x3_default_mid,
|
||||
let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_corew_bus_default_mid,
|
||||
araddr: req.addr,
|
||||
arlen: (burst) ? 1:0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
@@ -220,8 +220,8 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// on first flit...
|
||||
// ================
|
||||
if (first) begin
|
||||
AXI4_AWFlit #(Wd_MId_2x3, Wd_Addr, Wd_AW_User)
|
||||
mem_req_wr_addr = AXI4_AWFlit {awid: fabric_2x3_default_mid,
|
||||
AXI4_AWFlit #(Wd_CoreW_Bus_MId, Wd_Addr, Wd_AW_User)
|
||||
mem_req_wr_addr = AXI4_AWFlit {awid: fabric_corew_bus_default_mid,
|
||||
awaddr: req.addr,
|
||||
awlen: (burst) ? 1:0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
//-
|
||||
// RVFI_DII + CHERI modifications:
|
||||
// Copyright (c) 2020 Alexandre Joannou
|
||||
// Copyright (c) 2020-2022 Alexandre Joannou
|
||||
// Copyright (c) 2020 Peter Rugg
|
||||
// Copyright (c) 2020 Jonathan Woodruff
|
||||
// All rights reserved.
|
||||
@@ -13,6 +13,13 @@
|
||||
// DARPA SSITH research programme.
|
||||
//
|
||||
// This work was supported by NCSC programme grant 4212611/RFA 15971 ("SafeBet").
|
||||
//
|
||||
// This material is based upon work supported by the DoD Information Analysis
|
||||
// Center Program Management Office (DoD IAC PMO), sponsored by the Defense
|
||||
// Technical Information Center (DTIC) under Contract No. FA807518D0004. Any
|
||||
// opinions, findings and conclusions or recommendations expressed in this
|
||||
// material are those of the author(s) and do not necessarily reflect the views
|
||||
// of the Air Force Installation Contracting Agency (AFICA).
|
||||
//-
|
||||
|
||||
package Proc_IFC;
|
||||
@@ -72,9 +79,9 @@ interface Proc_IFC;
|
||||
Wd_AR_User, Wd_R_User) master0;
|
||||
|
||||
// Fabric master interface for IO (from MMIOPlatform)
|
||||
interface AXI4_Master #(Wd_MId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) master1;
|
||||
interface AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User) master1;
|
||||
|
||||
// ----------------
|
||||
// External interrupts
|
||||
@@ -99,9 +106,9 @@ interface Proc_IFC;
|
||||
// ----------------
|
||||
// Coherent port into LLC (used by Debug Module, DMA engines, ... to read/write memory)
|
||||
|
||||
interface AXI4_Slave #(Wd_SId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) debug_module_mem_server;
|
||||
interface AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User) debug_module_mem_server;
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//
|
||||
//-
|
||||
// RVFI_DII + CHERI modifications:
|
||||
// Copyright (c) 2020 Alexandre Joannou
|
||||
// Copyright (c) 2020-2022 Alexandre Joannou
|
||||
// Copyright (c) 2020 Peter Rugg
|
||||
// Copyright (c) 2020 Jonathan Woodruff
|
||||
// All rights reserved.
|
||||
@@ -13,6 +13,13 @@
|
||||
// DARPA SSITH research programme.
|
||||
//
|
||||
// This work was supported by NCSC programme grant 4212611/RFA 15971 ("SafeBet").
|
||||
//
|
||||
// This material is based upon work supported by the DoD Information Analysis
|
||||
// Center Program Management Office (DoD IAC PMO), sponsored by the Defense
|
||||
// Technical Information Center (DTIC) under Contract No. FA807518D0004. Any
|
||||
// opinions, findings and conclusions or recommendations expressed in this
|
||||
// material are those of the author(s) and do not necessarily reflect the views
|
||||
// of the Air Force Installation Contracting Agency (AFICA).
|
||||
//-
|
||||
|
||||
package CoreW;
|
||||
@@ -46,6 +53,7 @@ package CoreW;
|
||||
// BSV library imports
|
||||
|
||||
import Vector :: *;
|
||||
import FIFO :: *;
|
||||
import FIFOF :: *;
|
||||
import GetPut :: *;
|
||||
import ClientServer :: *;
|
||||
@@ -59,7 +67,8 @@ import Cur_Cycle :: *;
|
||||
import GetPut_Aux :: *;
|
||||
import Routable :: *;
|
||||
import AXI4 :: *;
|
||||
import AXI4_Utils :: *;
|
||||
import AXI4Lite :: *;
|
||||
import SourceSink :: *;
|
||||
import TagControllerAXI :: *;
|
||||
import CacheCore :: *;
|
||||
|
||||
@@ -84,9 +93,9 @@ import SoC_Map :: *;
|
||||
import Debug_Module :: *;
|
||||
`endif
|
||||
|
||||
import CoreW_IFC :: *;
|
||||
import Proc_IFC :: *;
|
||||
import Proc :: *;
|
||||
import WindCoreInterface :: *;
|
||||
import Proc_IFC :: *;
|
||||
import Proc :: *;
|
||||
|
||||
import PLIC :: *;
|
||||
import PLIC_16_CoreNumX2_7 :: *;
|
||||
@@ -110,9 +119,37 @@ import DM_CPU_Req_Rsp ::*;
|
||||
// ================================================================
|
||||
// The Core module
|
||||
|
||||
(* synthesize *)
|
||||
module mkCoreW #(Reset dm_power_on_reset)
|
||||
(CoreW_IFC #(N_External_Interrupt_Sources));
|
||||
typedef WindCoreMid #( // AXI lite subordinate control port parameters
|
||||
21, 32, 0, 0, 0, 0, 0
|
||||
// AXI manager 0 port parameters
|
||||
, TAdd #(Wd_MId, 1), Wd_Addr, Wd_Data, 0, 0, 0, 0, 0
|
||||
// AXI manager 1 port parameters
|
||||
, TAdd #(Wd_MId, 1), Wd_Addr, Wd_Data, 0, 0, 0, 0, 0
|
||||
// AXI subordinate 0 port parameters
|
||||
, Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User
|
||||
// Number of interrupt lines
|
||||
, t_n_irq) CoreW_IFC #(numeric type t_n_irq);
|
||||
|
||||
//(* synthesize *)
|
||||
module mkCoreW (CoreW_IFC #(t_n_irq));
|
||||
Clock clk <- exposeCurrentClock;
|
||||
Reset rst <- exposeCurrentReset;
|
||||
let newRst <- mkReset (0, True, clk, reset_by rst);
|
||||
match {.otherRst, .ifc} <- mkCoreW_reset ( rst
|
||||
, reset_by newRst.new_rst);
|
||||
rule rl_forward_debug_reset (otherRst);
|
||||
newRst.assertReset;
|
||||
endrule
|
||||
return ifc;
|
||||
endmodule
|
||||
|
||||
// The interface to this module is a convenience to avoid exposing the reset
|
||||
// hacks to the nicer outer interface, and not have to use a large amount of
|
||||
// reset_by to decouple the debug module from the rest...
|
||||
module mkCoreW_reset #(Reset porReset)
|
||||
(Tuple2#(PulseWire, CoreW_IFC #(t_n_irq)));
|
||||
|
||||
// ================================================================
|
||||
// Notes on 'reset'
|
||||
@@ -121,7 +158,7 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
// 'non-debug-module reset', or 'ndm-reset': it resets everything
|
||||
// in mkCoreW other than the optional RISC-V Debug Module (DM).
|
||||
|
||||
// DM is reset ONLY by 'dm_power_on_reset' (parameter of this module).
|
||||
// DM is reset ONLY by 'porReset' (parameter of this module).
|
||||
// This is expected to be performed exactly once, on power-up.
|
||||
|
||||
// Note: DM has an internal functionality that the DM spec calls
|
||||
@@ -172,14 +209,16 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
Proc_IFC proc <- mkProc (reset_by all_harts_reset);
|
||||
|
||||
// handle uncached interface
|
||||
let proc_uncached = prepend_AXI4_Master_id (0, zero_AXI4_Master_user (proc.master1));
|
||||
let proc_uncached =
|
||||
prepend_AXI4_Master_id (0, zero_AXI4_Master_user (proc.master1));
|
||||
// Bridge for uncached expernal bus transactions.
|
||||
let uncached_mem_shim <- mkAXI4ShimFF(reset_by all_harts_reset);
|
||||
|
||||
// handle cached interface
|
||||
// AXI4 tagController
|
||||
TagControllerAXI#(Wd_MId, Wd_Addr, Wd_Data) tagController <- mkTagControllerAXI(reset_by all_harts_reset); // TODO double check if reseting like this is good enough
|
||||
mkConnection(proc.master0, tagController.slave, reset_by all_harts_reset);
|
||||
TagControllerAXI #(Wd_MId, Wd_Addr, Wd_Data)
|
||||
tagController <- mkTagControllerAXI (reset_by all_harts_reset); // TODO double check if reseting like this is good enough
|
||||
mkConnection (proc.master0, tagController.slave, reset_by all_harts_reset);
|
||||
`ifdef PERFORMANCE_MONITORING
|
||||
rule report_tagController_events;
|
||||
EventsCacheCore cache_core_evts = tagController.events;
|
||||
@@ -198,11 +237,11 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
`endif
|
||||
|
||||
// PLIC (Platform-Level Interrupt Controller)
|
||||
PLIC_IFC_16_CoreNumX2_7 plic <- mkPLIC_16_CoreNumX2_7;
|
||||
PLIC_IFC_16_CoreNumX2_7 plic <- mkPLIC_16_CoreNumX2_7 (reset_by all_harts_reset);
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// Debug Module
|
||||
Debug_Module_IFC debug_module <- mkDebug_Module (reset_by dm_power_on_reset);
|
||||
Debug_Module_IFC debug_module <- mkDebug_Module (reset_by porReset);
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
@@ -215,9 +254,16 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
TV_Encode_IFC tv_encode <- mkTV_Encode;
|
||||
`endif
|
||||
|
||||
function do_release (restartRunning) = action
|
||||
plic.set_addr_map (zeroExtend (soc_map.m_plic_addr_range.base),
|
||||
zeroExtend (rangeTop(soc_map.m_plic_addr_range)));
|
||||
proc.start (restartRunning, soc_map_struct.pc_reset_value, 0, 0);
|
||||
endaction;
|
||||
|
||||
// ================================================================
|
||||
// Hart-reset from DM
|
||||
|
||||
Bool start_running = False;
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
Reg #(Bit #(8)) rg_harts_reset_delay <- mkReg (0);
|
||||
Reg #(Bit #(64)) rg_tohost_addr <- mkReg (0);
|
||||
@@ -225,36 +271,43 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
|
||||
for (Integer core = 0; core < valueOf(CoreNum); core = core + 1)
|
||||
rule rl_dm_harts_reset (rg_harts_reset_delay == 0);
|
||||
let x <- debug_module.harts_reset_client[core].request.get;
|
||||
dm_harts_reset_controller[core].assertReset;
|
||||
rg_harts_reset_delay <= fromInteger (hart_reset_duration + 200); // NOTE: heuristic
|
||||
|
||||
$display ("%0d: %m.rl_dm_harts_reset: asserting harts reset for %0d cycles",
|
||||
let x <- debug_module.harts_reset_client[core].request.get;
|
||||
dm_harts_reset_controller[core].assertReset;
|
||||
rg_harts_reset_delay <= fromInteger (hart_reset_duration + 200); // NOTE: heuristic
|
||||
$display ("%0d: %m.rl_dm_harts_reset: asserting harts reset for %0d cycles",
|
||||
cur_cycle, hart_reset_duration);
|
||||
endrule
|
||||
endrule
|
||||
|
||||
rule rl_dm_harts_reset_wait (rg_harts_reset_delay != 0);
|
||||
if (rg_harts_reset_delay == 1) begin
|
||||
let pc = soc_map_struct.pc_reset_value;
|
||||
Bool is_running = True;
|
||||
proc.start (is_running, pc, rg_tohost_addr, rg_fromhost_addr);
|
||||
proc.start (start_running, pc, rg_tohost_addr, rg_fromhost_addr);
|
||||
// We reset all the harts, so we indicate this to the DM, even though it's possible only one hart was requested to reset
|
||||
for (Integer core = 0; core < valueOf(CoreNum); core = core + 1)
|
||||
debug_module.harts_reset_client[core].response.put (is_running);
|
||||
$display ("%0d: %m.rl_dm_harts_reset_wait: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h",
|
||||
debug_module.harts_reset_client[core].response.put (start_running);
|
||||
$display ("%0d: %m.rl_dm_harts_reset_wait: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h",
|
||||
cur_cycle, pc, rg_tohost_addr, rg_fromhost_addr);
|
||||
end
|
||||
rg_harts_reset_delay <= rg_harts_reset_delay - 1;
|
||||
endrule
|
||||
|
||||
`endif
|
||||
// ================================================================
|
||||
// Start the proc a suitable time after a PoR
|
||||
UInt#(8) initial_wait = 100; // heuristic -- better to wait till "all out of reset" received from corew
|
||||
Reg #(UInt#(8)) rg_corew_start_after_por <- mkReg(initial_wait, reset_by porReset);
|
||||
rule rl_step_0 (rg_corew_start_after_por != 0);
|
||||
let n = rg_corew_start_after_por - 1;
|
||||
rg_corew_start_after_por <= n;
|
||||
if (n==0) do_release(start_running);
|
||||
endrule
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// ================================================================
|
||||
// Direct DM-to-CPU connections for run-control and other misc requests
|
||||
|
||||
mkConnection (debug_module.harts_client_run_halt, proc.harts_run_halt_server);
|
||||
mkConnection (debug_module.harts_get_other_req, proc.harts_put_other_req);
|
||||
mkConnection (debug_module.harts_client_run_halt, proc.harts_run_halt_server, reset_by porReset);
|
||||
mkConnection (debug_module.harts_get_other_req, proc.harts_put_other_req, reset_by porReset);
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
@@ -335,15 +388,15 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
// BEGIN SECTION: DM, no TV
|
||||
|
||||
// Connect DM's GPR interface directly to CPU
|
||||
mkConnection (debug_module.harts_gpr_mem_client, proc.harts_gpr_mem_server);
|
||||
mkConnection (debug_module.harts_gpr_mem_client, proc.harts_gpr_mem_server, reset_by porReset);
|
||||
|
||||
`ifdef ISA_F_OR_D
|
||||
// Connect DM's FPR interface directly to CPU
|
||||
mkConnection (debug_module.harts_fpr_mem_client, proc.harts_fpr_mem_server);
|
||||
mkConnection (debug_module.harts_fpr_mem_client, proc.harts_fpr_mem_server, reset_by porReset);
|
||||
`endif
|
||||
|
||||
// Connect DM's CSR interface directly to CPU
|
||||
mkConnection (debug_module.harts_csr_mem_client, proc.harts_csr_mem_server);
|
||||
mkConnection (debug_module.harts_csr_mem_client, proc.harts_csr_mem_server, reset_by porReset);
|
||||
|
||||
// DM's bus master is directly the bus master
|
||||
let dm_master_local = debug_module.master;
|
||||
@@ -369,30 +422,35 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
|
||||
|
||||
// ================================================================
|
||||
// Connect the local 2x3 fabric
|
||||
// new internal AXI4 manager from interace subordinate port
|
||||
let subShim <- mkAXI4Shim;
|
||||
|
||||
// Masters on the local 2x3 fabric
|
||||
Vector#(Num_Masters_2x3, AXI4_Master #(Wd_MId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User))
|
||||
master_vector = newVector;
|
||||
//let master_vector = newVector;
|
||||
// ================================================================
|
||||
// Connect the local bus
|
||||
|
||||
// Masters on the local bus
|
||||
Vector #( CoreW_Bus_Num_Masters
|
||||
, AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User))
|
||||
master_vector = newVector;
|
||||
master_vector[cpu_uncached_master_num] = proc_uncached;
|
||||
master_vector[debug_module_sba_master_num] = dm_master_local;
|
||||
master_vector[sub_ifc_master_num] = subShim.master;
|
||||
|
||||
// Slaves on the local 2x3 fabric
|
||||
// Slaves on the local bus
|
||||
// default slave is forwarded out directly to the Core interface
|
||||
Vector#(Num_Slaves_2x3, AXI4_Slave #(Wd_SId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User))
|
||||
slave_vector = newVector;
|
||||
//let slave_vector = newVector;
|
||||
Vector #( CoreW_Bus_Num_Slaves
|
||||
, AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User))
|
||||
slave_vector = newVector;
|
||||
slave_vector[default_slave_num] = uncached_mem_shim.slave;
|
||||
slave_vector[llc_slave_num] = proc.debug_module_mem_server;
|
||||
slave_vector[plic_slave_num] = zero_AXI4_Slave_user (plic.axi4_slave);
|
||||
|
||||
function Vector#(Num_Slaves_2x3, Bool) route_2x3 (Bit#(Wd_Addr) addr);
|
||||
Vector#(Num_Slaves_2x3, Bool) res = replicate(False);
|
||||
function Vector #(CoreW_Bus_Num_Slaves, Bool) route (Bit #(Wd_Addr) addr);
|
||||
Vector #(CoreW_Bus_Num_Slaves, Bool) res = replicate(False);
|
||||
if (inRange(soc_map.m_mem0_controller_addr_range, addr))
|
||||
res[llc_slave_num] = True;
|
||||
else if (inRange(soc_map.m_plic_addr_range, addr))
|
||||
@@ -404,7 +462,7 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
return res;
|
||||
endfunction
|
||||
|
||||
mkAXI4Bus (route_2x3, master_vector, slave_vector);
|
||||
mkAXI4Bus (route, master_vector, slave_vector, reset_by all_harts_reset);
|
||||
|
||||
// ================================================================
|
||||
// Connect external interrupt lines from PLIC to CPU
|
||||
@@ -422,79 +480,117 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
proc.s_external_interrupt_req (seips);
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
// Connect external debug module interface
|
||||
|
||||
let dbgShim <- mkAXI4LiteShim (reset_by porReset);
|
||||
|
||||
rule rl_debug_module_read_req;
|
||||
let arFlit <- get (dbgShim.master.ar);
|
||||
debug_module.dmi.read_addr (truncate (arFlit.araddr >> 2));
|
||||
endrule
|
||||
rule rl_debug_module_read_rsp;
|
||||
let x <- debug_module.dmi.read_data;
|
||||
dbgShim.master.r.put(AXI4Lite_RFlit { rdata: x, rresp: OKAY, ruser: ?});
|
||||
endrule
|
||||
rule rl_debug_module_write_req;
|
||||
let awFlit <- get (dbgShim.master.aw);
|
||||
let wFlit <- get (dbgShim.master.w);
|
||||
dbgShim.master.b.put(defaultValue);
|
||||
debug_module.dmi.write (truncate (awFlit.awaddr >> 2), wFlit.wdata);
|
||||
endrule
|
||||
|
||||
let fromDbgReset <- mkPulseWire (reset_by porReset);
|
||||
Reg #(UInt #(8)) ndm_reset_delay <- mkReg (0, reset_by porReset);
|
||||
Reg #(Bool) ndm_reset_restart_running <- mkReg (False, reset_by porReset);
|
||||
rule rl_debug_module_send_reset (ndm_reset_delay == 0);
|
||||
let restartRunning <- debug_module.ndm_reset_client.request.get;
|
||||
ndm_reset_delay <= 110;
|
||||
ndm_reset_restart_running <= restartRunning;
|
||||
fromDbgReset.send;
|
||||
endrule
|
||||
rule rl_debug_module_count_reset_delay (ndm_reset_delay > 1);
|
||||
ndm_reset_delay <= ndm_reset_delay - 1;
|
||||
endrule
|
||||
rule rl_debug_module_ack_reset (ndm_reset_delay == 1);
|
||||
debug_module.ndm_reset_client.response.put (ndm_reset_restart_running);
|
||||
do_release (ndm_reset_restart_running);
|
||||
ndm_reset_delay <= 0;
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
// Connect external interrupts to the PLIC and Proc
|
||||
|
||||
Vector #(t_n_irq, Reg #(Bool)) irq_reg
|
||||
<- replicateM (mkReg (False));
|
||||
Vector #(t_n_irq, Put #(Bool)) irq_ifc;
|
||||
for (Integer i = 0; i < valueof (t_n_irq); i = i + 1) begin
|
||||
irq_ifc [i] = interface Put;
|
||||
method put = writeReg (irq_reg[i]);
|
||||
endinterface;
|
||||
rule rl_connect_irq;
|
||||
plic.v_sources[i].m_interrupt_req (irq_reg[i]);
|
||||
endrule
|
||||
end
|
||||
|
||||
let nmirq_reg <- mkReg (False);
|
||||
let nmirq_ifc = interface Put;
|
||||
method put = writeReg (nmirq_reg);
|
||||
endinterface;
|
||||
rule rl_connect_nmirq;
|
||||
proc.non_maskable_interrupt_req (nmirq_reg);
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
// Connect other control and status signals
|
||||
|
||||
let f_ctrl_reqs <- mkFIFO1;
|
||||
let f_ctrl_rsps <- mkFIFO1;
|
||||
|
||||
rule rl_ctrl_req;
|
||||
case (f_ctrl_reqs.first) matches
|
||||
tagged ReleaseReq: do_release (False);
|
||||
tagged StatusReq: $display ("StatusReq not supported in Toooba");
|
||||
endcase
|
||||
f_ctrl_reqs.deq;
|
||||
endrule
|
||||
|
||||
rule rl_ctrl_rsp;
|
||||
f_ctrl_rsps.enq (StatusRsp(?));
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
// INTERFACE
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Debugging: set core's verbosity, htif addrs
|
||||
let ifc = interface CoreW_IFC;
|
||||
// debug related signals
|
||||
// ---------------------
|
||||
interface debug_subordinate = dbgShim.slave;
|
||||
|
||||
method Action set_verbosity (Bit #(4) verbosity, Bit #(64) logdelay);
|
||||
// Warning: ignoring logdelay
|
||||
proc.set_verbosity (verbosity);
|
||||
endmethod
|
||||
// interrupt related signals
|
||||
// -------------------------
|
||||
interface irq = irq_ifc;
|
||||
interface nmirq = nmirq_ifc;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Start
|
||||
// other control and status signals
|
||||
// --------------------------------
|
||||
interface controlStatusServer = toGPServer (f_ctrl_reqs, f_ctrl_rsps);
|
||||
|
||||
method Action start (Bool is_running, Bit #(64) tohost_addr, Bit #(64) fromhost_addr);
|
||||
plic.set_addr_map (zeroExtend (soc_map.m_plic_addr_range.base),
|
||||
zeroExtend (rangeTop(soc_map.m_plic_addr_range)));
|
||||
|
||||
let pc = soc_map_struct.pc_reset_value;
|
||||
proc.start (is_running, pc, tohost_addr, fromhost_addr);
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// Save for potential future use by rl_dm_harts_reset
|
||||
rg_tohost_addr <= tohost_addr;
|
||||
rg_fromhost_addr <= fromhost_addr;
|
||||
`endif
|
||||
|
||||
$display ("%0d: %m.method start: proc.start (pc %0h, tohostAddr %0h, fromhostAddr %0h)",
|
||||
cur_cycle, pc, tohost_addr, fromhost_addr);
|
||||
endmethod
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// AXI4 Fabric interfaces
|
||||
|
||||
// Cached master to Fabric master interface
|
||||
interface cpu_imem_master = tagController.master;
|
||||
|
||||
// Uncached master to Fabric master interface
|
||||
interface cpu_dmem_master = prepend_AXI4_Master_id(0, zero_AXI4_Master_user(uncached_mem_shim.master));
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// External interrupt sources
|
||||
|
||||
interface core_external_interrupt_sources = plic.v_sources;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Non-maskable interrupt request
|
||||
|
||||
method Action nmi_req (Bool set_not_clear);
|
||||
// TODO: fixup; passing const False for now
|
||||
proc.non_maskable_interrupt_req (False);
|
||||
endmethod
|
||||
// memory interfaces
|
||||
// -----------------
|
||||
// Cached master to Fabric master interface
|
||||
interface manager_0 = tagController.master;
|
||||
// Uncached master to Fabric master interface
|
||||
interface manager_1 = prepend_AXI4_Master_id
|
||||
(0, zero_AXI4_Master_user (uncached_mem_shim.master));
|
||||
interface subordinate_0 = subShim.slave;
|
||||
endinterface;
|
||||
|
||||
/*
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server = proc.rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// ----------------------------------------------------------------
|
||||
// Optional DM interfaces
|
||||
|
||||
// ----------------
|
||||
// DMI (Debug Module Interface) facing remote debugger
|
||||
|
||||
interface DMI dmi = debug_module.dmi;
|
||||
|
||||
// ----------------
|
||||
// Facing Platform
|
||||
|
||||
// Non-Debug-Module Reset (reset all except DM)
|
||||
interface Client ndm_reset_client = debug_module.ndm_reset_client;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
// ----------------------------------------------------------------
|
||||
// Optional TV interface
|
||||
@@ -506,50 +602,28 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
endmethod
|
||||
endinterface
|
||||
`endif
|
||||
*/
|
||||
|
||||
endmodule: mkCoreW
|
||||
|
||||
(* synthesize *)
|
||||
module mkCoreW_Synth #(Reset dm_power_on_reset)
|
||||
(CoreW_IFC_Synth #(N_External_Interrupt_Sources));
|
||||
let core <- mkCoreW (dm_power_on_reset);
|
||||
let cpu_imem_master_sig <- toAXI4_Master_Sig (core.cpu_imem_master);
|
||||
let cpu_dmem_master_sig <- toAXI4_Master_Sig (core.cpu_dmem_master);
|
||||
|
||||
method set_verbosity = core.set_verbosity;
|
||||
method start = core.start;
|
||||
interface cpu_imem_master = cpu_imem_master_sig;
|
||||
interface cpu_dmem_master = cpu_dmem_master_sig;
|
||||
interface core_external_interrupt_sources = core.core_external_interrupt_sources;
|
||||
method nmi_req = core.nmi_req;
|
||||
`ifdef RVFI_DII
|
||||
interface rvfi_dii_server = core.rvfi_dii_server;
|
||||
`endif
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
interface dmi = core.dmi;
|
||||
interface ndm_reset_client = core.ndm_reset_client;
|
||||
`endif
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
interface tv_verifier_info_get = core.tv_verifier_info_get;
|
||||
`endif
|
||||
endmodule
|
||||
return tuple2 (fromDbgReset, ifc);
|
||||
endmodule: mkCoreW_reset
|
||||
|
||||
// ================================================================
|
||||
// 2x3 Fabric for this Core
|
||||
// internal bus for this Core
|
||||
// Masters: CPU DMem, Debug Module System Bus Access, External access
|
||||
|
||||
// ----------------
|
||||
// Fabric port numbers for masters
|
||||
|
||||
Master_Num_2x3 cpu_uncached_master_num = 0;
|
||||
Master_Num_2x3 debug_module_sba_master_num = 1;
|
||||
CoreW_Bus_Master_Num cpu_uncached_master_num = 0;
|
||||
CoreW_Bus_Master_Num debug_module_sba_master_num = 1;
|
||||
CoreW_Bus_Master_Num sub_ifc_master_num = 2;
|
||||
|
||||
// ----------------
|
||||
// Fabric port numbers for slaves
|
||||
|
||||
Slave_Num_2x3 default_slave_num = 0; // for I/O, uncached memory, etc.
|
||||
Slave_Num_2x3 plic_slave_num = 1; // PLIC mem-mapped registers
|
||||
Slave_Num_2x3 llc_slave_num = 2; // Normal cached memory (connects to coherent Last-Level Cache)
|
||||
CoreW_Bus_Slave_Num default_slave_num = 0; // for I/O, uncached memory, etc.
|
||||
CoreW_Bus_Slave_Num plic_slave_num = 1; // PLIC mem-mapped registers
|
||||
CoreW_Bus_Slave_Num llc_slave_num = 2; // Normal cached memory (connects to coherent Last-Level Cache)
|
||||
|
||||
// ================================================================
|
||||
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
// Copyright (c) 2018-2020 Bluespec, Inc. All Rights Reserved.
|
||||
//
|
||||
//-
|
||||
// RVFI_DII + CHERI modifications:
|
||||
// Copyright (c) 2020 Alexandre Joannou
|
||||
// Copyright (c) 2020 Peter Rugg
|
||||
// Copyright (c) 2020 Jonathan Woodruff
|
||||
// All rights reserved.
|
||||
//
|
||||
// This software was developed by SRI International and the University of
|
||||
// Cambridge Computer Laboratory (Department of Computer Science and
|
||||
// Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
|
||||
// DARPA SSITH research programme.
|
||||
//
|
||||
// This work was supported by NCSC programme grant 4212611/RFA 15971 ("SafeBet").
|
||||
//-
|
||||
|
||||
package CoreW_IFC;
|
||||
|
||||
// ================================================================
|
||||
// This package defines the interface of a CoreW module which
|
||||
// contains:
|
||||
// - mkProc (the RISC-V CPU; this a variant of MIT's RISCY-OOO mkProc)
|
||||
// Note: MIT's RISCY-OOO internally has a 'mkCore' and hence this
|
||||
// interface and its module is called 'CoreW', to disambiguate.
|
||||
// - mkFabric_2x3
|
||||
// - mkNear_Mem_IO_AXI4
|
||||
// - mkPLIC_16_CoreNumX2_7
|
||||
// - mkTV_Encode (Tandem-Verification logic, optional: INCLUDE_TANDEM_VERIF)
|
||||
// - mkDebug_Module (RISC-V Debug Module, optional: INCLUDE_GDB_CONTROL)
|
||||
|
||||
// ================================================================
|
||||
// BSV library imports
|
||||
|
||||
import Vector :: *;
|
||||
import GetPut :: *;
|
||||
import ClientServer :: *;
|
||||
|
||||
// ----------------
|
||||
// BSV additional libs
|
||||
import AXI4 :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project imports
|
||||
|
||||
// Main fabric
|
||||
import Fabric_Defs :: *;
|
||||
|
||||
// External interrupt request interface
|
||||
import PLIC :: *;
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
import Debug_Module :: *;
|
||||
`endif
|
||||
|
||||
`ifdef RVFI_DII
|
||||
import ProcTypes :: *;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
import ProcTypes :: *;
|
||||
import Trace_Data2 :: *;
|
||||
import TV_Info :: *;
|
||||
`endif
|
||||
|
||||
// ================================================================
|
||||
// The CoreW interface
|
||||
|
||||
interface CoreW_IFC #(numeric type t_n_interrupt_sources);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Debugging: set core's verbosity
|
||||
|
||||
method Action set_verbosity (Bit #(4) verbosity, Bit #(64) logdelay);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Start
|
||||
|
||||
method Action start (Bool is_running, Bit #(64) tohost_addr, Bit #(64) fromhost_addr);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// AXI4 Fabric interfaces
|
||||
|
||||
// CPU IMem to Fabric master interface
|
||||
interface AXI4_Master #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
|
||||
0, 0, 0, 0, 0) cpu_imem_master;
|
||||
|
||||
// CPU DMem to Fabric master interface
|
||||
interface AXI4_Master #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
|
||||
0, 0, 0, 0, 0) cpu_dmem_master;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// External interrupt sources
|
||||
|
||||
interface Vector #(t_n_interrupt_sources, PLIC_Source_IFC) core_external_interrupt_sources;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Non-maskable interrupt request
|
||||
|
||||
(* always_ready, always_enabled *)
|
||||
method Action nmi_req (Bool set_not_clear);
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// ----------------------------------------------------------------
|
||||
// Optional Debug Module interfaces
|
||||
|
||||
// ----------------
|
||||
// DMI (Debug Module Interface) facing remote debugger
|
||||
|
||||
interface DMI dmi;
|
||||
|
||||
// ----------------
|
||||
// Facing Platform
|
||||
// Non-Debug-Module Reset (reset all except DM)
|
||||
|
||||
interface Client #(Bool, Bool) ndm_reset_client;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
// ----------------------------------------------------------------
|
||||
// Optional Tandem Verifier interface output tuples (n,vb),
|
||||
// where 'vb' is a vector of bytes
|
||||
// with relevant bytes in locations [0]..[n-1]
|
||||
|
||||
interface Get #(Info_CPU_to_Verifier) tv_verifier_info_get;
|
||||
`endif
|
||||
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
// The Synthesizable CoreW interface (same with Synth AXI)
|
||||
|
||||
interface CoreW_IFC_Synth #(numeric type t_n_interrupt_sources);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Debugging: set core's verbosity
|
||||
|
||||
method Action set_verbosity (Bit #(4) verbosity, Bit #(64) logdelay);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Start
|
||||
|
||||
method Action start (Bool is_running, Bit #(64) tohost_addr, Bit #(64) fromhost_addr);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// AXI4 Fabric interfaces
|
||||
|
||||
// CPU IMem to Fabric master interface
|
||||
interface AXI4_Master_Sig #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
|
||||
0, 0, 0, 0, 0) cpu_imem_master;
|
||||
|
||||
// CPU DMem to Fabric master interface
|
||||
interface AXI4_Master_Sig #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
|
||||
0, 0, 0, 0, 0) cpu_dmem_master;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// External interrupt sources
|
||||
|
||||
interface Vector #(t_n_interrupt_sources, PLIC_Source_IFC) core_external_interrupt_sources;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Non-maskable interrupt request
|
||||
|
||||
(* always_ready, always_enabled *)
|
||||
method Action nmi_req (Bool set_not_clear);
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// ----------------------------------------------------------------
|
||||
// Optional Debug Module interfaces
|
||||
|
||||
// ----------------
|
||||
// DMI (Debug Module Interface) facing remote debugger
|
||||
|
||||
interface DMI dmi;
|
||||
|
||||
// ----------------
|
||||
// Facing Platform
|
||||
// Non-Debug-Module Reset (reset all except DM)
|
||||
|
||||
interface Client #(Bool, Bool) ndm_reset_client;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
// ----------------------------------------------------------------
|
||||
// Optional Tandem Verifier interface output tuples (n,vb),
|
||||
// where 'vb' is a vector of bytes
|
||||
// with relevant bytes in locations [0]..[n-1]
|
||||
|
||||
interface Get #(Info_CPU_to_Verifier) tv_verifier_info_get;
|
||||
`endif
|
||||
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
|
||||
endpackage
|
||||
@@ -35,17 +35,17 @@ import ISA_Decls_CHERI :: *;
|
||||
// ================================================================
|
||||
// Core local Fabric parameters
|
||||
|
||||
typedef 2 Num_Masters_2x3;
|
||||
typedef 3 Num_Slaves_2x3;
|
||||
typedef 3 CoreW_Bus_Num_Masters;
|
||||
typedef 3 CoreW_Bus_Num_Slaves;
|
||||
|
||||
typedef Bit#(TLog #(Num_Masters_2x3)) Master_Num_2x3;
|
||||
typedef Bit#(TLog #(Num_Slaves_2x3)) Slave_Num_2x3;
|
||||
typedef Bit#(TLog #(CoreW_Bus_Num_Masters)) CoreW_Bus_Master_Num;
|
||||
typedef Bit#(TLog #(CoreW_Bus_Num_Slaves)) CoreW_Bus_Slave_Num;
|
||||
|
||||
// ----------------
|
||||
// Width of fabric 'Id' buses
|
||||
typedef 4 Wd_MId_2x3;
|
||||
typedef TAdd#(Wd_MId_2x3, TLog#(Num_Masters_2x3)) Wd_SId_2x3;
|
||||
typedef Wd_SId_2x3 Wd_MId;
|
||||
typedef 4 Wd_CoreW_Bus_MId;
|
||||
typedef TAdd#(Wd_CoreW_Bus_MId, TLog#(CoreW_Bus_Num_Masters)) Wd_CoreW_Bus_SId;
|
||||
typedef Wd_CoreW_Bus_SId Wd_MId;
|
||||
|
||||
// ----------------
|
||||
// Width of fabric 'addr' buses
|
||||
@@ -104,7 +104,7 @@ Integer zlsbs_aligned_fabric_addr = valueOf (ZLSBs_Aligned_Fabric_Addr);
|
||||
|
||||
// ================================================================
|
||||
// AXI4 defaults for this project
|
||||
Bit#(Wd_MId_2x3) fabric_2x3_default_mid = 0;
|
||||
Bit#(Wd_CoreW_Bus_MId) fabric_corew_bus_default_mid = 0;
|
||||
Bit#(Wd_MId) fabric_default_mid = 0;
|
||||
AXI4_Burst fabric_default_burst = INCR;
|
||||
AXI4_Lock fabric_default_lock = NORMAL;
|
||||
|
||||
@@ -54,9 +54,9 @@ interface DM_System_Bus_IFC;
|
||||
|
||||
// ----------------
|
||||
// Facing System
|
||||
interface AXI4_Master #(Wd_MId_2x3, Wd_Addr, Wd_Data_Periph,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) master;
|
||||
interface AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User) master;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
@@ -197,8 +197,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// Interface to memory fabric
|
||||
let master_xactor <- mkAXI4ShimFF;
|
||||
|
||||
let axiShim <- mkAXI4ShimFF;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// System Bus state
|
||||
@@ -283,7 +282,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
function Action fa_fabric_send_read_req (Bit #(64) addr64);
|
||||
action
|
||||
Fabric_Addr fabric_addr = truncate (addr64);
|
||||
let rda = AXI4_ARFlit {arid: fabric_2x3_default_mid,
|
||||
let rda = AXI4_ARFlit {arid: fabric_corew_bus_default_mid,
|
||||
araddr: fabric_addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: fn_DM_sbaccess_to_AXI4_Size (rg_sbcs_sbaccess),
|
||||
@@ -294,7 +293,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_aruser};
|
||||
master_xactor.slave.ar.put(rda);
|
||||
axiShim.slave.ar.put(rda);
|
||||
|
||||
// Save read-address for byte-lane extraction from later response
|
||||
// (since rg_sbaddress may be incremented by then).
|
||||
@@ -318,13 +317,13 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
.fabric_data,
|
||||
.fabric_strb,
|
||||
.fabric_size} = fn_to_fabric_write_fields (rg_sbcs_sbaccess, sbaddress, data64);
|
||||
|
||||
|
||||
// fabric_addr is always fabric-data-width aligned
|
||||
// fabric_data is properly lane-adjusted
|
||||
// fabric_strb identifies the lanes to be written
|
||||
// awsize is always the fabric width
|
||||
|
||||
let wra = AXI4_AWFlit {awid: fabric_2x3_default_mid,
|
||||
let wra = AXI4_AWFlit {awid: fabric_corew_bus_default_mid,
|
||||
awaddr: fabric_addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: fabric_size,
|
||||
@@ -335,13 +334,13 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_awuser};
|
||||
master_xactor.slave.aw.put(wra);
|
||||
axiShim.slave.aw.put(wra);
|
||||
|
||||
let wrd = AXI4_WFlit {wdata: fabric_data,
|
||||
wstrb: fabric_strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_wuser};
|
||||
master_xactor.slave.w.put(wrd);
|
||||
axiShim.slave.w.put(wrd);
|
||||
|
||||
if (verbosity != 0) begin
|
||||
$display (" DM_System_Bus.fa_fabric_send_write_req:");
|
||||
@@ -507,7 +506,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
(* descending_urgency = "rl_sb_read_finish, write" *)
|
||||
rule rl_sb_read_finish ( (rg_sb_state == SB_READ_FINISH)
|
||||
&& (rg_sbcs_sberror == DM_SBERROR_NONE));
|
||||
let rdr <- get(master_xactor.slave.r);
|
||||
let rdr <- get(axiShim.slave.r);
|
||||
if (verbosity != 0)
|
||||
$display ("DM_System_Bus.rule_sb_read_finish: rdr = ", fshow (rdr));
|
||||
|
||||
@@ -588,7 +587,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
// Consume write-responses
|
||||
|
||||
rule rl_sb_write_response;
|
||||
let wrr <- get(master_xactor.slave.b);
|
||||
let wrr <- get(axiShim.slave.b);
|
||||
if (wrr.bresp != OKAY)
|
||||
rg_sbcs_sberror <= DM_SBERROR_OTHER;
|
||||
endrule
|
||||
@@ -597,7 +596,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
// INTERFACE
|
||||
|
||||
method Action reset;
|
||||
master_xactor.clear;
|
||||
axiShim.clear;
|
||||
|
||||
rg_sb_state <= SB_NOTBUSY;
|
||||
|
||||
@@ -678,7 +677,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
|
||||
|
||||
// ----------------
|
||||
// Facing System
|
||||
interface master = master_xactor.master;
|
||||
interface master = axiShim.master;
|
||||
endmodule
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -136,9 +136,9 @@ interface Debug_Module_IFC;
|
||||
interface Client #(Bool, Bool) ndm_reset_client;
|
||||
|
||||
// Read/Write RISC-V memory
|
||||
interface AXI4_Master #(Wd_MId_2x3, Wd_Addr, Wd_Data_Periph,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) master;
|
||||
interface AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User) master;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -98,8 +98,8 @@ interface PLIC_IFC #(numeric type t_n_external_sources,
|
||||
method Action set_addr_map (Bit #(64) addr_base, Bit #(64) addr_lim);
|
||||
|
||||
// Memory-mapped access
|
||||
interface AXI4_Slave #( Wd_SId_2x3, Wd_Addr, Wd_Data, 0, 0, 0, 0, 0)
|
||||
axi4_slave;
|
||||
interface AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data
|
||||
, 0, 0, 0, 0, 0) axi4_slave;
|
||||
|
||||
// sources
|
||||
interface Vector #(t_n_external_sources, PLIC_Source_IFC) v_sources;
|
||||
|
||||
@@ -28,6 +28,9 @@ interface ResetGuard;
|
||||
endinterface
|
||||
|
||||
`ifdef BSIM
|
||||
`define NO_XILINX
|
||||
`endif
|
||||
`ifdef NO_XILINX
|
||||
module mkResetGuard(ResetGuard);
|
||||
Reg#(Bool) ready <- mkReg(False);
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
import Clocks::*;
|
||||
import FIFOF::*;
|
||||
import Assert::*;
|
||||
`ifdef USE_CONNECTAL_BRAM_SYNC_FIFO
|
||||
import ConnectalBramFifo::*;
|
||||
`endif
|
||||
import BRAMFIFO::*;
|
||||
import XilinxSyncFifo::*;
|
||||
import ResetGuard::*;
|
||||
|
||||
@@ -2,6 +2,9 @@ import FIFOF::*;
|
||||
import FIFO::*;
|
||||
|
||||
import WaitAutoReset::*;
|
||||
import Divide::*;
|
||||
import ClientServer::*;
|
||||
import GetPut::*;
|
||||
|
||||
export XilinxIntDiv(..);
|
||||
export mkXilinxIntDiv;
|
||||
@@ -70,22 +73,23 @@ module mkIntDivUnsignedSim(IntDivUnsignedImport);
|
||||
FIFO#(Bit#(64)) divisorQ <- mkFIFO;
|
||||
FIFOF#(Tuple2#(Bit#(128), IntDivUser)) respQ <- mkSizedFIFOF(2);
|
||||
|
||||
FIFO#(IntDivUser) userFF <- mkFIFO;
|
||||
Server#(Tuple2#(UInt#(128),UInt#(64)),Tuple2#(UInt#(64),UInt#(64)))
|
||||
nonpipediv <- mkNonPipelinedDivider (4);
|
||||
|
||||
rule compute;
|
||||
dividendQ.deq;
|
||||
divisorQ.deq;
|
||||
let {dividend, user} = dividendQ.first;
|
||||
let divisor = divisorQ.first;
|
||||
nonpipediv.request.put(tuple2(unpack(zeroExtend(dividend)), unpack(divisor)));
|
||||
userFF.enq(user);
|
||||
endrule
|
||||
|
||||
// Be careful to avoid divide-by-zero in bluesim's C++, which turns
|
||||
// res = cond ? exp1 : exp2
|
||||
// into
|
||||
// tmp1 = exp1; tmp2 = exp2; res = cond ? tmp1 : tmp2
|
||||
// so we must give a fake non-zero input even if it looks unused.
|
||||
UInt#(64) a = unpack(dividend);
|
||||
UInt#(64) b = divisor == 0 ? 1 : unpack(divisor);
|
||||
Bit#(64) q = divisor == 0 ? maxBound : pack(a / b);
|
||||
Bit#(64) r = divisor == 0 ? dividend : pack(a % b);
|
||||
respQ.enq(tuple2({q, r}, user));
|
||||
rule getResult;
|
||||
let {qq, rr} <- nonpipediv.response.get;
|
||||
let user <- toGet(userFF).get;
|
||||
respQ.enq(tuple2({pack(qq), pack(rr)}, user));
|
||||
endrule
|
||||
|
||||
method Action enqDividend(Bit#(64) dividend, IntDivUser user);
|
||||
@@ -124,6 +128,9 @@ module mkXilinxIntDiv(XilinxIntDiv#(tagT)) provisos (
|
||||
Bits#(tagT, tagSz), Add#(tagSz, a__, 8)
|
||||
);
|
||||
`ifdef BSIM
|
||||
`define NO_XILINX
|
||||
`endif
|
||||
`ifdef NO_XILINX
|
||||
IntDivUnsignedImport divIfc <- mkIntDivUnsignedSim;
|
||||
`else
|
||||
IntDivUnsignedImport divIfc <- mkIntDivUnsignedImport;
|
||||
|
||||
@@ -110,6 +110,9 @@ module mkXilinxIntMul(XilinxIntMul#(tagT)) provisos(
|
||||
// different multilpliers: WaitAutoReset is not needed, since mul is a
|
||||
// pipeline with fixed latency
|
||||
`ifdef BSIM
|
||||
`define NO_XILINX
|
||||
`endif
|
||||
`ifdef NO_XILINX
|
||||
IntMulImport mulSigned <- mkIntMulSim(Signed);
|
||||
IntMulImport mulUnsigned <- mkIntMulSim(Unsigned);
|
||||
IntMulImport mulSignedUnsigned <- mkIntMulSim(SignedUnsigned);
|
||||
|
||||
@@ -79,10 +79,18 @@
|
||||
`define LOG_L2_TLB_4KB_WAYS 2 // L2 4KB TLB log ways (4 ways)
|
||||
|
||||
// FMA bookkeeping FIFO: add 1 to allow simultaneous enq/deq
|
||||
`ifdef USE_XILINX_FPU
|
||||
`define BOOKKEEPING_FP_FMA_SIZE TAdd#(`XILINX_FP_FMA_LATENCY, 1)
|
||||
`else
|
||||
`define BOOKKEEPING_FP_FMA_SIZE 4
|
||||
`endif
|
||||
// INT MUL bookkeeping FIFO: add 1 to allow simultaneous enq/deq, another 1
|
||||
// because of internal flow control in MUL unit
|
||||
`ifdef USE_XILINX_FPU
|
||||
`define BOOKKEEPING_INT_MUL_SIZE TAdd#(`XILINX_INT_MUL_LATENCY, 2)
|
||||
`else
|
||||
`define BOOKKEEPING_INT_MUL_SIZE 4
|
||||
`endif
|
||||
|
||||
// non-blocking DTLB
|
||||
`define DTLB_REQ_NUM 4
|
||||
|
||||
@@ -95,7 +95,8 @@ module mkDoubleDiv(Server#(Tuple3#(Double, Double, FpuRoundMode), Tuple2#(Double
|
||||
`ifdef USE_XILINX_FPU
|
||||
let fpu <- mkXilinxFpDiv;
|
||||
`else
|
||||
let int_div <- mkNonPipelinedDivider(3); // [sizhuo] size in RVFpu: 2
|
||||
//let int_div <- mkDivider(1); // [sizhuo] size in RVFpu: 2
|
||||
let int_div <- mkNonPipelinedDivider(3);
|
||||
let fpu <- mkFloatingPointDivider(int_div);
|
||||
`endif
|
||||
return fpu;
|
||||
|
||||
@@ -127,15 +127,14 @@ endfunction
|
||||
|
||||
// ================================================================
|
||||
|
||||
module mkLLCDmaConnect #(
|
||||
DmaServer#(LLCDmaReqId) llc,
|
||||
// MemLoaderMemClient memLoader, // REPLACED BY AXI4_Slave_interface
|
||||
Vector#(CoreNum, TlbMemClient) tlb
|
||||
)(AXI4_Slave #(Wd_SId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User)) provisos (
|
||||
Alias#(dmaRqT, DmaRq#(LLCDmaReqId))
|
||||
);
|
||||
module mkLLCDmaConnect #( DmaServer#(LLCDmaReqId) llc
|
||||
// REPLACED BY AXI4_Slave_interface
|
||||
//, MemLoaderMemClient memLoader
|
||||
, Vector#(CoreNum, TlbMemClient) tlb )
|
||||
(AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data
|
||||
, Wd_AW_User, Wd_W_User, Wd_B_User
|
||||
, Wd_AR_User, Wd_R_User))
|
||||
provisos (Alias #(dmaRqT, DmaRq #(LLCDmaReqId)));
|
||||
Bool verbose = False;
|
||||
|
||||
Integer verbosity = 0;
|
||||
|
||||
@@ -16,7 +16,7 @@ compile: compile_sim compile_synth
|
||||
|
||||
# ================================================================
|
||||
|
||||
REPO ?= ..
|
||||
REPO ?= $(CURDIR)/..
|
||||
ARCH ?= RV64ACDFIMSUxCHERI
|
||||
|
||||
# ================================================================
|
||||
@@ -29,7 +29,7 @@ BSC_COMPILATION_FLAGS += \
|
||||
-D ISA_I -D ISA_M -D ISA_A -D ISA_F -D ISA_D -D ISA_FD_DIV -D ISA_C \
|
||||
-D CheriBusBytes=8 \
|
||||
-D CheriMasterIDWidth=1 \
|
||||
-D CheriTransactionIDWidth=5 \
|
||||
-D CheriTransactionIDWidth=6 \
|
||||
-D PERFORMANCE_MONITORING \
|
||||
-D SHIFT_BARREL \
|
||||
-D MULT_SERIAL \
|
||||
@@ -62,33 +62,32 @@ CORE_NUM = 2
|
||||
|
||||
include $(REPO)/builds/Resources/Include_RISCY_Config.mk
|
||||
|
||||
# ================================================================
|
||||
# Path to RISCY-OOO sources
|
||||
|
||||
RISCY_HOME ?= ../src_Core/RISCY_OOO
|
||||
|
||||
RISCY_DIRS = $(RISCY_HOME)/procs/RV64G_OOO:$(RISCY_HOME)/procs/lib:$(RISCY_HOME)/coherence/src:$(RISCY_HOME)/fpgautils/lib
|
||||
|
||||
CONNECTAL_DIRS = $(RISCY_HOME)/connectal/bsv:$(RISCY_HOME)/connectal/tests/spi:$(RISCY_HOME)/connectal/lib/bsv
|
||||
|
||||
CHERI_DIRS = $(RISCY_HOME)/../../libs/cheri-cap-lib
|
||||
|
||||
# ALL_RISCY_DIRS = $(RISCY_DIRS)
|
||||
ALL_RISCY_DIRS = $(RISCY_DIRS):$(CONNECTAL_DIRS):$(CHERI_DIRS)
|
||||
|
||||
# ================================================================
|
||||
# Search path for bsc for .bsv files
|
||||
COREDIR ?= $(REPO)
|
||||
COREW_DIRS = $(CURDIR)/src_BSV:$(COREDIR)/src_Core/Core:$(COREDIR)/src_Core/CPU:$(COREDIR)/src_Core/ISA:$(COREDIR)/src_Core/PLIC:$(COREDIR)/src_Core/Debug_Module:$(COREDIR)/src_Core/BSV_Additional_Libs:$(COREDIR)/src_Core/RISCY_OOO/procs/RV64G_OOO:$(COREDIR)/src_Core/RISCY_OOO/procs/lib:$(COREDIR)/src_Core/RISCY_OOO/coherence/src:$(COREDIR)/src_Core/RISCY_OOO/fpgautils/lib
|
||||
WINDCOREIFCDIR ?= $(COREDIR)/libs/WindCoreInterface
|
||||
CHERICAPLIBDIR ?= $(COREDIR)/libs/cheri-cap-lib
|
||||
TAGCONTROLLERDIR ?= $(COREDIR)/libs/TagController
|
||||
RISCVHPMEVENTSDIR ?= $(COREDIR)/libs/RISCV_HPM_Events
|
||||
TAGCONTROLLER_DIRS = $(TAGCONTROLLERDIR)/TagController:$(TAGCONTROLLERDIR)/TagController/CacheCore
|
||||
BLUESTUFFDIR ?= $(COREDIR)/libs/BlueStuff
|
||||
BLUEAXI4DIR = $(BLUESTUFFDIR)/BlueAXI4
|
||||
BLUEAXI4DIRS = $(BLUEAXI4DIR):$(BLUEAXI4DIR)/AXI4:$(BLUEAXI4DIR)/AXI4Lite:$(BLUEAXI4DIR)/AXI4Stream:$(BLUEAXI4DIR)/BlueUnixBridges
|
||||
BLUEUNIXBRIDGESDIR = $(BLUEAXI4DIR)/BlueUnixBridges
|
||||
BLUEBASICSDIR = $(BLUESTUFFDIR)/BlueBasics
|
||||
BLUEUTILSDIR = $(BLUESTUFFDIR)/BlueUtils
|
||||
BLUESTUFF_DIRS = $(BLUESTUFFDIR):$(BLUEAXI4DIRS):$(BLUEBASICSDIR):$(BLUEUTILSDIR):$(BLUESTUFFDIR)/Stratix10ChipID
|
||||
|
||||
CONTRIB_DIRS = %/Libraries/Bus
|
||||
CORE_DIRS = $(REPO)/src_Core/CPU:$(REPO)/src_Core/ISA:$(REPO)/src_Core/Core:$(REPO)/src_Core/PLIC:$(REPO)/src_Core/Debug_Module:$(REPO)/src_Core/BSV_Additional_Libs
|
||||
|
||||
BLUESTUFF_DIRS = $(REPO)/libs/BlueStuff:$(REPO)/libs/BlueStuff/AXI:$(REPO)/libs/BlueStuff/BlueUtils:$(REPO)/libs/BlueStuff/BlueBasics
|
||||
|
||||
TAGCONTROLLER_DIRS = $(REPO)/libs/TagController/TagController:$(REPO)/libs/TagController/TagController/CacheCore
|
||||
|
||||
RISCV_HPM_Events_DIR = $(REPO)/libs/RISCV_HPM_Events
|
||||
|
||||
BSC_PATH = -p $(CONTRIB_DIRS):$(ALL_RISCY_DIRS):$(CORE_DIRS):src_BSV:$(BLUESTUFF_DIRS):$(TAGCONTROLLER_DIRS):$(RISCV_HPM_Events_DIR):+
|
||||
# search path for bsc imports
|
||||
ifdef BSC_CONTRIB_DIR
|
||||
BSC_CONTRIB_LIB_DIR = $(BSC_CONTRIB_DIR)/lib/Libraries
|
||||
else
|
||||
BSC_CONTRIB_LIB_DIR = %/Libraries
|
||||
endif
|
||||
BSC_CONTRIB_DIRS = $(BSC_CONTRIB_LIB_DIR)/Bus
|
||||
BSVPATH = +:$(BSC_CONTRIB_DIRS):$(WINDCOREIFCDIR):$(RISCVHPMEVENTSDIR):$(CHERICAPLIBDIR):$(TAGCONTROLLER_DIRS):$(COREW_DIRS):$(BLUESTUFF_DIRS)
|
||||
BSC_PATH = -p $(BSVPATH)
|
||||
|
||||
# ----------------
|
||||
# Top-level file and module
|
||||
@@ -122,17 +121,17 @@ src_BSV/TagTableStructure.bsv: $(REPO)/libs/TagController/tagsparams.py
|
||||
|
||||
.PHONY: generate_hpm_vector
|
||||
generate_hpm_vector: GenerateHPMVector.bsv
|
||||
GenerateHPMVector.bsv: $(RISCV_HPM_Events_DIR)/parse_counters.py
|
||||
GenerateHPMVector.bsv: $(RISCVHPMEVENTSDIR)/parse_counters.py
|
||||
@echo "INFO: Re-generating GenerateHPMVector bluespec file"
|
||||
$^ $(RISCV_HPM_Events_DIR)/counters.yaml -m ProcTypes -b $@
|
||||
$^ $(RISCVHPMEVENTSDIR)/counters.yaml -m ProcTypes -b $@
|
||||
@echo "INFO: Re-generated GenerateHPMVector bluespec file"
|
||||
|
||||
|
||||
.PHONY: stat_counters
|
||||
stat_counters: StatCounters.bsv
|
||||
StatCounters.bsv: $(RISCV_HPM_Events_DIR)/parse_counters.py
|
||||
StatCounters.bsv: $(RISCVHPMEVENTSDIR)/parse_counters.py
|
||||
@echo "INFO: Re-generating HPM events struct bluepsec file"
|
||||
$^ $(RISCV_HPM_Events_DIR)/counters.yaml -m ProcTypes -s $@
|
||||
$^ $(RISCVHPMEVENTSDIR)/counters.yaml -m ProcTypes -s $@
|
||||
@echo "INFO: Re-generated HPM events struct bluespec file"
|
||||
compile_sim: tagsparams stat_counters generate_hpm_vector
|
||||
compile_synth: tagsparams stat_counters generate_hpm_vector
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
package Giraffe_IFC;
|
||||
|
||||
import AXI4 ::*;
|
||||
import Bus ::*;
|
||||
import Bus ::*;
|
||||
import BlueAXI4 ::*;
|
||||
import Connectable ::*;
|
||||
|
||||
`include "Giraffe.defines"
|
||||
|
||||
@@ -32,7 +32,9 @@ import Vector :: *;
|
||||
|
||||
import GetPut_Aux :: *;
|
||||
import Routable :: *;
|
||||
import AXI4 :: *;
|
||||
import BlueAXI4 :: *;
|
||||
import SourceSink :: *;
|
||||
import WindCoreInterface :: *;
|
||||
import Semi_FIFOF :: *;
|
||||
import Cur_Cycle :: *;
|
||||
|
||||
@@ -44,7 +46,6 @@ import Fabric_Defs :: *;
|
||||
import PowerOnReset :: *;
|
||||
|
||||
// The basic core
|
||||
import CoreW_IFC :: *;
|
||||
import CoreW :: *;
|
||||
|
||||
// External interrupt request interface
|
||||
@@ -160,67 +161,12 @@ module mkP3_Core (P3_Core_IFC);
|
||||
// ================================================================
|
||||
// CoreW
|
||||
// CPU + Near_Mem_IO (CLINT) + PLIC + Debug module (optional) + TV (optional)
|
||||
CoreW_IFC #(N_External_Interrupt_Sources) corew <- mkCoreW (dm_power_on_reset,
|
||||
reset_by ndm_reset);
|
||||
|
||||
// ================================================================
|
||||
// Tie-offs (not used in SSITH GFE)
|
||||
|
||||
// Set core's verbosity
|
||||
rule rl_never (False);
|
||||
corew.set_verbosity (?, ?);
|
||||
endrule
|
||||
|
||||
// Tie-offs
|
||||
rule rl_always (True);
|
||||
// Non-maskable interrupt request.
|
||||
corew.nmi_req (False);
|
||||
endrule
|
||||
Tuple2 #( PulseWire
|
||||
, CoreW_IFC #(N_External_Interrupt_Sources)) both
|
||||
<- mkCoreW_reset (dm_power_on_reset, reset_by ndm_reset);
|
||||
match {.otherRst, .corew} = both;
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// ================================================================
|
||||
// NDM reset (reset for non-DebugModule)
|
||||
|
||||
Reg #(Bit #(8)) rg_ndm_reset_delay <- mkReg (0);
|
||||
Reg #(Bool) rg_running <- mkRegU;
|
||||
|
||||
// Get an NDM-reset request from the Debug Module, assert ndm-reset,
|
||||
// and then wait for a suitable delay.
|
||||
rule rl_ndm_reset (rg_ndm_reset_delay == 0);
|
||||
let x <- corew.ndm_reset_client.request.get;
|
||||
rg_running <= x;
|
||||
ndm_reset_controller.assertReset;
|
||||
rg_ndm_reset_delay <= fromInteger (ndm_reset_duration + 100); // NOTE: heuristic
|
||||
|
||||
$display ("%0d: %m.rl_ndm_reset: asserting NDM reset (for non-DebugModule) for %0d cycles",
|
||||
cur_cycle, ndm_reset_duration);
|
||||
endrule
|
||||
|
||||
// Wait for suitable delay, then send ack response to Debug Module for NDM-reset request
|
||||
rule rl_ndm_reset_wait (rg_ndm_reset_delay != 0);
|
||||
if (rg_ndm_reset_delay == 1) begin
|
||||
Bool is_running = rg_running;
|
||||
// Restart the corew
|
||||
corew.start (rg_running, 0, 0);
|
||||
corew.ndm_reset_client.response.put (is_running);
|
||||
$display ("%0d: %m.rl_ndm_reset_wait: sent NDM reset ack (for non-DebugModule) to Debug Module",
|
||||
cur_cycle);
|
||||
end
|
||||
rg_ndm_reset_delay <= rg_ndm_reset_delay - 1;
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
// Start the corew a suitable time after a PoR
|
||||
UInt#(8) initial_wait = 100; // heuristic -- better to wait till "all out of reset" received from corew
|
||||
Reg #(UInt#(8)) rg_corew_start_after_por <- mkReg(initial_wait);
|
||||
rule rl_step_0 (rg_corew_start_after_por != 0);
|
||||
let n = rg_corew_start_after_por - 1;
|
||||
rg_corew_start_after_por <= n;
|
||||
if (n==0) corew.start (True, 0, 0); // initial start leaves proc running
|
||||
endrule
|
||||
// ================================================================
|
||||
|
||||
|
||||
|
||||
// ================================================================
|
||||
// Instantiate JTAG TAP controller,
|
||||
@@ -261,23 +207,40 @@ module mkP3_Core (P3_Core_IFC);
|
||||
w_dmi_rsp_response <= response;
|
||||
endrule
|
||||
|
||||
(* preempts = "rl_dmi_req_cpu, rl_dmi_rsp_cpu" *)
|
||||
(* preempts = "rl_dmi_req_cpu, rl_dmi_read_rsp_cpu" *)
|
||||
rule rl_dmi_req_cpu;
|
||||
match {.addr, .data, .op} = bus_dmi_req.out.first;
|
||||
bus_dmi_req.out.deq;
|
||||
case (op)
|
||||
1: corew.dmi.read_addr(addr);
|
||||
1: corew.debug_subordinate.ar.put(AXI4Lite_ARFlit {
|
||||
araddr: zeroExtend (addr) << 2
|
||||
, arprot: ?
|
||||
, aruser: ?
|
||||
});
|
||||
2: begin
|
||||
corew.dmi.write(addr, data);
|
||||
corew.debug_subordinate.aw.put(AXI4Lite_AWFlit {
|
||||
awaddr: zeroExtend (addr) << 2
|
||||
, awprot: ?
|
||||
, awuser: ?
|
||||
});
|
||||
corew.debug_subordinate.w.put(AXI4Lite_WFlit {
|
||||
wdata: data
|
||||
, wstrb: ~0
|
||||
, wuser: ?
|
||||
});
|
||||
bus_dmi_rsp.in.enq(tuple2(?, 0));
|
||||
end
|
||||
default: bus_dmi_rsp.in.enq(tuple2(?, 2));
|
||||
endcase
|
||||
endrule
|
||||
|
||||
rule rl_dmi_rsp_cpu;
|
||||
let data <- corew.dmi.read_data;
|
||||
bus_dmi_rsp.in.enq(tuple2(data, 0));
|
||||
rule rl_dmi_read_rsp_cpu;
|
||||
let rflit <- get (corew.debug_subordinate.r);
|
||||
bus_dmi_rsp.in.enq(tuple2(rflit.rdata, 0));
|
||||
endrule
|
||||
|
||||
rule rl_dmi_write_rsp_drain;
|
||||
corew.debug_subordinate.b.drop;
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
@@ -293,8 +256,8 @@ module mkP3_Core (P3_Core_IFC);
|
||||
|
||||
// ================================================================
|
||||
// INTERFACE
|
||||
let master0_sig <- toAXI4_Master_Sig(corew.cpu_imem_master);
|
||||
let master1_sig <- toAXI4_Master_Sig(corew.cpu_dmem_master);
|
||||
let master0_sig <- toAXI4_Master_Sig (corew.manager_0);
|
||||
let master1_sig <- toAXI4_Master_Sig (corew.manager_1);
|
||||
// ----------------------------------------------------------------
|
||||
// Core CPU interfaces
|
||||
|
||||
@@ -306,10 +269,8 @@ module mkP3_Core (P3_Core_IFC);
|
||||
|
||||
// External interrupts
|
||||
method Action interrupt_reqs (Bit #(N_External_Interrupt_Sources) reqs);
|
||||
for (Integer j = 0; j < valueOf (N_External_Interrupt_Sources); j = j + 1) begin
|
||||
Bool req_j = unpack (reqs [j]);
|
||||
corew.core_external_interrupt_sources [j].m_interrupt_req (req_j);
|
||||
end
|
||||
for (Integer j = 0; j < valueOf (N_External_Interrupt_Sources); j = j + 1)
|
||||
corew.irq[j].put (unpack (reqs [j]));
|
||||
endmethod
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
|
||||
@@ -2236,11 +2236,6 @@
|
||||
<spirit:fileType>verilogSource</spirit:fileType>
|
||||
<spirit:userFileType>IMPORTED_FILE</spirit:userFileType>
|
||||
</spirit:file>
|
||||
<spirit:file>
|
||||
<spirit:name>../Verilog_RTL/mkCoreW.v</spirit:name>
|
||||
<spirit:fileType>verilogSource</spirit:fileType>
|
||||
<spirit:userFileType>IMPORTED_FILE</spirit:userFileType>
|
||||
</spirit:file>
|
||||
<spirit:file>
|
||||
<spirit:name>../Verilog_RTL/mkTagController.v</spirit:name>
|
||||
<spirit:fileType>verilogSource</spirit:fileType>
|
||||
|
||||
@@ -47,6 +47,7 @@ import Cur_Cycle :: *;
|
||||
import GetPut_Aux :: *;
|
||||
import Routable :: *;
|
||||
import AXI4 :: *;
|
||||
import AXI4Lite :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project imports
|
||||
@@ -56,9 +57,9 @@ import SoC_Map :: *;
|
||||
|
||||
// SoC components (CPU, mem, and IPs)
|
||||
|
||||
import CoreW_IFC :: *;
|
||||
import WindCoreInterface :: *;
|
||||
import CoreW :: *;
|
||||
import PLIC :: *; // For interface to PLIC interrupt sources, in CoreW_IFC
|
||||
import PLIC :: *;
|
||||
|
||||
import Boot_ROM :: *;
|
||||
import Mem_Controller :: *;
|
||||
@@ -90,15 +91,9 @@ import Debug_Module :: *;
|
||||
// The outermost interface of the SoC
|
||||
|
||||
interface SoC_Top_IFC;
|
||||
// Set core's verbosity
|
||||
method Action set_verbosity (Bit #(4) verbosity, Bit #(64) logdelay);
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// DMI (Debug Module Interface) facing remote debugger
|
||||
interface DMI dmi;
|
||||
|
||||
// Non-Debug-Module Reset (reset all except DM)
|
||||
interface Client #(Bool, Bool) ndm_reset_client;
|
||||
interface AXI4Lite_Slave #(7, 32, 0, 0, 0, 0, 0) debug_subordinate;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
@@ -148,7 +143,7 @@ module mkSoC_Top #(Reset dm_power_on_reset)
|
||||
// Core: CPU + Near_Mem_IO (CLINT) + PLIC + Debug module (optional) + TV (optional)
|
||||
// The Debug Module has its own RST_N reset signal (which comes
|
||||
// from outside this module as a paramter)
|
||||
CoreW_IFC #(N_External_Interrupt_Sources) corew <- mkCoreW (dm_power_on_reset);
|
||||
CoreW_IFC #(N_External_Interrupt_Sources) corew <- mkCoreW;
|
||||
|
||||
// SoC Boot ROM
|
||||
Boot_ROM_IFC boot_rom <- mkBoot_ROM;
|
||||
@@ -179,10 +174,10 @@ module mkSoC_Top #(Reset dm_power_on_reset)
|
||||
master_vector = newVector;
|
||||
|
||||
// CPU IMem master to fabric
|
||||
master_vector[imem_master_num] = corew.cpu_imem_master;
|
||||
master_vector[imem_master_num] = corew.manager_0;
|
||||
|
||||
// CPU DMem master to fabric
|
||||
master_vector[dmem_master_num] = corew.cpu_dmem_master;
|
||||
master_vector[dmem_master_num] = corew.manager_1;
|
||||
|
||||
// ----------------
|
||||
// SoC fabric slave connections
|
||||
@@ -232,21 +227,21 @@ module mkSoC_Top #(Reset dm_power_on_reset)
|
||||
Bool intr = uart0.intr;
|
||||
|
||||
// UART
|
||||
corew.core_external_interrupt_sources [irq_num_uart0].m_interrupt_req (intr);
|
||||
corew.irq [irq_num_uart0].put (intr);
|
||||
Integer last_irq_num = irq_num_uart0;
|
||||
|
||||
`ifdef INCLUDE_ACCEL0
|
||||
Bool intr_accel0 = accel0.interrupt_req;
|
||||
corew.core_external_interrupt_sources [irq_num_accel0].m_interrupt_req (intr_accel0);
|
||||
corew.irq [irq_num_accel0].put (intr_accel0);
|
||||
last_irq_num = irq_num_accel0;
|
||||
`endif
|
||||
|
||||
// Tie off remaining interrupt request lines (1..N)
|
||||
for (Integer j = last_irq_num + 1; j < valueOf (N_External_Interrupt_Sources); j = j + 1)
|
||||
corew.core_external_interrupt_sources [j].m_interrupt_req (False);
|
||||
corew.irq [j].put (False);
|
||||
|
||||
// Non-maskable interrupt request. [Tie-off; TODO: connect to genuine sources]
|
||||
corew.nmi_req (False);
|
||||
corew.nmirq.put (False);
|
||||
endrule
|
||||
|
||||
// ================================================================
|
||||
@@ -314,17 +309,9 @@ module mkSoC_Top #(Reset dm_power_on_reset)
|
||||
// ================================================================
|
||||
// INTERFACE
|
||||
|
||||
method Action set_verbosity (Bit #(4) new_verbosity, Bit #(64) logdelay);
|
||||
corew.set_verbosity (new_verbosity, logdelay);
|
||||
endmethod
|
||||
|
||||
// To external controller (E.g., GDB)
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// DMI (Debug Module Interface) facing remote debugger
|
||||
interface DMI dmi = corew.dmi;
|
||||
|
||||
// Non-Debug-Module Reset (reset all except DM)
|
||||
interface Client ndm_reset_client = corew.ndm_reset_client;
|
||||
interface debug_subordinate = corew.debug_subordinate;
|
||||
`endif
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
@@ -352,7 +339,7 @@ module mkSoC_Top #(Reset dm_power_on_reset)
|
||||
Bool watch_tohost = (tohost_addr != 0);
|
||||
mem0_controller.set_watch_tohost (watch_tohost, tohost_addr);
|
||||
Bool is_running = True;
|
||||
corew.start (is_running, tohost_addr, fromhost_addr);
|
||||
corew.controlStatusServer.request.put (ReleaseReq);
|
||||
$display ("%0d: %m.method start (tohost %0h, fromhost %0h)",
|
||||
cur_cycle, tohost_addr, fromhost_addr);
|
||||
endmethod
|
||||
|
||||
@@ -51,6 +51,9 @@ import GetPut_Aux :: *;
|
||||
// ================================================================
|
||||
// Project imports
|
||||
|
||||
import WindCoreInterface :: *;
|
||||
import AXI4Lite :: *;
|
||||
import SourceSink :: *;
|
||||
import ISA_Decls :: *;
|
||||
import TV_Info :: *;
|
||||
import SoC_Top :: *;
|
||||
@@ -104,16 +107,7 @@ module mkPre_Top_HW_Side (Toooba_RVFI_DII_Server);
|
||||
// - on power-on, and
|
||||
// - when the Debug Module requests an NDM reset (for non-DebugModule).
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
let clk <- exposeCurrentClock;
|
||||
Bool initial_reset_val = False;
|
||||
Integer ndm_reset_duration = 10; // NOTE: assuming 10 cycle reset enough for NDM
|
||||
let ndm_reset_controller <- mkReset(ndm_reset_duration, initial_reset_val, clk);
|
||||
|
||||
let ndm_reset <- mkResetEither (power_on_reset, ndm_reset_controller.new_rst);
|
||||
`else
|
||||
let ndm_reset = power_on_reset;
|
||||
`endif
|
||||
|
||||
// ================================================================
|
||||
// STATE
|
||||
@@ -140,7 +134,6 @@ module mkPre_Top_HW_Side (Toooba_RVFI_DII_Server);
|
||||
Bool v2 <- $test$plusargs ("v2");
|
||||
Bit #(4) verbosity = ((v2 ? 2 : (v1 ? 1 : 0)));
|
||||
Bit #(64) logdelay = 0; // # of instructions after which to set verbosity
|
||||
soc_top.set_verbosity (verbosity, logdelay);
|
||||
|
||||
// ----------------
|
||||
// Load optional tohost and fromhost addrs from symbol-table file
|
||||
@@ -165,36 +158,6 @@ module mkPre_Top_HW_Side (Toooba_RVFI_DII_Server);
|
||||
endfunction
|
||||
|
||||
// ================================================================
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
// ================================================================
|
||||
// NDM reset from DM
|
||||
|
||||
Reg #(Bit #(8)) rg_ndm_reset_delay <- mkReg (0);
|
||||
|
||||
rule rl_ndm_reset (rg_ndm_reset_delay == 0);
|
||||
let x <- soc_top.ndm_reset_client.request.get;
|
||||
ndm_reset_controller.assertReset;
|
||||
rg_ndm_reset_delay <= fromInteger (ndm_reset_duration + 200); // NOTE: heuristic
|
||||
|
||||
$display ("%0d: %m.rl_ndm_reset: asserting NDM reset (for non-DebugModule) for %0d cycles",
|
||||
cur_cycle, ndm_reset_duration);
|
||||
endrule
|
||||
|
||||
rule rl_ndm_reset_wait (rg_ndm_reset_delay != 0);
|
||||
if (rg_ndm_reset_delay == 1) begin
|
||||
fa_reset_actions;
|
||||
Bool is_running = True;
|
||||
soc_top.ndm_reset_client.response.put (is_running);
|
||||
$display ("%0d: %m.rl_ndm_reset_wait: sent NDM reset ack (for non-DebugModule) to Debug Module",
|
||||
cur_cycle);
|
||||
end
|
||||
rg_ndm_reset_delay <= rg_ndm_reset_delay - 1;
|
||||
endrule
|
||||
// ================================================================
|
||||
`endif
|
||||
|
||||
// ================================================================
|
||||
// BEHAVIOR
|
||||
|
||||
Reg #(Bool) rg_banner_printed <- mkReg (False);
|
||||
@@ -376,7 +339,8 @@ module mkPre_Top_HW_Side (Toooba_RVFI_DII_Server);
|
||||
|
||||
rule rl_handle_external_req_read_request (req.op == external_control_req_op_read_control_fabric);
|
||||
f_external_control_reqs.deq;
|
||||
soc_top.dmi.read_addr (truncate (req.arg1));
|
||||
soc_top.debug_subordinate.ar.put(AXI4Lite_ARFlit { araddr: truncate (req.arg1)
|
||||
, arprot: ?, aruser: ? });
|
||||
if (dmi_verbosity != 0) begin
|
||||
$display ("%0d: %m.rl_handle_external_req_read_request", cur_cycle);
|
||||
$display (" ", fshow (req));
|
||||
@@ -384,8 +348,8 @@ module mkPre_Top_HW_Side (Toooba_RVFI_DII_Server);
|
||||
endrule
|
||||
|
||||
rule rl_handle_external_req_read_response;
|
||||
let x <- soc_top.dmi.read_data;
|
||||
let rsp = Control_Rsp {status: external_control_rsp_status_ok, result: signExtend (x)};
|
||||
let x <- get (soc_top.debug_subordinate.r);
|
||||
let rsp = Control_Rsp {status: external_control_rsp_status_ok, result: signExtend (x.rdata)};
|
||||
f_external_control_rsps.enq (rsp);
|
||||
if (dmi_verbosity != 0) begin
|
||||
$display ("%0d: %m.rl_handle_external_req_read_response", cur_cycle);
|
||||
@@ -395,7 +359,10 @@ module mkPre_Top_HW_Side (Toooba_RVFI_DII_Server);
|
||||
|
||||
rule rl_handle_external_req_write (req.op == external_control_req_op_write_control_fabric);
|
||||
f_external_control_reqs.deq;
|
||||
soc_top.dmi.write (truncate (req.arg1), truncate (req.arg2));
|
||||
soc_top.debug_subordinate.aw.put(AXI4Lite_AWFlit { awaddr: truncate (req.arg1)
|
||||
, awprot: ?, awuser: ? });
|
||||
soc_top.debug_subordinate.w.put(AXI4Lite_WFlit { wdata: truncate (req.arg2)
|
||||
, wstrb: ~0, wuser: ? });
|
||||
// let rsp = Control_Rsp {status: external_control_rsp_status_ok, result: 0};
|
||||
// f_external_control_rsps.enq (rsp);
|
||||
if (dmi_verbosity != 0) begin
|
||||
@@ -404,6 +371,8 @@ module mkPre_Top_HW_Side (Toooba_RVFI_DII_Server);
|
||||
end
|
||||
endrule
|
||||
|
||||
rule rl_drain_debug_write_rsps; soc_top.debug_subordinate.b.drop; endrule
|
||||
|
||||
rule rl_handle_external_req_err ( (req.op != external_control_req_op_read_control_fabric)
|
||||
&& (req.op != external_control_req_op_write_control_fabric));
|
||||
f_external_control_reqs.deq;
|
||||
|
||||
Reference in New Issue
Block a user