Merge branch 'CHERI' into ks980-prefetch

This commit is contained in:
Jonathan Woodruff
2023-05-17 15:32:40 +00:00
18 changed files with 241 additions and 355 deletions

View File

@@ -88,11 +88,11 @@ BSC_COMPILATION_FLAGS += \
-D MULT_SYNTH \
-D Near_Mem_Caches \
-D FABRIC64 \
-D CheriBusBytes=8 \
-D CheriBusBytes=64 \
-D CheriMasterIDWidth=1 \
-D CheriTransactionIDWidth=6 \
-D CAP128 -D BLUESIM \
-D MEM64 \
-D MEM512 \
-D RISCV \
-D PERFORMANCE_MONITORING \
-D RAS_HIT_TRACING \

View File

@@ -48,6 +48,10 @@ import SourceSink :: *;
import Fabric_Defs :: *;
import SoC_Map :: *;
import VnD :: *;
import Bag :: *;
import ProcTypes :: *;
// ================================================================
interface LLC_AXI4_Adapter_IFC;
@@ -61,16 +65,27 @@ endinterface
// ================================================================
typedef struct {
Bool tag_req; // meaningful to upgrade to E if toState is S
idT id; // slot id in child cache
childT child; // from which child
} LLC_AXI_ID#(type idT, type childT) deriving(Bits, Eq, FShow);
typedef 16 OutstandingWrites;
typedef 16 WriteAddressHashW;
module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
(LLC_AXI4_Adapter_IFC)
provisos(Bits#(idT, a__),
Bits#(childT, b__),
provisos(Bits#(idT, idSz),
Bits#(childT, childSz),
FShow#(ToMemMsg#(idT, childT)),
FShow#(MemRsMsg#(idT, childT)),
Add#(SizeOf#(Line), 0, TAdd#(512, 4))); // assert Line sz = 512 + 4 tags
Add#(SizeOf#(Line), 0, TAdd#(512, 4)), // assert Line sz = 512 + 4 tags
Add#(a__, SizeOf#(LLC_AXI_ID#(idT, childT)), Wd_MId) // LLC_AXI_ID must fit into the external ID.
);
// Verbosity: 0: quiet; 1: LLC transactions; 2: loop detail
Integer verbosity = 0;
Integer verbosity = 2;
Reg #(Bit #(4)) cfg_verbosity <- mkConfigReg (fromInteger (verbosity));
// ================================================================
@@ -79,25 +94,28 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
let masterPortShim <- mkAXI4ShimFF;
// For discarding write-responses
CreditCounter_IFC #(4) ctr_wr_rsps_pending <- mkCreditCounter; // Max 15 writes outstanding
CreditCounter_IFC #(TLog#(OutstandingWrites)) ctr_wr_rsps_pending <- mkCreditCounter; // 16 outstanding writes.
Bag#(OutstandingWrites, Bit#(Wd_MId), Bit#(WriteAddressHashW)) outstandingWrites <- mkSmallBag;
// ================================================================
// Functions to interact with the fabric
// Send a read-request into the fabric
function Action fa_fabric_send_read_req (Fabric_Addr addr, Bool tag_req);
function Action fa_fabric_send_read_req (Fabric_Addr addr, LLC_AXI_ID#(idT, childT) id);
action
let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_default_mid,
Bit#(Wd_MId) arid = zeroExtend(pack(id));
let mem_req_rd_addr = AXI4_ARFlit {arid: arid,
araddr: addr,
arlen: tag_req ? 0 : 7, // burst len = arlen+1
arsize: tag_req ? 1 : 8,
arlen: 0, // burst len = arlen+1
arsize: id.tag_req ? 1 : 64,
arburst: INCR,
arlock: fabric_default_lock,
arcache: fabric_default_arcache,
arprot: fabric_default_prot,
arqos: fabric_default_qos,
arregion: fabric_default_region,
aruser: pack(tag_req)};
aruser: pack(id.tag_req)};
masterPortShim.slave.ar.put(mem_req_rd_addr);
@@ -110,16 +128,8 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
// ================================================================
// Handle read requests and responses
// Don't do reads while writes are outstanding.
// Each 512b cache line takes 8 beats, each handling 64 bits
Reg #(Bit #(3)) rg_rd_rsp_beat <- mkReg (0);
FIFOF #(LdMemRq #(idT, childT)) f_pending_reads <- mkFIFOF;
Reg #(CLine) rg_cline <- mkRegU;
rule rl_handle_read_req (llc.toM.first matches tagged Ld .ld
&&& (ctr_wr_rsps_pending.value == 0));
rule rl_handle_read_req (llc.toM.first matches tagged Ld .ld &&& !outstandingWrites.dataMatch(hash(ld.addr[63:6])));
if ((cfg_verbosity > 0)) begin
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_req: Ld request from LLC to memory",
cur_cycle);
@@ -127,105 +137,72 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
end
Addr line_addr = {ld.addr [63:6], 6'h0 }; // Addr of containing cache line
fa_fabric_send_read_req (line_addr, ld.tag_req);
f_pending_reads.enq (ld);
fa_fabric_send_read_req (line_addr, LLC_AXI_ID{tag_req: ld.tag_req, id: ld.id, child: ld.child});
llc.toM.deq;
endrule
rule rl_handle_read_rsps;
let mem_rsp <- get(masterPortShim.slave.r);
if (cfg_verbosity > 1) begin
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsps: beat %0d ", cur_cycle, rg_rd_rsp_beat);
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsps: ", cur_cycle);
$display (" ", fshow (mem_rsp));
end
if (mem_rsp.rresp != OKAY) begin
// TODO: need to raise a non-maskable interrupt (NMI) here
$display ("%0d: LLC_AXI4_Adapter.rl_handle_read_rsp: fabric response error; exit", cur_cycle);
$display (" ", fshow (mem_rsp));
$finish (1);
end
// Shift next 64 bits from fabric into the cache line being assembled
let new_cline_tag = { mem_rsp.ruser, pack(rg_cline.tag) [3:1] };
let new_cline_data = { mem_rsp.rdata, pack(rg_cline.data) [511:64] };
let new_cline = CLine { tag: rg_rd_rsp_beat[0] == 0 ? unpack(new_cline_tag) : rg_cline.tag
, data: unpack(new_cline_data) };
if (mem_rsp.rlast) begin
let ldreq <- pop (f_pending_reads);
MemRsMsg #(idT, childT) resp = MemRsMsg {data: new_cline,
child: ldreq.child,
id: ldreq.id};
if (ldreq.tag_req) begin
resp.data = CLine { tag: unpack(truncate(mem_rsp.rdata)), data: ?};
end
llc.rsFromM.enq (resp);
if (cfg_verbosity > 1)
$display (" Response to LLC: ", fshow (resp));
rg_rd_rsp_beat <= 0;
rg_cline <= unpack(0);
end else begin
rg_rd_rsp_beat <= rg_rd_rsp_beat + 1;
rg_cline <= new_cline;
let new_cline = CLine { tag: unpack(mem_rsp.ruser)
, data: unpack(mem_rsp.rdata) };
LLC_AXI_ID#(idT, childT) id = unpack(truncate(mem_rsp.rid));
MemRsMsg #(idT, childT) resp = MemRsMsg {data: new_cline,
child: id.child,
id: id.id};
if (id.tag_req) begin
resp.data = CLine { tag: unpack(truncate(mem_rsp.rdata)), data: ?};
end
llc.rsFromM.enq (resp);
if (cfg_verbosity > 1)
$display (" Response to LLC: ", fshow (resp));
endrule
// ================================================================
// Handle write requests and responses
// Each 512b cache line takes 8 beats, each handling 64 bits
Reg #(Bit #(3)) rg_wr_req_beat <- mkReg (0);
rule rl_handle_write_req (llc.toM.first matches tagged Wb .wb);
if ((cfg_verbosity > 0) && (rg_wr_req_beat == 0)) begin
Reg#(Bit#(Wd_MId)) wid_reg <- mkRegU;
rule rl_handle_write_req (llc.toM.first matches tagged Wb .wb &&& !outstandingWrites.isMember(wid_reg).v);
if (cfg_verbosity > 0) begin
$display ("%d: LLC_AXI4_Adapter.rl_handle_write_req: Wb request from LLC to memory:", cur_cycle);
$display (" ", fshow (wb));
end
// on first flit...
// ================
if (rg_wr_req_beat == 0) begin
// send AXI4 AW flit
masterPortShim.slave.aw.put (AXI4_AWFlit {
awid: fabric_default_mid,
awaddr: { wb.addr [63:6], 6'h0 },
awlen: 7, // burst len = awlen+1
awsize: 8,
awburst: INCR,
awlock: fabric_default_lock,
awcache: fabric_default_awcache,
awprot: fabric_default_prot,
awqos: fabric_default_qos,
awregion: fabric_default_region,
awuser: 0});
// Expect a fabric response
ctr_wr_rsps_pending.incr;
end
// send AXI4 AW flit
masterPortShim.slave.aw.put (AXI4_AWFlit {
awid: wid_reg,
awaddr: { wb.addr [63:6], 6'h0 },
awlen: 0, // burst len = awlen+1
awsize: 64,
awburst: INCR,
awlock: fabric_default_lock,
awcache: fabric_default_awcache,
awprot: fabric_default_prot,
awqos: fabric_default_qos,
awregion: fabric_default_region,
awuser: 0});
// Expect a fabric response
ctr_wr_rsps_pending.incr;
outstandingWrites.insert(wid_reg, hash(wb.addr[63:6]));
wid_reg <= wid_reg + 1; // Best effort to use unique IDs to allow reordering in the fabric.
llc.toM.deq;
// on last flit...
// ===============
if (rg_wr_req_beat == 7) begin
llc.toM.deq;
rg_wr_req_beat <= 0;
end else // increment flit counter
rg_wr_req_beat <= rg_wr_req_beat + 1;
// on each flit ...
// ================
Vector #(8, Bit #(8)) line_strb = unpack(pack(wb.byteEn));
Vector #(4, MemTaggedData) line_data = clineToMemTaggedDataVector(wb.data);
// send AXI4 W flit
masterPortShim.slave.w.put(AXI4_WFlit {
wdata: line_data[rg_wr_req_beat[2:1]].data[rg_wr_req_beat[0]],
wstrb: line_strb[rg_wr_req_beat],
wlast: rg_wr_req_beat == 7,
wuser: pack(line_data[rg_wr_req_beat[2:1]].tag)});
wdata: pack(wb.data.data),
wstrb: pack(wb.byteEn),
wlast: True,
wuser: pack(wb.data.tag)});
endrule
// ----------------
@@ -242,6 +219,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
end
ctr_wr_rsps_pending.decr;
outstandingWrites.remove(wr_resp.bid);
if (wr_resp.bresp != OKAY) begin
// TODO: need to raise a non-maskable interrupt (NMI) here
@@ -255,7 +233,9 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
// INTERFACE
method Action reset;
ctr_wr_rsps_pending.clear;
error("Reset called for LLC AXI4 adapter");
// XXX resetting this module would cause wedges unless the surrounding
// fabric was also fully reset
endmethod
// Fabric interface for memory

