Port AXI4 changes from Flute
This commit is contained in:
@@ -29,8 +29,10 @@ import CCTypes :: *;
|
||||
// ----------------
|
||||
// From Bluespec Pipes
|
||||
|
||||
import AXI4_Types :: *;
|
||||
import AXI4 :: *;
|
||||
import SourceSink :: *;
|
||||
import Fabric_Defs :: *;
|
||||
import SoC_Map :: *;
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -38,7 +40,9 @@ interface LLC_AXI4_Adapter_IFC;
|
||||
method Action reset;
|
||||
|
||||
// Fabric master interface for memory
|
||||
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) mem_master;
|
||||
interface AXI4_Master_Synth #(Wd_MId, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) mem_master;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
@@ -58,7 +62,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
// ================================================================
|
||||
// Fabric request/response
|
||||
|
||||
AXI4_Master_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master_xactor <- mkAXI4_Master_Xactor_2;
|
||||
let master_xactor <- mkAXI4_Master_Xactor;
|
||||
|
||||
// For discarding write-responses
|
||||
CreditCounter_IFC #(4) ctr_wr_rsps_pending <- mkCreditCounter; // Max 15 writes outstanding
|
||||
@@ -69,20 +73,20 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
// Send a read-request into the fabric
|
||||
function Action fa_fabric_send_read_req (Fabric_Addr addr);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
araddr: addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
AXI4_Size size = 8;
|
||||
let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_default_mid,
|
||||
araddr: addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
arburst: fabric_default_burst,
|
||||
arlock: fabric_default_lock,
|
||||
arcache: fabric_default_arcache,
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_aruser};
|
||||
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
master_xactor.slave.ar.put(mem_req_rd_addr);
|
||||
|
||||
// Debugging
|
||||
if (cfg_verbosity > 1) begin
|
||||
@@ -94,35 +98,37 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
// Send a write-request into the fabric
|
||||
function Action fa_fabric_send_write_req (Fabric_Addr addr, Fabric_Strb strb, Bit #(64) st_val);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
awaddr: addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
AXI4_Size size = 8;
|
||||
let mem_req_wr_addr = AXI4_AWFlit {awid: fabric_default_mid,
|
||||
awaddr: addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
awburst: fabric_default_burst,
|
||||
awlock: fabric_default_lock,
|
||||
awcache: fabric_default_awcache,
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: 0};
|
||||
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wdata: st_val,
|
||||
wstrb: strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
let mem_req_wr_data = AXI4_WFlit {wdata: st_val,
|
||||
wstrb: strb,
|
||||
wlast: True,
|
||||
wuser: 0};
|
||||
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
master_xactor.slave.aw.put (mem_req_wr_addr);
|
||||
master_xactor.slave.w.put (mem_req_wr_data);
|
||||
|
||||
// Expect a fabric response
|
||||
ctr_wr_rsps_pending.incr;
|
||||
|
||||
// Debugging
|
||||
/*
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display (" To fabric: ", fshow (mem_req_wr_addr));
|
||||
$display (" ", fshow (mem_req_wr_data));
|
||||
end
|
||||
*/
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -159,14 +165,14 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
endrule
|
||||
|
||||
rule rl_handle_read_rsps;
|
||||
let mem_rsp <- pop_o (master_xactor.o_rd_data);
|
||||
let mem_rsp <- get(master_xactor.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 (" ", fshow (mem_rsp));
|
||||
end
|
||||
|
||||
if (mem_rsp.rresp != axi4_resp_okay) begin
|
||||
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));
|
||||
@@ -229,7 +235,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
// Discard write-responses from the fabric
|
||||
|
||||
rule rl_discard_write_rsp;
|
||||
let wr_resp <- pop_o (master_xactor.o_wr_resp);
|
||||
let wr_resp <- get(master_xactor.slave.b);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_discard_write_rsp: beat %0d ", cur_cycle, rg_wr_rsp_beat);
|
||||
@@ -245,7 +251,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
|
||||
ctr_wr_rsps_pending.decr;
|
||||
|
||||
if (wr_resp.bresp != axi4_resp_okay) begin
|
||||
if (wr_resp.bresp != OKAY) begin
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d: LLC_AXI4_Adapter.rl_discard_write_rsp: fabric response error: exit", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
@@ -268,7 +274,7 @@ module mkLLC_AXi4_Adapter #(MemFifoClient #(idT, childT) llc)
|
||||
endmethod
|
||||
|
||||
// Fabric interface for memory
|
||||
interface mem_master = master_xactor.axi_side;
|
||||
interface mem_master = master_xactor.masterSynth;
|
||||
endmodule
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -37,7 +37,8 @@ import ProcTypes :: *;
|
||||
// ----------------
|
||||
// From Bluespec Pipes
|
||||
|
||||
import AXI4_Types :: *;
|
||||
import AXI4 :: *;
|
||||
import SourceSink :: *;
|
||||
import Fabric_Defs :: *;
|
||||
import SoC_Map :: *;
|
||||
|
||||
@@ -49,7 +50,9 @@ interface MMIO_AXI4_Adapter_IFC;
|
||||
interface Server #(MMIOCRq, MMIODataPRs) core_side;
|
||||
|
||||
// Fabric master interface for IO
|
||||
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) mmio_master;
|
||||
interface AXI4_Master_Synth #(Wd_MId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) mmio_master;
|
||||
endinterface
|
||||
|
||||
// ================================================================
|
||||
@@ -71,7 +74,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// ================================================================
|
||||
// Fabric request/response
|
||||
|
||||
AXI4_Master_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master_xactor <- mkAXI4_Master_Xactor_2;
|
||||
let master_xactor <- mkAXI4_Master_Xactor;
|
||||
|
||||
// For discarding write-responses
|
||||
CreditCounter_IFC #(4) ctr_wr_rsps_pending <- mkCreditCounter; // Max 15 writes outstanding
|
||||
@@ -82,8 +85,8 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// Send a read-request into the fabric
|
||||
function Action fa_fabric_send_read_req (Fabric_Addr addr);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_rd_addr = AXI4_Rd_Addr {arid: fabric_default_id,
|
||||
AXI4_Size size = 8;
|
||||
let mem_req_rd_addr = AXI4_ARFlit {arid: fabric_2x3_default_mid,
|
||||
araddr: addr,
|
||||
arlen: 0, // burst len = arlen+1
|
||||
arsize: size,
|
||||
@@ -93,9 +96,9 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
arprot: fabric_default_prot,
|
||||
arqos: fabric_default_qos,
|
||||
arregion: fabric_default_region,
|
||||
aruser: fabric_default_user};
|
||||
aruser: fabric_default_aruser};
|
||||
|
||||
master_xactor.i_rd_addr.enq (mem_req_rd_addr);
|
||||
master_xactor.slave.ar.put(mem_req_rd_addr);
|
||||
|
||||
// Debugging
|
||||
if (cfg_verbosity > 0) begin
|
||||
@@ -107,8 +110,8 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// Send a write-request into the fabric
|
||||
function Action fa_fabric_send_write_req (Fabric_Addr addr, Fabric_Strb strb, Bit #(64) st_val);
|
||||
action
|
||||
AXI4_Size size = axsize_8;
|
||||
let mem_req_wr_addr = AXI4_Wr_Addr {awid: fabric_default_id,
|
||||
AXI4_Size size = 8;
|
||||
let mem_req_wr_addr = AXI4_AWFlit {awid: fabric_2x3_default_mid,
|
||||
awaddr: addr,
|
||||
awlen: 0, // burst len = awlen+1
|
||||
awsize: size,
|
||||
@@ -118,12 +121,12 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
awprot: fabric_default_prot,
|
||||
awqos: fabric_default_qos,
|
||||
awregion: fabric_default_region,
|
||||
awuser: fabric_default_user};
|
||||
awuser: 0};
|
||||
|
||||
let mem_req_wr_data = AXI4_Wr_Data {wdata: st_val,
|
||||
let mem_req_wr_data = AXI4_WFlit {wdata: st_val,
|
||||
wstrb: strb,
|
||||
wlast: True,
|
||||
wuser: fabric_default_user};
|
||||
wuser: 0};
|
||||
|
||||
`ifdef FABRIC64
|
||||
// Work-around for a misbehavior on Xilinx UART and its
|
||||
@@ -136,21 +139,23 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// problem.
|
||||
|
||||
if (strb [7:4] == 0 || strb [3:0] == 0) begin
|
||||
mem_req_wr_addr.awsize = axsize_4;
|
||||
mem_req_wr_addr.awsize = 4;
|
||||
end
|
||||
`endif
|
||||
|
||||
master_xactor.i_wr_addr.enq (mem_req_wr_addr);
|
||||
master_xactor.i_wr_data.enq (mem_req_wr_data);
|
||||
master_xactor.slave.aw.put (mem_req_wr_addr);
|
||||
master_xactor.slave.w.put (mem_req_wr_data);
|
||||
|
||||
// Expect a fabric response
|
||||
ctr_wr_rsps_pending.incr;
|
||||
|
||||
// Debugging
|
||||
/*
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display (" To fabric: ", fshow (mem_req_wr_addr));
|
||||
$display (" ", fshow (mem_req_wr_data));
|
||||
end
|
||||
*/
|
||||
endaction
|
||||
endfunction
|
||||
|
||||
@@ -188,19 +193,19 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// ----------------
|
||||
|
||||
rule rl_handle_read_rsps;
|
||||
let mem_rsp <- pop_o (master_xactor.o_rd_data);
|
||||
let mem_rsp <- get(master_xactor.slave.r);
|
||||
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_handle_read_rsps ", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
end
|
||||
|
||||
if ((cfg_verbosity > 0) && (mem_rsp.rresp != axi4_resp_okay)) begin
|
||||
if ((cfg_verbosity > 0) && (mem_rsp.rresp != OKAY)) begin
|
||||
$display ("%0d: %m.rl_handle_read_rsp: fabric response error", cur_cycle);
|
||||
$display (" ", fshow (mem_rsp));
|
||||
end
|
||||
|
||||
let rsp = MMIODataPRs {valid: (mem_rsp.rresp == axi4_resp_okay),
|
||||
let rsp = MMIODataPRs {valid: (mem_rsp.rresp == OKAY),
|
||||
data: mem_rsp.rdata};
|
||||
f_rsps_to_core.enq (rsp);
|
||||
|
||||
@@ -240,7 +245,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
// Discard write-responses from the fabric
|
||||
|
||||
rule rl_discard_write_rsp;
|
||||
let wr_resp <- pop_o (master_xactor.o_wr_resp);
|
||||
let wr_resp <- get(master_xactor.slave.b);
|
||||
|
||||
if (cfg_verbosity > 0) begin
|
||||
$display ("%0d: %m.rl_discard_write_rsp", cur_cycle);
|
||||
@@ -256,7 +261,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
|
||||
ctr_wr_rsps_pending.decr;
|
||||
|
||||
if (wr_resp.bresp != axi4_resp_okay) begin
|
||||
if (wr_resp.bresp != OKAY) begin
|
||||
// TODO: need to raise a non-maskable interrupt (NMI) here
|
||||
$display ("%0d:%m.rl_discard_write_rsp: ERROR: fabric response error: exit.", cur_cycle);
|
||||
$display (" ", fshow (wr_resp));
|
||||
@@ -297,7 +302,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
|
||||
interface Server core_side = toGPServer (f_reqs_from_core, f_rsps_to_core);
|
||||
|
||||
// Fabric master interface for IO
|
||||
interface mmio_master = master_xactor.axi_side;
|
||||
interface mmio_master = master_xactor.masterSynth;
|
||||
endmodule
|
||||
|
||||
// ================================================================
|
||||
|
||||
@@ -4,7 +4,7 @@ package Proc;
|
||||
|
||||
// Copyright (c) 2018 Massachusetts Institute of Technology
|
||||
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
|
||||
//
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person
|
||||
// obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without
|
||||
@@ -12,10 +12,10 @@ package Proc;
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
// of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
@@ -75,7 +75,7 @@ import LLC_AXI4_Adapter :: *;
|
||||
import MMIO_AXI4_Adapter :: *;
|
||||
|
||||
import SoC_Map :: *;
|
||||
import AXI4_Types :: *;
|
||||
import AXI4 :: *;
|
||||
import Fabric_Defs :: *;
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
|
||||
@@ -14,8 +14,9 @@ import ClientServer :: *;
|
||||
|
||||
import ISA_Decls :: *;
|
||||
|
||||
import AXI4_Types :: *;
|
||||
import AXI4 :: *;
|
||||
import Fabric_Defs :: *;
|
||||
import SoC_Map :: *;
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
import DM_CPU_Req_Rsp :: *;
|
||||
@@ -48,10 +49,14 @@ interface Proc_IFC;
|
||||
// SoC fabric connections
|
||||
|
||||
// Fabric master interface for memory (from LLC)
|
||||
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master0;
|
||||
interface AXI4_Master_Synth #(Wd_MId, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) master0;
|
||||
|
||||
// Fabric master interface for IO (from MMIOPlatform)
|
||||
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) master1;
|
||||
interface AXI4_Master_Synth #(Wd_MId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) master1;
|
||||
|
||||
// ----------------
|
||||
// External interrupts
|
||||
@@ -76,7 +81,9 @@ interface Proc_IFC;
|
||||
// ----------------
|
||||
// Coherent port into LLC (used by Debug Module, DMA engines, ... to read/write memory)
|
||||
|
||||
interface AXI4_Slave_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) debug_module_mem_server;
|
||||
interface AXI4_Slave_Synth #(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;
|
||||
|
||||
`ifdef RVFI_DII
|
||||
interface Toooba_RVFI_DII_Server rvfi_dii_server;
|
||||
|
||||
@@ -19,11 +19,9 @@ package CoreW;
|
||||
// This package defines:
|
||||
// Core_IFC
|
||||
// mkCore #(Core_IFC)
|
||||
// mkFabric_2x3 -- specialized AXI4 fabric used inside this core
|
||||
//
|
||||
// mkCoreW instantiates:
|
||||
// - mkProc (the RISC-V CPU, a version of MIT's RISCY-OOO)
|
||||
// - mkFabric_2x3
|
||||
// - mkPLIC_16_2_7
|
||||
// - mkTV_Encode (Tandem-Verification logic, optional: INCLUDE_TANDEM_VERIF)
|
||||
// - mkDebug_Module (RISC-V Debug Module, optional: INCLUDE_GDB_CONTROL)
|
||||
@@ -44,6 +42,9 @@ import Clocks :: *;
|
||||
|
||||
import Cur_Cycle :: *;
|
||||
import GetPut_Aux :: *;
|
||||
import Routable :: *;
|
||||
import AXI4 :: *;
|
||||
import TagControllerAXI :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project imports
|
||||
@@ -56,9 +57,7 @@ import ProcTypes :: *;
|
||||
// From Toooba
|
||||
|
||||
// Main fabric
|
||||
import AXI4_Types :: *;
|
||||
import AXI4_Fabric :: *;
|
||||
import Fabric_Defs :: *; // for Wd_Id, Wd_Addr, Wd_Data, Wd_User
|
||||
import Fabric_Defs :: *; // for Wd_Id, Wd_Addr, Wd_Data...
|
||||
import SoC_Map :: *;
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
@@ -148,9 +147,13 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
// RISCY-OOO processor
|
||||
// TODO (when we do multicore): need resets for each core.
|
||||
Proc_IFC proc <- mkProc (reset_by hart0_reset);
|
||||
// handle imem interface
|
||||
let tmp0 <- fromAXI4_Master_Synth(proc.master0);
|
||||
let tmp1 <- toUnguarded_AXI4_Master(tmp0);
|
||||
let proc_imem = toAXI4_Master_Synth(extendIDFields(zeroMasterUserFields(tmp1), 0));
|
||||
|
||||
// A 2x3 fabric for connecting {CPU, Debug_Module} to {Fabric, PLIC}
|
||||
Fabric_2x3_IFC fabric_2x3 <- mkFabric_2x3;
|
||||
// AXI4 tagController
|
||||
let tagController <- mkTagControllerAXI(reset_by hart0_reset); // TODO double check if reseting like this is good enough
|
||||
|
||||
// PLIC (Platform-Level Interrupt Controller)
|
||||
PLIC_IFC_16_2_7 plic <- mkPLIC_16_2_7;
|
||||
@@ -310,8 +313,7 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
// BEGIN SECTION: no DM
|
||||
|
||||
// No DM, so 'DM bus master' is AXI4 dummy
|
||||
AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User)
|
||||
dm_master_local = dummy_AXI4_Master_ifc;
|
||||
let dm_master_local = culDeSac;
|
||||
|
||||
`ifdef INCLUDE_TANDEM_VERIF
|
||||
// TV, no DM: stub out the dm input to TV
|
||||
@@ -326,14 +328,41 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
// Connect the local 2x3 fabric
|
||||
|
||||
// Masters on the local 2x3 fabric
|
||||
mkConnection (proc.master1, fabric_2x3.v_from_masters [cpu_dmem_master_num]);
|
||||
mkConnection (dm_master_local, fabric_2x3.v_from_masters [debug_module_sba_master_num]);
|
||||
Vector#(Num_Masters_2x3,
|
||||
AXI4_Master_Synth #(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;
|
||||
master_vector[cpu_dmem_master_num] = proc.master1;
|
||||
master_vector[debug_module_sba_master_num] = dm_master_local;
|
||||
|
||||
// Slaves on the local 2x3 fabric
|
||||
// Two of the slaves are connected here.
|
||||
// The third slave (default slave) is taken out directly to the Core interface
|
||||
mkConnection (fabric_2x3.v_to_slaves [plic_slave_num], plic.axi4_slave);
|
||||
mkConnection (fabric_2x3.v_to_slaves [llc_slave_num], proc.debug_module_mem_server);
|
||||
// default slave is forwarded out directly to the Core interface
|
||||
Vector#(Num_Slaves_2x3,
|
||||
AXI4_Slave_Synth #(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;
|
||||
slave_vector[default_slave_num] = toAXI4_Slave_Synth(tagController.slave);
|
||||
slave_vector[llc_slave_num] = proc.debug_module_mem_server;
|
||||
slave_vector[plic_slave_num] = plic.axi4_slave;
|
||||
|
||||
function Vector#(Num_Slaves_2x3, Bool) route_2x3 (Bit#(Wd_Addr) addr);
|
||||
Vector#(Num_Slaves_2x3, 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))
|
||||
res[plic_slave_num] = True;
|
||||
else
|
||||
res[default_slave_num] = True;
|
||||
Bit #(24) topBits = truncateLSB(addr); //XXX TODO Tag controller masks to 40 bits
|
||||
if (topBits != 0) res = replicate(False);
|
||||
return res;
|
||||
endfunction
|
||||
|
||||
mkAXI4Bus_Synth (route_2x3, master_vector, slave_vector);
|
||||
|
||||
// ================================================================
|
||||
// Connect external interrupt lines from PLIC to CPU
|
||||
@@ -363,8 +392,8 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
// Start
|
||||
|
||||
method Action start (Bit #(64) tohost_addr, Bit #(64) fromhost_addr);
|
||||
plic.set_addr_map (zeroExtend (soc_map.m_plic_addr_base),
|
||||
zeroExtend (soc_map.m_plic_addr_lim));
|
||||
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 (pc, tohost_addr, fromhost_addr);
|
||||
@@ -383,10 +412,10 @@ module mkCoreW #(Reset dm_power_on_reset)
|
||||
// AXI4 Fabric interfaces
|
||||
|
||||
// IMem to Fabric master interface
|
||||
interface AXI4_Master_IFC cpu_imem_master = proc.master0;
|
||||
interface cpu_imem_master = proc_imem;
|
||||
|
||||
// DMem to Fabric master interface
|
||||
interface AXI4_Master_IFC cpu_dmem_master = fabric_2x3.v_to_slaves [default_slave_num];
|
||||
interface cpu_dmem_master = toAXI4_Master_Synth(tagController.master);
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// External interrupt sources
|
||||
@@ -442,65 +471,16 @@ endmodule: mkCoreW
|
||||
// ----------------
|
||||
// Fabric port numbers for masters
|
||||
|
||||
typedef 2 Num_Masters_2x3;
|
||||
|
||||
typedef Bit #(TLog #(Num_Masters_2x3)) Master_Num_2x3;
|
||||
|
||||
Master_Num_2x3 cpu_dmem_master_num = 0;
|
||||
Master_Num_2x3 debug_module_sba_master_num = 1;
|
||||
|
||||
// ----------------
|
||||
// Fabric port numbers for slaves
|
||||
|
||||
typedef 3 Num_Slaves_2x3;
|
||||
|
||||
typedef Bit #(TLog #(Num_Slaves_2x3)) Slave_Num_2x3;
|
||||
|
||||
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)
|
||||
|
||||
// ----------------
|
||||
// Specialization of parameterized AXI4 fabric for 2x3 Core fabric
|
||||
|
||||
typedef AXI4_Fabric_IFC #(Num_Masters_2x3,
|
||||
Num_Slaves_2x3,
|
||||
Wd_Id,
|
||||
Wd_Addr,
|
||||
Wd_Data,
|
||||
Wd_User) Fabric_2x3_IFC;
|
||||
|
||||
// ----------------
|
||||
|
||||
(* synthesize *)
|
||||
module mkFabric_2x3 (Fabric_2x3_IFC);
|
||||
|
||||
// System address map
|
||||
SoC_Map_IFC soc_map <- mkSoC_Map;
|
||||
|
||||
// ----------------
|
||||
// Slave address decoder
|
||||
// Any addr is legal, and there is only one slave to service it.
|
||||
|
||||
function Tuple2 #(Bool, Slave_Num_2x3) fn_addr_to_slave_num_2x3 (Fabric_Addr addr);
|
||||
if ( (soc_map.m_mem0_controller_addr_base <= addr)
|
||||
&& (addr < soc_map.m_mem0_controller_addr_lim))
|
||||
return tuple2 (True, llc_slave_num);
|
||||
|
||||
else if ( (soc_map.m_plic_addr_base <= addr)
|
||||
&& (addr < soc_map.m_plic_addr_lim))
|
||||
return tuple2 (True, plic_slave_num);
|
||||
|
||||
else
|
||||
return tuple2 (True, default_slave_num);
|
||||
endfunction
|
||||
|
||||
AXI4_Fabric_IFC #(Num_Masters_2x3, Num_Slaves_2x3, Wd_Id, Wd_Addr, Wd_Data, Wd_User)
|
||||
fabric <- mkAXI4_Fabric (fn_addr_to_slave_num_2x3);
|
||||
|
||||
return fabric;
|
||||
endmodule: mkFabric_2x3
|
||||
|
||||
// ================================================================
|
||||
|
||||
endpackage
|
||||
|
||||
@@ -21,11 +21,14 @@ import Vector :: *;
|
||||
import GetPut :: *;
|
||||
import ClientServer :: *;
|
||||
|
||||
// ----------------
|
||||
// BSV additional libs
|
||||
import AXI4 :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project imports
|
||||
|
||||
// Main fabric
|
||||
import AXI4_Types :: *;
|
||||
import Fabric_Defs :: *;
|
||||
|
||||
// External interrupt request interface
|
||||
@@ -64,10 +67,12 @@ interface CoreW_IFC #(numeric type t_n_interrupt_sources);
|
||||
// AXI4 Fabric interfaces
|
||||
|
||||
// CPU IMem to Fabric master interface
|
||||
interface AXI4_Master_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) cpu_imem_master;
|
||||
interface AXI4_Master_Synth #(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_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) cpu_dmem_master;
|
||||
interface AXI4_Master_Synth #(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data,
|
||||
0, 0, 0, 0, 0) cpu_dmem_master;
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// External interrupt sources
|
||||
|
||||
@@ -17,20 +17,23 @@ package Fabric_Defs;
|
||||
// ================================================================
|
||||
// BSV lib imports
|
||||
|
||||
// None
|
||||
import AXI4 :: *;
|
||||
import ISA_Decls_CHERI :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project imports
|
||||
// Core local Fabric parameters
|
||||
|
||||
import AXI4_Types :: *;
|
||||
typedef 2 Num_Masters_2x3;
|
||||
typedef 3 Num_Slaves_2x3;
|
||||
|
||||
// ================================================================
|
||||
// Fabric parameters
|
||||
typedef Bit#(TLog #(Num_Masters_2x3)) Master_Num_2x3;
|
||||
typedef Bit#(TLog #(Num_Slaves_2x3)) Slave_Num_2x3;
|
||||
|
||||
// ----------------
|
||||
// Width of fabric 'id' buses
|
||||
typedef 4 Wd_Id;
|
||||
typedef Bit #(Wd_Id) Fabric_Id;
|
||||
// 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;
|
||||
|
||||
// ----------------
|
||||
// Width of fabric 'addr' buses
|
||||
@@ -46,23 +49,40 @@ typedef TDiv #(Wd_Addr, 8) Bytes_per_Fabric_Addr;
|
||||
Integer bytes_per_fabric_addr = valueOf (Bytes_per_Fabric_Addr);
|
||||
|
||||
// ----------------
|
||||
// Width of fabric 'data' buses
|
||||
`ifdef FABRIC64
|
||||
typedef 64 Wd_Data;
|
||||
`else
|
||||
typedef 32 Wd_Data;
|
||||
`endif
|
||||
// Widths of the main bus data are 128 bits. Peripherals each have a shim
|
||||
// converting this down to 64 bits (and stripping tags).
|
||||
// (caches <==> Bus <==> (tag controller) <==> main memory
|
||||
// |
|
||||
// Periph
|
||||
|
||||
typedef Bit #(Wd_Data) Fabric_Data;
|
||||
typedef Bit #(TDiv #(Wd_Data, 8)) Fabric_Strb;
|
||||
typedef 64 Wd_Data;
|
||||
|
||||
// ----------------
|
||||
// Width of fabric 'user' datapaths. Carry capability tags on data lines.
|
||||
typedef 0 Wd_AW_User;
|
||||
typedef 0 Wd_B_User;
|
||||
typedef 0 Wd_AR_User;
|
||||
typedef TMax#(TDiv#(Wd_Data, CLEN),1) Wd_W_User;
|
||||
typedef TMax#(TDiv#(Wd_Data, CLEN),1) Wd_R_User;
|
||||
|
||||
typedef TDiv #(Wd_Data, 8) Bytes_per_Fabric_Data;
|
||||
Integer bytes_per_fabric_data = valueOf (Bytes_per_Fabric_Data);
|
||||
|
||||
typedef Bit #(Wd_Data) Fabric_Data;
|
||||
typedef Bit #(TDiv #(Wd_Data, 8)) Fabric_Strb;
|
||||
|
||||
// ----------------
|
||||
// Width of fabric 'user' datapaths
|
||||
typedef 0 Wd_User;
|
||||
typedef Bit #(Wd_User) Fabric_User;
|
||||
typedef 64 Wd_Data_Periph;
|
||||
|
||||
typedef 0 Wd_AW_User_Periph;
|
||||
typedef 0 Wd_W_User_Periph;
|
||||
typedef 0 Wd_B_User_Periph;
|
||||
typedef 0 Wd_AR_User_Periph;
|
||||
typedef 0 Wd_R_User_Periph;
|
||||
|
||||
typedef Bit #(Wd_Data_Periph) Fabric_Data_Periph;
|
||||
typedef Bit #(TDiv #(Wd_Data_Periph, 8)) Fabric_Strb_Periph;
|
||||
typedef TDiv #(Wd_Data_Periph, 8) Bytes_per_Fabric_Data_Periph;
|
||||
|
||||
// ----------------
|
||||
// Number of zero LSBs in a fabric address aligned to the fabric data width
|
||||
@@ -72,16 +92,20 @@ Integer zlsbs_aligned_fabric_addr = valueOf (ZLSBs_Aligned_Fabric_Addr);
|
||||
|
||||
// ================================================================
|
||||
// AXI4 defaults for this project
|
||||
|
||||
Fabric_Id fabric_default_id = 0;
|
||||
AXI4_Burst fabric_default_burst = axburst_incr;
|
||||
AXI4_Lock fabric_default_lock = axlock_normal;
|
||||
AXI4_Cache fabric_default_arcache = arcache_dev_nonbuf;
|
||||
AXI4_Cache fabric_default_awcache = awcache_dev_nonbuf;
|
||||
AXI4_Prot fabric_default_prot = { axprot_2_data, axprot_1_secure, axprot_0_unpriv };
|
||||
AXI4_QoS fabric_default_qos = 0;
|
||||
AXI4_Region fabric_default_region = 0;
|
||||
Fabric_User fabric_default_user = ?;
|
||||
Bit#(Wd_MId_2x3) fabric_2x3_default_mid = 0;
|
||||
Bit#(Wd_MId) fabric_default_mid = 0;
|
||||
AXI4_Burst fabric_default_burst = INCR;
|
||||
AXI4_Lock fabric_default_lock = NORMAL;
|
||||
AXI4_Cache fabric_default_arcache = arcache_dev_nonbuf;
|
||||
AXI4_Cache fabric_default_awcache = awcache_dev_nonbuf;
|
||||
AXI4_Prot fabric_default_prot = axi4Prot(DATA, SECURE, UNPRIV);
|
||||
AXI4_QoS fabric_default_qos = 0;
|
||||
AXI4_Region fabric_default_region = 0;
|
||||
Bit#(Wd_AW_User) fabric_default_awuser = 0;
|
||||
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;
|
||||
|
||||
// ================================================================
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ import Assert :: *;
|
||||
import Cur_Cycle :: *;
|
||||
import GetPut_Aux :: *;
|
||||
import Semi_FIFOF :: *;
|
||||
import SourceSink :: *;
|
||||
import AXI4 :: *;
|
||||
|
||||
// ================================================================
|
||||
// Project imports
|
||||
|
||||
import AXI4_Types :: *;
|
||||
import AXI4_Fabric :: *;
|
||||
import Fabric_Defs :: *; // for Wd_Id, Wd_Addr, Wd_Data, Wd_User
|
||||
import Fabric_Defs :: *; // for Wd_SId_2x3, Wd_Addr, Wd_Data...
|
||||
|
||||
// ================================================================
|
||||
// Change bitwidth without requiring < or > constraints.
|
||||
@@ -84,7 +84,9 @@ 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_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) axi4_slave;
|
||||
interface AXI4_Slave_Synth #(Wd_SId_2x3, Wd_Addr, Wd_Data,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User,
|
||||
Wd_AR_User, Wd_R_User) axi4_slave;
|
||||
|
||||
// sources
|
||||
interface Vector #(t_n_external_sources, PLIC_Source_IFC) v_sources;
|
||||
@@ -126,7 +128,9 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
Reg #(Bit #(64)) rg_addr_lim <- mkRegU;
|
||||
|
||||
// Connector to AXI4 fabric
|
||||
AXI4_Slave_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) slave_xactor <- mkAXI4_Slave_Xactor;
|
||||
AXI4_Slave_Width_Xactor#(Wd_SId_2x3, Wd_Addr, Wd_Data_Periph, Wd_Data,
|
||||
Wd_AW_User_Periph, Wd_W_User_Periph, Wd_B_User_Periph, Wd_AR_User_Periph, Wd_R_User_Periph,
|
||||
Wd_AW_User, Wd_W_User, Wd_B_User, Wd_AR_User, Wd_R_User) slave_xactor <- mkAXI4_Slave_Zeroing_Xactor;
|
||||
|
||||
// ----------------
|
||||
// Per-interrupt source state
|
||||
@@ -228,7 +232,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
for (Integer source_id = 0; source_id < n_sources; source_id = source_id + 1)
|
||||
vvrg_ie [target_id][source_id] <= False;
|
||||
|
||||
slave_xactor.reset;
|
||||
slave_xactor.clear;
|
||||
|
||||
f_reset_rsps.enq (?);
|
||||
endrule
|
||||
@@ -243,7 +247,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
rule rl_process_rd_req (! f_reset_reqs.notEmpty);
|
||||
|
||||
let rda <- pop_o (slave_xactor.o_rd_addr);
|
||||
let rda <- get(slave_xactor.master.ar);
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_rd_req:", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
@@ -251,17 +255,17 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
let addr_offset = rda.araddr - rg_addr_base;
|
||||
Bit #(64) rdata = 0;
|
||||
AXI4_Resp rresp = axi4_resp_okay;
|
||||
AXI4_Resp rresp = OKAY;
|
||||
|
||||
if (rda.araddr < rg_addr_base) begin
|
||||
// Technically this should not happen: the fabric should
|
||||
// never have delivered such an addr to this IP.
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
rresp = axi4_resp_decerr;
|
||||
rresp = DECERR;
|
||||
end
|
||||
|
||||
// Source Priority
|
||||
// Source Priority
|
||||
else if (addr_offset < 'h1000) begin
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
@@ -272,7 +276,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle, source_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Source IPs (interrupt pending).
|
||||
@@ -297,7 +301,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Source IEs (interrupt enables) for a target
|
||||
@@ -324,7 +328,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle, source_id_base, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Target threshold
|
||||
@@ -338,7 +342,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle, target_id, rdata);
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
// Interrupt service claim by target
|
||||
@@ -353,7 +357,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
$display (" Still servicing interrupt from source %0d", vrg_servicing_source [target_id]);
|
||||
$display (" Trying to claim service for source %0d", max_id);
|
||||
$display (" Ignoring.");
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = SLVERR;
|
||||
end
|
||||
else begin
|
||||
if (max_id != 0) begin
|
||||
@@ -369,13 +373,13 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
end
|
||||
end
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = SLVERR;
|
||||
end
|
||||
|
||||
else
|
||||
rresp = axi4_resp_slverr;
|
||||
rresp = SLVERR;
|
||||
|
||||
if (rresp != axi4_resp_okay) begin
|
||||
if (rresp != OKAY) begin
|
||||
$display ("%0d: ERROR: PLIC.rl_process_rd_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (rda));
|
||||
end
|
||||
@@ -385,12 +389,12 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
// Send read-response to bus
|
||||
Fabric_Data x = truncate (rdata);
|
||||
let rdr = AXI4_Rd_Data {rid: rda.arid,
|
||||
rdata: x,
|
||||
rresp: rresp,
|
||||
rlast: True,
|
||||
ruser: rda.aruser};
|
||||
slave_xactor.i_rd_data.enq (rdr);
|
||||
let rdr = AXI4_RFlit {rid: rda.arid,
|
||||
rdata: x,
|
||||
rresp: rresp,
|
||||
rlast: True,
|
||||
ruser: rda.aruser}; // XXX This requires that Wd_AR_User == Wd_R_User
|
||||
slave_xactor.master.r.put(rdr);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_rd_req", cur_cycle);
|
||||
@@ -406,8 +410,8 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
|
||||
rule rl_process_wr_req (! f_reset_reqs.notEmpty);
|
||||
|
||||
let wra <- pop_o (slave_xactor.o_wr_addr);
|
||||
let wrd <- pop_o (slave_xactor.o_wr_data);
|
||||
let wra <- get(slave_xactor.master.aw);
|
||||
let wrd <- get(slave_xactor.master.w);
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.rl_process_wr_req", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
@@ -418,7 +422,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
let wdata32 = (((valueOf (Wd_Data) == 64) && ((addr_offset & 'h7) == 'h4))
|
||||
? wrd.wdata [63:32]
|
||||
: wrd.wdata [31:0]);
|
||||
let bresp = axi4_resp_okay;
|
||||
let bresp = OKAY;
|
||||
|
||||
if (wra.awaddr < rg_addr_base) begin
|
||||
// Technically this should not happen: the fabric should
|
||||
@@ -426,10 +430,10 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
bresp = axi4_resp_decerr;
|
||||
bresp = DECERR;
|
||||
end
|
||||
|
||||
// Source priority
|
||||
// Source priority
|
||||
else if (addr_offset < 'h1000) begin
|
||||
Bit #(T_wd_source_id) source_id = truncate (addr_offset [11:2]);
|
||||
if ((0 < source_id) && (source_id <= fromInteger (n_sources - 1))) begin
|
||||
@@ -441,7 +445,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
end
|
||||
else begin
|
||||
// Note: write to source_id 0 is error; should it just be ignored?
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = SLVERR;
|
||||
end
|
||||
end
|
||||
|
||||
@@ -456,7 +460,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle, source_id_base);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
// Source IEs (interrupt enables) for a target
|
||||
@@ -479,7 +483,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle, target_id, source_id_base, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
// Target threshold
|
||||
@@ -493,7 +497,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle, target_id, wdata32);
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
// Interrupt service completion by target
|
||||
@@ -515,27 +519,27 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
cur_cycle);
|
||||
$display (" Completion message from target %0d to source %0d", target_id, source_id);
|
||||
$display (" Ignoring");
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = SLVERR;
|
||||
end
|
||||
end
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = SLVERR;
|
||||
end
|
||||
|
||||
else
|
||||
bresp = axi4_resp_slverr;
|
||||
bresp = SLVERR;
|
||||
|
||||
if (bresp != axi4_resp_okay) begin
|
||||
if (bresp != OKAY) begin
|
||||
$display ("%0d: ERROR: PLIC.rl_process_wr_req: unrecognized addr", cur_cycle);
|
||||
$display (" ", fshow (wra));
|
||||
$display (" ", fshow (wrd));
|
||||
end
|
||||
|
||||
// Send write-response to bus
|
||||
let wrr = AXI4_Wr_Resp {bid: wra.awid,
|
||||
bresp: bresp,
|
||||
buser: wra.awuser};
|
||||
slave_xactor.i_wr_resp.enq (wrr);
|
||||
let wrr = AXI4_BFlit {bid: wra.awid,
|
||||
bresp: bresp,
|
||||
buser: wra.awuser}; // XXX This requires that Wd_AW_User == Wd_B_User
|
||||
slave_xactor.master.b.put(wrr);
|
||||
|
||||
if (cfg_verbosity > 1) begin
|
||||
$display ("%0d: PLIC.AXI4.rl_process_wr_req", cur_cycle);
|
||||
@@ -610,7 +614,7 @@ module mkPLIC (PLIC_IFC #(t_n_external_sources, t_n_targets, t_max_priority))
|
||||
endmethod
|
||||
|
||||
// Memory-mapped access
|
||||
interface axi4_slave = slave_xactor.axi_side;
|
||||
interface axi4_slave = slave_xactor.slaveSynth;
|
||||
|
||||
// sources
|
||||
interface v_sources = genWith (fn_mk_PLIC_Source_IFC);
|
||||
|
||||
@@ -238,7 +238,7 @@ deriving (Eq, FShow, Bits);
|
||||
module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
Bool verbose = False;
|
||||
|
||||
Integer verbosity = 0; // Bluespec: for lightweight verbosity trace
|
||||
Integer verbosity = 1; // Bluespec: for lightweight verbosity trace
|
||||
|
||||
// Used to inform tandem-verifier about program order.
|
||||
// 0 is used to indicate we've just come out of reset
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
// of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be
|
||||
// included in all copies or substantial portions of the Software.
|
||||
//
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
@@ -72,8 +72,10 @@ import MemLoader::*;
|
||||
// ----------------
|
||||
// From Toooba
|
||||
|
||||
import AXI4_Types :: *;
|
||||
import AXI4 :: *;
|
||||
import SourceSink :: *;
|
||||
import Fabric_Defs :: *;
|
||||
import SoC_Map :: *;
|
||||
import Semi_FIFOF :: *;
|
||||
|
||||
// ================================================================
|
||||
@@ -125,7 +127,9 @@ module mkLLCDmaConnect #(
|
||||
DmaServer#(LLCDmaReqId) llc,
|
||||
// MemLoaderMemClient memLoader, // REPLACED BY AXI4_Slave_interface
|
||||
Vector#(CoreNum, TlbMemClient) tlb
|
||||
)(AXI4_Slave_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User)) provisos (
|
||||
)(AXI4_Slave_Synth #(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))
|
||||
);
|
||||
Bool verbose = False;
|
||||
@@ -136,7 +140,7 @@ module mkLLCDmaConnect #(
|
||||
FIFOF #(Bit #(3)) f_dword_in_line <- mkFIFOF;
|
||||
|
||||
// Slave transactor for requests from Debug Module
|
||||
AXI4_Slave_Xactor_IFC #(Wd_Id, Wd_Addr, Wd_Data, Wd_User) axi4_slave_xactor <- mkAXI4_Slave_Xactor;
|
||||
let axi4_slave_xactor <- mkAXI4_Slave_Xactor;
|
||||
|
||||
// ================================================================
|
||||
// These regs are a 1-location local cache for an LLC Cache Line,
|
||||
@@ -155,10 +159,10 @@ module mkLLCDmaConnect #(
|
||||
// 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 (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
&& (fn_addr_is_in_line (axi4_slave_xactor.master.aw.peek.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let wr_addr <- pop_o (axi4_slave_xactor.o_wr_addr);
|
||||
let wr_data <- pop_o (axi4_slave_xactor.o_wr_data);
|
||||
let wr_addr <- get (axi4_slave_xactor.master.aw);
|
||||
let wr_data <- get (axi4_slave_xactor.master.w);
|
||||
Addr addr = wr_addr.awaddr;
|
||||
Bit #(64) data = wr_data.wdata;
|
||||
Bit #(64) mask = fn_expand_strb_to_mask (wr_data.wstrb);
|
||||
@@ -176,11 +180,11 @@ module mkLLCDmaConnect #(
|
||||
rg_cacheline_cache_dirty_delay <= '1; // start write-back delay countdown
|
||||
|
||||
// Send response to external client
|
||||
AXI4_Wr_Resp #(Wd_Id, Wd_User)
|
||||
wr_resp = AXI4_Wr_Resp {bid: 0, // TODO: change uniformly to Fabric_id
|
||||
bresp: axi4_resp_okay,
|
||||
buser: ?};
|
||||
axi4_slave_xactor.i_wr_resp.enq (wr_resp);
|
||||
axi4_slave_xactor.master.b.put(AXI4_BFlit{
|
||||
bid: 0, // TODO: change uniformly to Fabric_id
|
||||
bresp: OKAY,
|
||||
buser: ?
|
||||
});
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_handle_MemLoader_st_req: addr %0h data %0h strb %0h",
|
||||
@@ -196,9 +200,9 @@ module mkLLCDmaConnect #(
|
||||
// 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 (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
&& (fn_addr_is_in_line (axi4_slave_xactor.master.ar.peek.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let rd_addr <- pop_o (axi4_slave_xactor.o_rd_addr);
|
||||
let rd_addr <- get (axi4_slave_xactor.master.ar);
|
||||
Addr addr = rd_addr.araddr;
|
||||
|
||||
// Read rg_cacheline_cache as 64-bit words
|
||||
@@ -207,13 +211,13 @@ module mkLLCDmaConnect #(
|
||||
Bit #(64) dword = line_dwords [dword_in_line];
|
||||
|
||||
// Send response to external client
|
||||
AXI4_Rd_Data #(Wd_Id, Wd_Data, Wd_User)
|
||||
rd_data = AXI4_Rd_Data {rid: 0, // TODO: fixup
|
||||
rdata: dword,
|
||||
rresp: axi4_resp_okay,
|
||||
rlast: True,
|
||||
ruser: ?};
|
||||
axi4_slave_xactor.i_rd_data.enq (rd_data);
|
||||
axi4_slave_xactor.master.r.put(AXI4_RFlit{
|
||||
rid: 0, // TODO: fixup
|
||||
rdata: dword,
|
||||
rresp: OKAY,
|
||||
rlast: True,
|
||||
ruser: ?
|
||||
});
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_handle_MemLoader_ld_req: addr %0h", cur_cycle, rd_addr.araddr);
|
||||
@@ -257,12 +261,12 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// 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 (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.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", axi4_slave_xactor.o_wr_addr.first.awaddr);
|
||||
$display (" New addr %0h", axi4_slave_xactor.master.aw.peek.awaddr);
|
||||
end
|
||||
|
||||
fa_writeback;
|
||||
@@ -271,12 +275,12 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// 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 (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.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", axi4_slave_xactor.o_wr_addr.first.awaddr);
|
||||
$display (" New addr %0h", axi4_slave_xactor.master.aw.peek.awaddr);
|
||||
end
|
||||
|
||||
fa_writeback;
|
||||
@@ -315,9 +319,9 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// 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 (axi4_slave_xactor.o_wr_addr.first.awaddr,
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.master.aw.peek.awaddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let addr = axi4_slave_xactor.o_wr_addr.first.awaddr;
|
||||
let addr = axi4_slave_xactor.master.aw.peek.awaddr;
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_req_st for addr %0h", cur_cycle, addr);
|
||||
@@ -329,9 +333,9 @@ module mkLLCDmaConnect #(
|
||||
|
||||
// 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 (axi4_slave_xactor.o_rd_addr.first.araddr,
|
||||
&& (! fn_addr_is_in_line (axi4_slave_xactor.master.ar.peek.araddr,
|
||||
rg_cacheline_cache_addr)));
|
||||
let addr = axi4_slave_xactor.o_rd_addr.first.araddr;
|
||||
let addr = axi4_slave_xactor.master.ar.peek.araddr;
|
||||
|
||||
if (verbosity >= 2) begin
|
||||
$display ("%0d: %m.rl_cacheline_cache_reload_req_ld for addr %0h", cur_cycle, addr);
|
||||
@@ -426,5 +430,5 @@ module mkLLCDmaConnect #(
|
||||
// ================================================================
|
||||
// INTERFACE
|
||||
|
||||
return axi4_slave_xactor.axi_side;
|
||||
return axi4_slave_xactor.slaveSynth;
|
||||
endmodule
|
||||
|
||||
Reference in New Issue
Block a user