Allow dynamic latency config

This commit is contained in:
Peter Rugg
2023-07-12 15:34:36 +01:00
parent d17d3135bb
commit f71f650023
2 changed files with 73 additions and 4 deletions

View File

@@ -143,6 +143,9 @@ endmodule
(* synthesize *)
module mkP3_Core (P3_Core_IFC);
// System address map
SoC_Map_IFC soc_map <- mkSoC_Map;
// ================================================================
// The RISC-V Debug Module is at the following point in the module hierarchy:
// p3_core.corew.debug_module
@@ -201,12 +204,67 @@ module mkP3_Core (P3_Core_IFC);
match {.wideS, .narrowM} = wideS_narrowM;
mkConnection(corew.manager_0, wideS);
Bit#(16) latencyCycles = 200;
AXI4_Shim#(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0) master_0_delay <- mkDelayShim(latencyCycles);
AXI4_Shim#(TAdd#(Wd_MId,1), Wd_Addr, Wd_Data_Periph, 0, 0, 0, 0, 0) master_1_delay <- mkDelayShim(latencyCycles);
// ================================================================
// Delay DRAM to compensate for relatively lower FPGA clock
Bit#(16) defaultLatency = 0;
Reg#(Bit#(16)) latencyCycles0 <- mkReg(defaultLatency);
Reg#(Bit#(16)) latencyCycles1 <- mkReg(defaultLatency);
let master_0_delay <- mkDelayShim(latencyCycles0);
let master_1_delay <- mkDelayShim(latencyCycles1);
// Support dynamic changing of latency
let latencyToggleShim <- mkAXI4Shim;
rule changeLatency;
let awflit <- get(latencyToggleShim.master.aw);
let wflit <- get(latencyToggleShim.master.w);
let bresp = OKAY;
let latency = truncate(wflit.wdata);
case(awflit.awaddr)
0: latencyCycles0 <= latency;
64: latencyCycles1 <= latency;
default: bresp = SLVERR;
endcase
let bflit = AXI4_BFlit { bid: awflit.awid
, bresp: bresp
, buser: awflit.awuser };
latencyToggleShim.master.b.put(bflit);
endrule
rule queryLatency;
let arflit <- get(latencyToggleShim.master.ar);
let rresp = OKAY;
Bit#(Wd_Data_Periph) rdata = ?;
case(arflit.araddr)
0: rdata = zeroExtend(latencyCycles0);
64: rdata = zeroExtend(latencyCycles1);
default: rresp = SLVERR;
endcase
let rflit = AXI4_RFlit { rid: arflit.arid
, rresp: rresp
, rdata: rdata
, rlast: True
, ruser: arflit.aruser };
latencyToggleShim.master.r.put(rflit);
endrule
let master_vector = cons(corew.manager_1, nil);
let slave_vector = cons(master_1_delay.slave, cons(latencyToggleShim.slave, nil));
function Vector #(2, Bool) route (Bit #(Wd_Addr) addr);
Vector #(2, Bool) res = replicate(False);
if (inRange(soc_map.m_soc_config_addr_range, addr))
res[1] = True;
else
res[0] = True;
return res;
endfunction
mkAXI4Bus (route, master_vector, slave_vector);
mkConnection(master_0_delay.slave, narrowM);
mkConnection(master_1_delay.slave, corew.manager_1);
`ifdef INCLUDE_GDB_CONTROL

View File

@@ -97,6 +97,7 @@ interface SoC_Map_IFC;
(* always_ready *) method Range#(Wd_Addr) m_ddr4_0_uncached_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_ddr4_0_cached_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_mem0_controller_addr_range;
(* always_ready *) method Range#(Wd_Addr) m_soc_config_addr_range;
(* always_ready *)
method Bool m_is_mem_addr (Fabric_Addr addr);
@@ -197,6 +198,14 @@ module mkSoC_Map (SoC_Map_IFC);
size: 'h_C000_0000 // 3G
};
// ----------------------------------------------------------------
// SoC Config addresses
let soc_config_addr_range = Range {
base: 'h_0000_1000,
size: 'h_0000_1000 // 4K
};
// ----------------------------------------------------------------
function fn_is_flash_regs_addr = addr_function('h6240_0000, 'h1000);
@@ -229,6 +238,7 @@ module mkSoC_Map (SoC_Map_IFC);
return ( inRange(boot_rom_addr_range, addr)
|| inRange(ddr4_0_uncached_addr_range, addr)
|| inRange(flash_mem_addr_range, addr)
|| inRange(soc_config_addr_range, addr)
|| ( (! imem_not_dmem)
&& ( inRange(plic_addr_range, addr)
|| inRange(near_mem_io_addr_range, addr)
@@ -271,6 +281,7 @@ module mkSoC_Map (SoC_Map_IFC);
method Range#(Wd_Addr) m_ddr4_0_uncached_addr_range = ddr4_0_uncached_addr_range;
method Range#(Wd_Addr) m_ddr4_0_cached_addr_range = ddr4_0_cached_addr_range;
method Range#(Wd_Addr) m_mem0_controller_addr_range = ddr4_0_cached_addr_range;
method Range#(Wd_Addr) m_soc_config_addr_range = soc_config_addr_range;
method Bool m_is_mem_addr (Fabric_Addr addr) = fn_is_mem_addr (addr);