View File

@@ -66,7 +66,7 @@ interface MMIO_AXI4_Adapter_IFC;
interface Server #(MMIOCRq, MMIODataPRs) core_side;
// Fabric master interface for IO
interface AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data
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) mmio_master;
endinterface
@@ -251,7 +251,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
// on each flit...
// ===============
AXI4_WFlit #(Wd_Data, Wd_W_User)
AXI4_WFlit #(Wd_Data_Periph, Wd_W_User)
wflit = AXI4_WFlit {wdata: req.data.data[whichHalf],
wstrb: line_strb[whichHalf],
wlast: last,

View File

@@ -79,7 +79,7 @@ interface Proc_IFC;
Wd_AR_User, Wd_R_User) master0;
// Fabric master interface for IO (from MMIOPlatform)
interface AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data
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) master1;
@@ -106,9 +106,10 @@ interface Proc_IFC;
// ----------------
// Coherent port into LLC (used by Debug Module, DMA engines, ... to read/write memory)
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;
interface AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph)
debug_module_mem_server;
`ifdef RVFI_DII
interface Toooba_RVFI_DII_Server rvfi_dii_server;

View File

@@ -66,8 +66,7 @@ import Clocks :: *;
import Cur_Cycle :: *;
import GetPut_Aux :: *;
import Routable :: *;
import AXI4 :: *;
import AXI4Lite :: *;
import BlueAXI4 :: *;
import SourceSink :: *;
import TagControllerAXI :: *;
import CacheCore :: *;
@@ -124,11 +123,11 @@ typedef WindCoreMid #( // AXI lite subordinate control port parameters
// 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
, TAdd #(Wd_MId, 1), Wd_Addr, Wd_Data_Periph, 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
, Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph
// Number of interrupt lines
, t_n_irq) CoreW_IFC #(numeric type t_n_irq);
@@ -226,8 +225,8 @@ module mkCoreW_reset #(Reset porReset)
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));
AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0)
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);
@@ -236,6 +235,11 @@ module mkCoreW_reset #(Reset porReset)
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);
AXI4_Shim#(TAdd #(Wd_MId, 1), Wd_Addr, Wd_Data, 0, 0, 0, 0, 0)
tag_controller_deburster <- mkBurstToNoBurst;
mkConnection (tagController.master, tag_controller_deburster.slave, reset_by all_harts_reset);
`ifdef PERFORMANCE_MONITORING
rule report_tagController_events;
EventsCacheCore cache_core_evts = tagController.events;
@@ -310,7 +314,7 @@ module mkCoreW_reset #(Reset porReset)
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
rg_harts_reset_delay <= fromInteger (hart_reset_duration + 200); // NOTE: heuristic
rg_harts_reset_running <= x;
$display ("%0d: %m.rl_dm_harts_reset: asserting harts reset for %0d cycles",
cur_cycle, hart_reset_duration);
@@ -363,7 +367,10 @@ module mkCoreW_reset #(Reset porReset)
// Create a tap for DM's memory-writes to the bus, and merge-in the trace data.
DM_Mem_Tap_IFC dm_mem_tap <- mkDM_Mem_Tap;
mkConnection (debug_module.master, dm_mem_tap.slave);
let dm_master_local = dm_mem_tap.master;
AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph )
dm_master_local = dm_mem_tap.master;
rule rl_merge_dm_mem_trace_data;
let tmp <- dm_mem_tap.trace_data_out.get;
@@ -429,7 +436,10 @@ module mkCoreW_reset #(Reset porReset)
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;
AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph )
dm_master_local = debug_module.master;
// END SECTION: DM, no TV
// ================================================================
@@ -440,7 +450,10 @@ module mkCoreW_reset #(Reset porReset)
// BEGIN SECTION: no DM
// No DM, so 'DM bus master' is AXI4 dummy
let dm_master_local = culDeSac;
AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph )
dm_master_local = culDeSac;
`ifdef INCLUDE_TANDEM_VERIF
// TV, no DM: stub out the dm input to TV
@@ -460,9 +473,10 @@ module mkCoreW_reset #(Reset porReset)
// 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))
, AXI4_Master #( Wd_CoreW_Bus_MId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph
, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph ))
master_vector = newVector;
master_vector[cpu_uncached_master_num] = proc_uncached;
master_vector[debug_module_sba_master_num] = dm_master_local;
@@ -471,12 +485,12 @@ module mkCoreW_reset #(Reset porReset)
// Slaves on the local bus
// default slave is forwarded out directly to the Core interface
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))
, AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph ))
slave_vector = newVector;
slave_vector[default_slave_num] = uncached_mem_shim.slave;
slave_vector[llc_slave_num] = proc.debug_module_mem_server;
slave_vector[llc_slave_num] = zero_AXI4_Slave_user (proc.debug_module_mem_server);
slave_vector[plic_slave_num] = zero_AXI4_Slave_user (plic.axi4_slave);
function Vector #(CoreW_Bus_Num_Slaves, Bool) route (Bit #(Wd_Addr) addr);
@@ -618,7 +632,7 @@ module mkCoreW_reset #(Reset porReset)
// memory interfaces
// -----------------
// Cached master to Fabric master interface
interface manager_0 = tagController.master;
interface manager_0 = tag_controller_deburster.master;
// Uncached master to Fabric master interface
interface manager_1 = prepend_AXI4_Master_id
(0, zero_AXI4_Master_user (uncached_mem_shim.master));

View File

@@ -67,7 +67,7 @@ Integer bytes_per_fabric_addr = valueOf (Bytes_per_Fabric_Addr);
// |
// Periph
typedef 64 Wd_Data;
typedef 512 Wd_Data;
// ----------------
// Width of fabric 'user' datapaths. Carry capability tags on data lines.
@@ -118,6 +118,11 @@ Bit#(Wd_W_User) fabric_default_wuser = 0;
Bit#(Wd_B_User) fabric_default_buser = 0;
Bit#(Wd_AR_User) fabric_default_aruser = 0;
Bit#(Wd_R_User) fabric_default_ruser = 0;
Bit#(Wd_AW_User_Periph) fabric_default_awuser_periph = 0;
Bit#(Wd_W_User_Periph) fabric_default_wuser_periph = 0;
Bit#(Wd_B_User_Periph) fabric_default_buser_periph = 0;
Bit#(Wd_AR_User_Periph) fabric_default_aruser_periph = 0;
Bit#(Wd_R_User_Periph) fabric_default_ruser_periph = 0;
// ================================================================

View File

@@ -55,8 +55,8 @@ interface DM_System_Bus_IFC;
// ----------------
// Facing System
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;
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph) master;
endinterface
// ================================================================
@@ -292,7 +292,7 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
arprot: fabric_default_prot,
arqos: fabric_default_qos,
arregion: fabric_default_region,
aruser: fabric_default_aruser};
aruser: fabric_default_aruser_periph};
axiShim.slave.ar.put(rda);
// Save read-address for byte-lane extraction from later response
@@ -333,13 +333,13 @@ module mkDM_System_Bus (DM_System_Bus_IFC);
awprot: fabric_default_prot,
awqos: fabric_default_qos,
awregion: fabric_default_region,
awuser: fabric_default_awuser};
awuser: fabric_default_awuser_periph};
axiShim.slave.aw.put(wra);
let wrd = AXI4_WFlit {wdata: fabric_data,
wstrb: fabric_strb,
wlast: True,
wuser: fabric_default_wuser};
wuser: fabric_default_wuser_periph};
axiShim.slave.w.put(wrd);
if (verbosity != 0) begin

View File

@@ -138,8 +138,8 @@ interface Debug_Module_IFC;
// Read/Write RISC-V memory
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;
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph) master;
endinterface
// ================================================================

View File

@@ -98,7 +98,7 @@ 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_CoreW_Bus_SId, Wd_Addr, Wd_Data
interface AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data_Periph
, 0, 0, 0, 0, 0) axi4_slave;
// sources
@@ -381,13 +381,12 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
$display (" ", fshow (rda));
end
if ((valueOf (Wd_Data) == 64) && ((addr_offset & 'h7) == 'h4))
if ((valueOf (Wd_Data_Periph) == 64) && ((addr_offset & 'h7) == 'h4))
rdata = { rdata [31:0], 32'h0 };
// Send read-response to bus
Fabric_Data x = truncate (rdata);
let rdr = AXI4_RFlit {rid: rda.arid,
rdata: x,
rdata: rdata,
rresp: rresp,
rlast: True,
ruser: rda.aruser}; // XXX This requires that Wd_AR_User == Wd_R_User
@@ -416,7 +415,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
end
let addr_offset = wra.awaddr - rg_addr_base;
let wdata32 = (((valueOf (Wd_Data) == 64) && ((addr_offset & 'h7) == 'h4))
let wdata32 = (((valueOf (Wd_Data_Periph) == 64) && ((addr_offset & 'h7) == 'h4))
? wrd.wdata [63:32]
: wrd.wdata [31:0]);
let bresp = OKAY;

View File

@@ -519,6 +519,8 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
dInst.csr = tagged Invalid;
dInst.execFunc = tagged Br AT;
if (funct3 != 0) illegalInst = True;
dInst.capChecks.check_enable = True;
dInst.capChecks.check_low_src = Src1Addr;
dInst.capChecks.check_high_src = Src1AddrPlus2;
@@ -542,14 +544,18 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
opcBranch: begin
dInst.iType = Br;
dInst.execFunc = tagged Br (case(funct3)
fnBEQ: Eq;
fnBNE: Neq;
fnBLT: Lt;
fnBLTU: Ltu;
fnBGE: Ge;
fnBGEU: Geu;
endcase);
ExecFunc execFunc = ?;
{illegalInst, execFunc} = case(funct3)
fnBEQ: tuple2(False, Br(Eq));
fnBNE: tuple2(False, Br(Neq));
fnBLT: tuple2(False, Br(Lt));
fnBLTU: tuple2(False, Br(Ltu));
fnBGE: tuple2(False, Br(Ge));
fnBGEU: tuple2(False, Br(Geu));
default: tuple2(True, Br(?));
endcase;
dInst.execFunc = execFunc;
regs.dst = Invalid;
regs.src1 = Valid(tagged Gpr rs1);
regs.src2 = Valid(tagged Gpr rs2);

View File

@@ -79,9 +79,7 @@ import ProcTypes::*;
import CacheUtils::*;
import CCTypes::*;
import L2Tlb::*;
import MemLoader::*;
import CrossBar::*;
import MemLoader::*;
// ----------------
// From Toooba
@@ -101,7 +99,7 @@ typedef struct {
} TlbDmaReqId deriving(Bits, Eq, FShow);
typedef union tagged {
MemLoaderMemReqId MemLoader;
void Client;
TlbDmaReqId Tlb;
} LLCDmaReqId deriving(Bits, Eq, FShow);
@@ -128,79 +126,82 @@ endfunction
// ================================================================
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))
(AXI4_Slave #( Wd_CoreW_Bus_SId, Wd_Addr, Wd_Data_Periph
, Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph
, Wd_AR_User_Periph, Wd_R_User_Periph ))
provisos (Alias #(dmaRqT, DmaRq #(LLCDmaReqId)));
Bool verbose = False;
Integer verbosity = 0;
// When debugger reads a word, request a line from LLC, and remember dword-in-line here
FIFOF #(Bit #(3)) f_dword_in_line <- mkFIFOF;
// Connector to AXI4 fabric
let slavePortShim <- mkAXI4ShimFF;
// ================================================================
// These regs are a 1-location local cache for an LLC Cache Line,
// to avoid doing a full read-modify-write to the LLC on each transaction.
Reg #(Cacheline_Cache_State) rg_cacheline_cache_state <- mkReg (CACHELINE_CACHE_CLEAN);
Reg #(Addr) rg_cacheline_cache_addr <- mkReg (1); // never matches an LLC line addr
Reg #(Line) rg_cacheline_cache_data <- mkRegU;
// Writeback dirty cacheline_cache if no new store requests within n-cycles
Reg #(Bit #(10)) rg_cacheline_cache_dirty_delay <- mkReg (0);
// ================================================================
// Write transactions from the external client (e.g., Debug Module)
// Respond to store-requests from the external client on store-hit
rule rl_handle_MemLoader_st_req ( ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
|| (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY))
&& (fn_addr_is_in_line (slavePortShim.master.aw.peek.awaddr,
rg_cacheline_cache_addr)));
let internal_aw_ff <- mkFIFO;
rule rl_client_st;
let wr_addr <- get (slavePortShim.master.aw);
let wr_data <- get (slavePortShim.master.w);
// Modify relevant bytes of relevant dword
let newLine = setDataAtBE( rg_cacheline_cache_data
, getCLineDataSel(wr_addr.awaddr)
, wr_data.wdata, unpack(pack(wr_data.wstrb)));
// Save it
rg_cacheline_cache_data <= newLine;
rg_cacheline_cache_state <= CACHELINE_CACHE_DIRTY;
rg_cacheline_cache_dirty_delay <= '1; // start write-back delay countdown
internal_aw_ff.enq(wr_addr);
if (verbosity >= 2) begin
$display ("%0d: %m.rl_client_st for addr %0h", cur_cycle, wr_addr.awaddr);
end
let line_addr = fn_align_addr_to_line (wr_addr.awaddr);
Vector#(TDiv#(CLineDataNumBytes,8), Bit#(TDiv#(Wd_Data_Periph,8))) line_be = replicate(0);
line_be[getCLineDataSel(wr_addr.awaddr)] = wr_data.wstrb;
dmaRqT req = DmaRq {addr: line_addr,
byteEn: unpack(pack(line_be)),
data: setDataAt(unpack(0), getCLineDataSel(wr_addr.awaddr), wr_data.wdata),
id: tagged Client}; // TODO: change uniformly to wr_addr.awid
llc.memReq.enq (req);
endrule
rule rl_client_st_rsp(llc.respSt.first matches tagged Client);
llc.respSt.deq;
let wr_addr <- get (internal_aw_ff);
// Send response to external client
slavePortShim.master.b.put(AXI4_BFlit{
bid: wr_addr.awid, // TODO: change uniformly to Fabric_id
bid: wr_addr.awid,
bresp: OKAY,
buser: ?
});
if (verbosity >= 2) begin
$display ("%0d: %m.rl_handle_MemLoader_st_req: addr %0h data %0h strb %0h",
cur_cycle, wr_addr.awaddr, wr_data.wdata, wr_data.wstrb);
//$display (" old_dword: %0h", old_dword);
//$display (" new_dword: %0h", old_dword);
end
endrule
// ================================================================
// Read transactions from the external memory client (e.g., Debug Module)
// Responds to load-requests from the external client on load-hit
rule rl_handle_MemLoader_ld_req ( ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
|| (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY))
&& (fn_addr_is_in_line (slavePortShim.master.ar.peek.araddr,
rg_cacheline_cache_addr)));
let internal_ar_ff <- mkFIFO;
rule rl_client_ld_req;
let rd_addr <- get (slavePortShim.master.ar);
let dword = getDataAt( rg_cacheline_cache_data
internal_ar_ff.enq(rd_addr);
let line_addr = fn_align_addr_to_line (rd_addr.araddr);
dmaRqT req = DmaRq {addr: line_addr,
byteEn: replicate(replicate(False)), // all False means 'read'
data: ?,
id: tagged Client}; // TODO: change uniformly to wr_addr.awid
llc.memReq.enq (req);
if (verbosity >= 2) begin
$display ("%0d: %m.rl_client_ld_req: line_addr %0h", cur_cycle, line_addr);
end
endrule
// Finish reload
rule rl_client_ld_rsp (llc.respLd.first.id matches tagged Client);
let resp = llc.respLd.first;
llc.respLd.deq;
let rd_addr <- get (internal_ar_ff);
let dword = getDataAt( resp.data
, getCLineDataSel(rd_addr.araddr));
// Send response to external client
@@ -213,145 +214,11 @@ module mkLLCDmaConnect #( DmaServer#(LLCDmaReqId) llc
});
if (verbosity >= 2) begin
$display ("%0d: %m.rl_handle_MemLoader_ld_req: addr %0h", cur_cycle, rd_addr.araddr);
$display ("%0d: %m.rl_client_ld_rsp: addr %0h", cur_cycle, rd_addr.araddr);
$display (" dword: %0h", dword);
end
endrule
// ----------------------------------------------------------------
// Miss and writeback processing
// Maintain dirty delay countdown
rule rl_cacheline_cache_writeback_dirty_delay ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
&& (rg_cacheline_cache_dirty_delay != 0));
rg_cacheline_cache_dirty_delay <= rg_cacheline_cache_dirty_delay - 1;
endrule
function Action fa_writeback;
action
dmaRqT req = DmaRq {addr: rg_cacheline_cache_addr,
byteEn: replicate(replicate(True)), // Write all bytes
data: rg_cacheline_cache_data,
id: tagged MemLoader (?) // TODO: use wr_addr.awid?
};
llc.memReq.enq (req);
// $display ("%0d: %m.fa_writeback line at %0h", cur_cycle, rg_cacheline_cache_addr);
// $display (" data %0128h", rg_cacheline_cache_data);
endaction
endfunction
// Initiate writeback if dirty for full delay
rule rl_cacheline_cache_writeback_dirty_aged ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
&& (rg_cacheline_cache_dirty_delay == 0));
if (verbosity >= 2) begin
$display ("%0d: %m.rl_cacheline_cache_writeback_dirty_aged.", cur_cycle);
$display (" Old line addr %0h", rg_cacheline_cache_addr);
end
fa_writeback;
rg_cacheline_cache_state <= CACHELINE_CACHE_WRITING_BACK;
endrule
// Initiate writeback if dirty and next request is store-miss
rule rl_cacheline_cache_writeback_st_miss ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
&& (! fn_addr_is_in_line (slavePortShim.master.aw.peek.awaddr,
rg_cacheline_cache_addr)));
if (verbosity >= 2) begin
$display ("%0d: %m.rl_cacheline_cache_writeback_st_miss.", cur_cycle);
$display (" Old line addr %0h", rg_cacheline_cache_addr);
$display (" New addr %0h", slavePortShim.master.aw.peek.awaddr);
end
fa_writeback;
rg_cacheline_cache_state <= CACHELINE_CACHE_WRITING_BACK;
endrule
// Initiate writeback if dirty and next request is load-miss
rule rl_cacheline_cache_writeback_ld_miss ( (rg_cacheline_cache_state == CACHELINE_CACHE_DIRTY)
&& (! fn_addr_is_in_line (slavePortShim.master.ar.peek.araddr,
rg_cacheline_cache_addr)));
if (verbosity >= 2) begin
$display ("%0d: %m.rl_cacheline_cache_writeback_ld_miss.", cur_cycle);
$display (" Old line addr %0h", rg_cacheline_cache_addr);
$display (" New addr %0h", slavePortShim.master.aw.peek.awaddr);
end
fa_writeback;
rg_cacheline_cache_state <= CACHELINE_CACHE_WRITING_BACK;
endrule
// Finish writeback
rule rl_cacheline_cache_writeback_finish (llc.respSt.first matches tagged MemLoader .id
&&& (rg_cacheline_cache_state == CACHELINE_CACHE_WRITING_BACK));
let resp = llc.respSt.first;
llc.respSt.deq;
rg_cacheline_cache_state <= CACHELINE_CACHE_CLEAN;
if (verbosity >= 2) begin
$display ("%0d: %m.rl_cacheline_cache_writeback_finish. Line addr %0h",
cur_cycle, rg_cacheline_cache_addr);
$display (" Line data %0h", rg_cacheline_cache_data);
end
endrule
function Action fa_initiate_reload (Addr addr);
action
let line_addr = fn_align_addr_to_line (addr);
dmaRqT req = DmaRq {addr: line_addr,
byteEn: replicate(replicate(False)), // all False means 'read'
data: ?,
id: tagged MemLoader (?)}; // TODO: change uniformly to wr_addr.awid
llc.memReq.enq (req);
rg_cacheline_cache_addr <= line_addr;
if (verbosity >= 2) begin
$display (" fa_initiate_reload: line_addr %0h", line_addr);
end
endaction
endfunction
// Initiate reload when cacheline_cache is clean on store-miss
rule rl_cacheline_cache_reload_req_st ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
&& (! fn_addr_is_in_line (slavePortShim.master.aw.peek.awaddr,
rg_cacheline_cache_addr)));
let addr = slavePortShim.master.aw.peek.awaddr;
if (verbosity >= 2) begin
$display ("%0d: %m.rl_cacheline_cache_reload_req_st for addr %0h", cur_cycle, addr);
end
fa_initiate_reload (addr);
rg_cacheline_cache_state <= CACHELINE_CACHE_RELOADING;
endrule
// Initiate reload when cacheline_cache is clean on load-miss
rule rl_cacheline_cache_reload_req_ld ( (rg_cacheline_cache_state == CACHELINE_CACHE_CLEAN)
&& (! fn_addr_is_in_line (slavePortShim.master.ar.peek.araddr,
rg_cacheline_cache_addr)));
let addr = slavePortShim.master.ar.peek.araddr;
if (verbosity >= 2) begin
$display ("%0d: %m.rl_cacheline_cache_reload_req_ld for addr %0h", cur_cycle, addr);
end
fa_initiate_reload (addr);
rg_cacheline_cache_state <= CACHELINE_CACHE_RELOADING;
endrule
// Finish reload
rule rl_cacheline_cache_reload_finish (llc.respLd.first.id matches tagged MemLoader .id
&&& (rg_cacheline_cache_state == CACHELINE_CACHE_RELOADING));
let resp = llc.respLd.first;
llc.respLd.deq;
rg_cacheline_cache_state <= CACHELINE_CACHE_CLEAN;
rg_cacheline_cache_data <= resp.data;
if (verbosity >= 2) begin
$display ("%0d: %m.rl_cacheline_cache_reload_finish. Line addr %0h", cur_cycle, rg_cacheline_cache_addr);
$display (" Line data %0h", resp.data);
end
endrule
// ================================================================
// Transactions from the TLB
// Expecting only LOAD requests from TLB
@@ -384,11 +251,8 @@ module mkLLCDmaConnect #( DmaServer#(LLCDmaReqId) llc
endfunction
// Prioritize external mem client over Tlb
(* descending_urgency = "rl_cacheline_cache_writeback_dirty_aged, sendTlbReqToLLC" *)
(* descending_urgency = "rl_cacheline_cache_writeback_st_miss, sendTlbReqToLLC" *)
(* descending_urgency = "rl_cacheline_cache_writeback_ld_miss, sendTlbReqToLLC" *)
(* descending_urgency = "rl_cacheline_cache_reload_req_st, sendTlbReqToLLC" *)
(* descending_urgency = "rl_cacheline_cache_reload_req_ld, sendTlbReqToLLC" *)
(* descending_urgency = "rl_client_st, sendTlbReqToLLC" *)
(* descending_urgency = "rl_client_ld_req, sendTlbReqToLLC" *)
rule sendTlbReqToLLC;
let {c, r} <- toGet(tlbQ).get;

View File

@@ -27,7 +27,7 @@ BSC_COMPILATION_FLAGS += \
-D ISA_PRIV_M -D ISA_PRIV_S -D ISA_PRIV_U \
-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 CheriBusBytes=8 \
-D CheriBusBytes=64 \
-D CheriMasterIDWidth=1 \
-D CheriTransactionIDWidth=6 \
-D PERFORMANCE_MONITORING \
@@ -36,9 +36,8 @@ BSC_COMPILATION_FLAGS += \
-D Near_Mem_Caches \
-D FABRIC64 \
-D CAP128 \
-D MEM64 \
-D MEM512 \
-D RISCV \
-D NO_SPEC_TRAINING -D NO_SPEC_REDIRECT -D NO_SPEC_STRAIGHT_PATH -D SPEC_RSB_FIXUP -D NO_SPEC_RSB_PUSH -D NO_SPEC_STL \
-D TSO_MM \
-D INCLUDE_GDB_CONTROL \
-D BRVF_TRACE \

View File

@@ -32,6 +32,7 @@ import Vector :: *;
import GetPut_Aux :: *;
import Routable :: *;
import BlueBasics :: *;
import BlueAXI4 :: *;
import SourceSink :: *;
import WindCoreInterface :: *;
@@ -71,10 +72,10 @@ interface P3_Core_IFC;
// Core CPU interfaces
// CPU IMem to Fabric master interface
interface AXI4_Master_Sig#(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
interface AXI4_Master_Sig#(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data_Periph,
0, 0, 0, 0, 0) master0;
interface AXI4_Master_Sig#(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
interface AXI4_Master_Sig#(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data_Periph,
0, 0, 0, 0, 0) master1;
// External interrupt sources
@@ -165,6 +166,14 @@ module mkP3_Core (P3_Core_IFC);
, CoreW_IFC #(N_External_Interrupt_Sources)) both
<- mkCoreW_reset (dm_power_on_reset, reset_by ndm_reset);
match {.otherRst, .corew} = both;
// AXI4 Narrower Master in front of cached memory master
NumProxy #(4) proxyInDepth = error ("don't look inside a proxy");
NumProxy #(4) proxyOutDepth = error ("don't look inside a proxy");
Tuple2 #( AXI4_Slave #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data, 0, 0, 0, 0, 0)
, AXI4_Master #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0) )
wideS_narrowM <- mkAXI4DataWidthShim_WideToNarrow (proxyInDepth, proxyOutDepth);
match {.wideS, .narrowM} = wideS_narrowM;
mkConnection(corew.manager_0, wideS);
`ifdef INCLUDE_GDB_CONTROL
@@ -261,7 +270,7 @@ module mkP3_Core (P3_Core_IFC);
// ================================================================
// INTERFACE
let master0_sig <- toAXI4_Master_Sig (corew.manager_0);
let master0_sig <- toAXI4_Master_Sig (narrowM);
let master1_sig <- toAXI4_Master_Sig (corew.manager_1);
// ----------------------------------------------------------------
// Core CPU interfaces

