Allow dynamic latency config
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user