Use updated Bluestuff library, and also support uncached 128-bit transactions through MMIO.

This commit is contained in:
jon
2020-06-24 11:57:43 +01:00
parent 56cd502145
commit 312d0316da
4 changed files with 78 additions and 31 deletions

View File

@@ -17,6 +17,7 @@ import ConfigReg :: *;
import FIFOF :: *;
import GetPut :: *;
import ClientServer :: *;
import Vector :: *;
// ----------------
// BSV additional libs
@@ -51,9 +52,9 @@ interface MMIO_AXI4_Adapter_IFC;
interface Server #(MMIOCRq, MMIODataPRs) core_side;
// Fabric master interface for IO
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;
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;
endinterface
// ================================================================
@@ -76,7 +77,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
// ================================================================
// Fabric request/response
let master_xactor <- mkAXI4_Master_Xactor;
let master_shim <- mkAXI4ShimFF;
// For discarding write-responses
CreditCounter_IFC #(4) ctr_wr_rsps_pending <- mkCreditCounter; // Max 15 writes outstanding
@@ -100,7 +101,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
arregion: fabric_default_region,
aruser: fabric_default_aruser};
master_xactor.slave.ar.put(mem_req_rd_addr);
master_shim.slave.ar.put(mem_req_rd_addr);
read_req_addr <= addr;
// Debugging
@@ -146,8 +147,8 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
end
`endif
master_xactor.slave.aw.put (mem_req_wr_addr);
master_xactor.slave.w.put (mem_req_wr_data);
master_shim.slave.aw.put (mem_req_wr_addr);
master_shim.slave.w.put (mem_req_wr_data);
// Expect a fabric response
ctr_wr_rsps_pending.incr;
@@ -196,7 +197,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
// ----------------
rule rl_handle_read_rsps;
let mem_rsp <- get(master_xactor.slave.r);
let mem_rsp <- get(master_shim.slave.r);
dynamicAssert(mem_rsp.rlast, "TODO, implement multi-flit transactions");
if (cfg_verbosity > 0) begin
@@ -222,8 +223,11 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
// ================================================================
// Handle write requests and responses
// Each 128b word takes 2 beats, each handling 64 bits
Reg #(Bit #(1)) rg_wr_req_beat <- mkReg (0);
rule rl_handle_write_req (f_reqs_from_core.first.func matches St);
let req <- pop (f_reqs_from_core);
let req = f_reqs_from_core.first;
if (cfg_verbosity > 0) begin
$display ("%d: %m.rl_handle_write_req: St request:", cur_cycle);
@@ -234,9 +238,55 @@ 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.
dynamicAssert(pack(req.byteEn)[15:8] == 0, "TODO, handle multiflit transactions");
if (soc_map.m_is_IO_addr (req.addr))
fa_fabric_send_write_req (req.addr, truncate(pack(req.byteEn)), fromMemTaggedData(req.data));
else begin
if (soc_map.m_is_IO_addr (req.addr)) begin
//fa_fabric_send_write_req (req.addr, truncate(pack(req.byteEn)), fromMemTaggedData(req.data));
// on first flit...
// ================
if (rg_wr_req_beat == 0) begin
AXI4_Size size = 8;
let mem_req_wr_addr = AXI4_AWFlit {awid: fabric_2x3_default_mid,
awaddr: req.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};
`ifdef FABRIC64
// Work-around for a misbehavior on Xilinx UART and its
// Xilinx AXI4 adapter. On 64-bit fabrics, for a write where
// axsize says '8 bytes' but wstrb is for <= 4 bytes, the
// adapter converts it two 32-bit writes, one of which has
// wstrb=4'b0000. The Xilinx UART, in turn ignores wstrb and
// therefore performs a spurious write. This workaround
// changes axsize for such writes to '4 bytes', avoiding this
// problem.
if (countOnes(pack(req.byteEn)) <= 4)
mem_req_wr_addr.awsize = 4;
`endif
master_shim.slave.aw.put (mem_req_wr_addr);
// Expect a fabric response
ctr_wr_rsps_pending.incr;
end
// on last flit...
// ===============
if (rg_wr_req_beat == 1) f_reqs_from_core.deq;
// on each flit...
// ===============
Vector #(2, Bit #(8)) line_strb = unpack(pack(req.byteEn));
master_shim.slave.w.put (AXI4_WFlit {wdata: req.data.data[rg_wr_req_beat],
wstrb: line_strb[rg_wr_req_beat],
wlast: True,
wuser: 0});
// increment flit counter
rg_wr_req_beat <= rg_wr_req_beat + 1;
end else begin
let rsp = MMIODataPRs {valid: False,
data: toMemTaggedData(req.addr)}; // For debugging convenience only
f_rsps_to_core.enq (rsp);
@@ -252,7 +302,7 @@ module mkMMIO_AXI4_Adapter (MMIO_AXI4_Adapter_IFC);
// Discard write-responses from the fabric
rule rl_discard_write_rsp;
let wr_resp <- get(master_xactor.slave.b);
let wr_resp <- get(master_shim.slave.b);
if (cfg_verbosity > 0) begin
$display ("%0d: %m.rl_discard_write_rsp", cur_cycle);
@@ -309,7 +359,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.masterSynth;
interface mmio_master = master_shim.master;
endmodule
// ================================================================

View File

@@ -54,9 +54,9 @@ interface Proc_IFC;
Wd_AR_User, Wd_R_User) master0;
// Fabric master interface for IO (from MMIOPlatform)
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;
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;
// ----------------
// External interrupts

View File

@@ -149,11 +149,10 @@ module mkCoreW #(Reset dm_power_on_reset)
Proc_IFC proc <- mkProc (reset_by hart0_reset);
// handle uncached interface
let tmp0 <- fromAXI4_Master_Synth(proc.master1, reset_by hart0_reset);
let proc_uncached = toAXI4_Master_Synth(extendIDFields(zeroMasterUserFields(tmp0), 0));
let proc_uncached <- toAXI4_Master_Synth(extendIDFields(zeroMasterUserFields(proc.master1), 0));
// Bridge for uncached expernal bus transactions.
let uncached_mem_shim <- mkAXI4ShimFF(reset_by hart0_reset);
let ug_uncached_mem_shim_master <- toUnguarded_AXI4_Master(zeroMasterUserFields(extendIDFields(uncached_mem_shim.master,0)), reset_by hart0_reset);
let uncached_mem_master <- toAXI4_Master_Synth(extendIDFields(zeroMasterUserFields(uncached_mem_shim.master), 0), reset_by hart0_reset);
// handle cached interface
// AXI4 tagController
@@ -351,7 +350,7 @@ module mkCoreW #(Reset dm_power_on_reset)
Wd_AR_User, Wd_R_User))
slave_vector = newVector;
//let slave_vector = newVector;
slave_vector[default_slave_num] = toAXI4_Slave_Synth(uncached_mem_shim.slave);
slave_vector[default_slave_num] <- toAXI4_Slave_Synth(uncached_mem_shim.slave);
slave_vector[llc_slave_num] = proc.debug_module_mem_server;
slave_vector[plic_slave_num] = plic.axi4_slave;
@@ -370,6 +369,8 @@ module mkCoreW #(Reset dm_power_on_reset)
mkAXI4Bus_Synth (route_2x3, master_vector, slave_vector);
let cached_mem_master <- toAXI4_Master_Synth(tagController.master);
// ================================================================
// Connect external interrupt lines from PLIC to CPU
@@ -418,10 +419,10 @@ module mkCoreW #(Reset dm_power_on_reset)
// AXI4 Fabric interfaces
// Cached master to Fabric master interface
interface cpu_imem_master = toAXI4_Master_Synth(tagController.master);
interface cpu_imem_master = cached_mem_master;
// Uncached master to Fabric master interface
interface cpu_dmem_master = toAXI4_Master_Synth(ug_uncached_mem_shim_master);
interface cpu_dmem_master = uncached_mem_master;
// ----------------------------------------------------------------
// External interrupt sources

View File

@@ -192,26 +192,22 @@ module mkSoC_Top #(Reset dm_power_on_reset)
// Fabric to Boot ROM
let br <- fromAXI4_Slave_Synth(boot_rom.slave);
mkConnection(boot_rom_axi4_deburster.master, br);
let ug_boot_rom_slave <- toUnguarded_AXI4_Slave(boot_rom_axi4_deburster.slave);
slave_vector[boot_rom_slave_num] = toAXI4_Slave_Synth(zeroSlaveUserFields(ug_boot_rom_slave));
slave_vector[boot_rom_slave_num] <- toAXI4_Slave_Synth(zeroSlaveUserFields(boot_rom_axi4_deburster.slave));
route_vector[boot_rom_slave_num] = soc_map.m_boot_rom_addr_range;
// Fabric to Mem Controller
let mem <- fromAXI4_Slave_Synth(mem0_controller.slave);
mkConnection(mem0_controller_axi4_deburster.master, mem);
let ug_mem0_slave <- toUnguarded_AXI4_Slave(mem0_controller_axi4_deburster.slave);
slave_vector[mem0_controller_slave_num] = toAXI4_Slave_Synth(zeroSlaveUserFields(ug_mem0_slave));
slave_vector[mem0_controller_slave_num] <- toAXI4_Slave_Synth(zeroSlaveUserFields(mem0_controller_axi4_deburster.slave));
route_vector[mem0_controller_slave_num] = soc_map.m_mem0_controller_addr_range;
// Fabric to UART0
let uart0_slave <- fromAXI4_Slave_Synth(uart0.slave);
slave_vector[uart0_slave_num] = toAXI4_Slave_Synth(zeroSlaveUserFields(uart0_slave));
slave_vector[uart0_slave_num] <- liftAXI4_Slave_Synth(zeroSlaveUserFields, uart0.slave);
route_vector[uart0_slave_num] = soc_map.m_uart0_addr_range;
`ifdef INCLUDE_ACCEL0
// Fabric to accel0
let accel0_slave <- fromAXI4_Slave_Synth(accel0.slave);
slave_vector[accel0_slave_num] = toAXI4_Slave_Synth(zeroSlaveUserFields(accel0_slave));
slave_vector[accel0_slave_num] <- liftAXI4_Slave_Synth(zeroSlaveUserFields, accel0.slave);
route_vector[accel0_slave_num] = soc_map.m_accel0_addr_range;
`endif