View File

@@ -126,7 +126,7 @@ typedef TLog #(Word64s_per_Raw_Mem_Word) Bits_per_Word64_in_Raw_Me
// Type of index of a Word64 in a Raw_Mem_Word seen as a vector of Word64s
typedef Bit #(Bits_per_Word64_in_Raw_Mem_Word) Word64_in_Raw_Mem_Word;
typedef TDiv #(Bytes_per_Raw_Mem_Word, Bytes_per_Fabric_Data) Fabric_Data_per_Raw_Mem_Word;
typedef TDiv #(Bytes_per_Raw_Mem_Word, TDiv #(Wd_Data_Periph, 8)) Fabric_Data_per_Raw_Mem_Word;
// Index of bit that selects a fabric data word in an address
`ifdef FABRIC32
@@ -207,7 +207,7 @@ interface Mem_Controller_IFC;
method Action set_addr_map (Fabric_Addr addr_base, Fabric_Addr addr_lim);
// Main Fabric Reqs/Rsps
interface AXI4_Slave #(Wd_SId, Wd_Addr, Wd_Data, 0, 0, 0, 0, 0)
interface AXI4_Slave #(Wd_SId, Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0)
slave;
// To raw memory (outside the SoC)
@@ -245,8 +245,8 @@ typedef struct {Req_Op req_op;
Bit #(Wd_User) user;
// Write data info
Bit #(TDiv #(Wd_Data, 8)) wstrb;
Fabric_Data data;
Bit #(TDiv #(Wd_Data_Periph, 8)) wstrb;
Bit #(Wd_Data_Periph) data;
} Req
deriving (Bits, FShow);
@@ -487,7 +487,7 @@ module mkMem_Controller (Mem_Controller_IFC);
// We need to select the fabric data word from the raw mem word that contains the target address.
// View the raw mem word as a vector of fabric data words (Wd_Data width words)
Vector #(Fabric_Data_per_Raw_Mem_Word, Bit #(Wd_Data)) raw_mem_word_V_fabric_data = unpack (rg_cached_raw_mem_word);
Vector #(Fabric_Data_per_Raw_Mem_Word, Bit #(Wd_Data_Periph)) raw_mem_word_V_fabric_data = unpack (rg_cached_raw_mem_word);
// Get the index into this vector of the fabric word containing the target address.
// For this index, use a generous size (here Bit #(16)), and let zeroExtend pad it automaticallly.
@@ -496,7 +496,7 @@ module mkMem_Controller (Mem_Controller_IFC);
n = (n >> lo_fabric_data);
// Select the fabric data word of interest
Bit #(Wd_Data) rdata = raw_mem_word_V_fabric_data [n];
Bit #(Wd_Data_Periph) rdata = raw_mem_word_V_fabric_data [n];
let rdr = AXI4_RFlit {rid: f_reqs.first.id,
rdata: rdata,
@@ -529,7 +529,7 @@ module mkMem_Controller (Mem_Controller_IFC);
// Lane-adjust the new word64
Bit #(64) word64_new = zeroExtend (f_reqs.first.data);
Bit #(8) strobe = zeroExtend (f_reqs.first.wstrb);
if ((valueOf (Wd_Data) == 32) && (f_reqs.first.addr [2] == 1'b1)) begin
if ((valueOf (Wd_Data_Periph) == 32) && (f_reqs.first.addr [2] == 1'b1)) begin
// Upper 32b only
word64_new = { word64_new [31:0], 0 };
strobe = { strobe [3:0], 0 };
@@ -609,7 +609,7 @@ module mkMem_Controller (Mem_Controller_IFC);
rule rl_invalid_rd_address ( (rg_state == STATE_READY)
&& (! fn_addr_is_ok (rg_addr_base, f_reqs.first.addr, rg_addr_lim, f_reqs.first.size))
&& (f_reqs.first.req_op == REQ_OP_RD));
Fabric_Data rdata = zeroExtend (f_reqs.first.addr);
Bit#(Wd_Data_Periph) rdata = zeroExtend (f_reqs.first.addr);
let rdr = AXI4_RFlit {rid: f_reqs.first.id,
rdata: rdata, // for debugging only
rresp: SLVERR,

View File

@@ -46,8 +46,8 @@ import Vector :: *;
import Cur_Cycle :: *;
import GetPut_Aux :: *;
import Routable :: *;
import AXI4 :: *;
import AXI4Lite :: *;
import BlueBasics :: *;
import BlueAXI4 :: *;
// ================================================================
// Project imports
@@ -153,15 +153,24 @@ module mkSoC_Top #(Reset dm_power_on_reset)
// SoC Boot ROM
Boot_ROM_IFC boot_rom <- mkBoot_ROM;
// AXI4 Deburster in front of Boot_ROM
AXI4_Shim#(Wd_SId, Wd_Addr, Wd_Data, 0, 0, 0, 0, 0)
AXI4_Shim#(Wd_SId, Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0)
boot_rom_axi4_deburster <- mkBurstToNoBurst;
// SoC Memory
Mem_Controller_IFC mem0_controller <- mkMem_Controller;
// AXI4 Deburster in front of SoC Memory
AXI4_Shim#(Wd_SId, Wd_Addr, Wd_Data, 0, 0, 0, 0, 0)
AXI4_Shim#(Wd_SId, Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0)
mem0_controller_axi4_deburster <- mkBurstToNoBurst;
// AXI4 Narrower Master in front of cached memory master
NumProxy #(4) proxyInDepth = error ("don't look inside a proxy");
NumProxy #(4) proxyOutDepth = error ("don't look inside a proxy");
Tuple2 #( AXI4_Slave #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data, 0, 0, 0, 0, 0)
, AXI4_Master #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0) )
wideS_narrowM <- mkAXI4DataWidthShim_WideToNarrow (proxyInDepth, proxyOutDepth);
match {.wideS, .narrowM} = wideS_narrowM;
mkConnection(corew.manager_0, wideS);
// SoC IPs
UART_IFC uart0 <- mkUART;
@@ -174,12 +183,12 @@ module mkSoC_Top #(Reset dm_power_on_reset)
// SoC fabric master connections
// Note: see 'SoC_Map' for 'master_num' definitions
Vector#(Num_Masters, AXI4_Master #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
Vector#(Num_Masters, AXI4_Master #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data_Periph,
0, 0, 0, 0, 0))
master_vector = newVector;
// CPU IMem master to fabric
master_vector[imem_master_num] = corew.manager_0;
master_vector[imem_master_num] = narrowM;
// CPU DMem master to fabric
master_vector[dmem_master_num] = corew.manager_1;
@@ -188,7 +197,7 @@ module mkSoC_Top #(Reset dm_power_on_reset)
// SoC fabric slave connections
// Note: see 'SoC_Map' for 'slave_num' definitions
Vector#(Num_Slaves, AXI4_Slave #(Wd_SId, Wd_Addr, Wd_Data,
Vector#(Num_Slaves, AXI4_Slave #(Wd_SId, Wd_Addr, Wd_Data_Periph,
0, 0, 0, 0, 0))
slave_vector = newVector;
Vector#(Num_Slaves, Range#(Wd_Addr)) route_vector = newVector;

View File

@@ -130,7 +130,7 @@ interface UART_IFC;
method Action set_addr_map (Fabric_Addr addr_base, Fabric_Addr addr_lim);
// Main Fabric Reqs/Rsps
interface AXI4_Slave #(Wd_SId, Wd_Addr, Wd_Data, 0, 0, 0, 0, 0) slave;
interface AXI4_Slave #(Wd_SId, Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0) slave;
// To external console
interface Get #(Bit #(8)) get_to_console;
@@ -367,8 +367,8 @@ module mkUART (UART_IFC);
end
// Align data byte for AXI4 data bus based on fabric-width
Fabric_Data rdata = zeroExtend (rdata_byte);
if ((valueOf (Wd_Data) == 64) && (byte_addr [2:0] == 3'b100))
Bit#(Wd_Data_Periph) rdata = zeroExtend (rdata_byte);
if ((valueOf (Wd_Data_Periph) == 64) && (byte_addr [2:0] == 3'b100))
rdata = rdata << 32;
// Send read-response to bus