Remove HTIF; use debug module for testing in simulation
This commit is contained in:
@ -262,12 +262,12 @@ class BaseConfig extends Config (
|
||||
case TLKey("L1toL2") =>
|
||||
TileLinkParameters(
|
||||
coherencePolicy = new MESICoherence(site(L2DirectoryRepresentation)),
|
||||
nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1,
|
||||
nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1 /* MMIO */,
|
||||
nCachingClients = site(NCachedTileLinkPorts),
|
||||
nCachelessClients = site(NUncachedTileLinkPorts),
|
||||
maxClientXacts = max_int(
|
||||
// L1 cache
|
||||
site(NMSHRs) + 1,
|
||||
site(NMSHRs) + 1 /* IOMSHR */,
|
||||
// RoCC
|
||||
if (site(BuildRoCC).isEmpty) 1 else site(RoccMaxTaggedMemXacts)),
|
||||
maxClientsPerPort = if (site(BuildRoCC).isEmpty) 1 else 2,
|
||||
|
@ -18,10 +18,8 @@ class ZynqAdapter(implicit val p: Parameters) extends Module
|
||||
|
||||
val io = new Bundle {
|
||||
val nasti = new NastiIO()(adapterParams).flip
|
||||
val host = new HostIO(htifW).flip
|
||||
val reset = Bool(OUTPUT)
|
||||
}
|
||||
|
||||
val conv = Module(new NastiIOHostIOConverter(htifW)(adapterParams))
|
||||
io <> conv.io
|
||||
require(false, "TODO reimplement using debug port, not HTIF")
|
||||
}
|
||||
|
@ -53,8 +53,7 @@ trait HasTopLevelParameters {
|
||||
implicit val p: Parameters
|
||||
lazy val nTiles = p(NTiles)
|
||||
lazy val nCachedTilePorts = p(NCachedTileLinkPorts)
|
||||
lazy val nUncachedTilePorts = p(NUncachedTileLinkPorts) - 1
|
||||
lazy val htifW = p(HtifKey).width
|
||||
lazy val nUncachedTilePorts = p(NUncachedTileLinkPorts)
|
||||
lazy val csrAddrBits = 12
|
||||
lazy val tMemChannels = p(TMemoryChannels)
|
||||
lazy val nMemChannels = p(NMemoryChannels)
|
||||
@ -83,9 +82,7 @@ class MemBackupCtrlIO extends Bundle {
|
||||
|
||||
/** Top-level io for the chip */
|
||||
class BasicTopIO(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
||||
with HasTopLevelParameters {
|
||||
val host = new HostIO(htifW)
|
||||
}
|
||||
with HasTopLevelParameters
|
||||
|
||||
class TopIO(implicit p: Parameters) extends BasicTopIO()(p) {
|
||||
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
||||
@ -120,8 +117,10 @@ object TopUtils {
|
||||
require(resetToMemDist == (resetToMemDist.toInt >> 12 << 12))
|
||||
val configStringAddr = p(ResetVector).toInt + rom.capacity
|
||||
|
||||
rom.putInt(0x00000297 + resetToMemDist.toInt) // auipc t0, &mem - &here
|
||||
rom.putInt(0x00028067) // jr t0
|
||||
// This boot ROM doesn't know about any boot devices, so it just spins,
|
||||
// waiting for the debugger to load a program and change the PC.
|
||||
rom.putInt(0x0000006f) // loop forever
|
||||
rom.putInt(0) // reserved
|
||||
rom.putInt(0) // reserved
|
||||
rom.putInt(configStringAddr) // pointer to config string
|
||||
rom.putInt(0) // default trap vector
|
||||
@ -151,7 +150,7 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
|
||||
case HastiId => "TL"
|
||||
case TLId => "L1toL2"
|
||||
case NCachedTileLinkPorts => nCachedPorts
|
||||
case NUncachedTileLinkPorts => nUncachedPorts + 1 // 1 for HTIF
|
||||
case NUncachedTileLinkPorts => nUncachedPorts
|
||||
})
|
||||
|
||||
val uncore = Module(new Uncore()(innerTLParams))
|
||||
@ -165,7 +164,6 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
|
||||
// Connect the uncore to the tile memory ports, HostIO and MemIO
|
||||
uncore.io.tiles_cached <> tileList.map(_.io.cached).flatten
|
||||
uncore.io.tiles_uncached <> tileList.map(_.io.uncached).flatten
|
||||
io.host <> uncore.io.host
|
||||
uncore.io.interrupts <> io.interrupts
|
||||
uncore.io.debugBus <> io.debug
|
||||
|
||||
@ -185,7 +183,6 @@ class Uncore(implicit val p: Parameters) extends Module
|
||||
|
||||
|
||||
val io = new Bundle {
|
||||
val host = new HostIO(htifW)
|
||||
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
||||
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
|
||||
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
||||
@ -197,30 +194,15 @@ class Uncore(implicit val p: Parameters) extends Module
|
||||
val debugBus = new DebugBusIO()(p).flip
|
||||
}
|
||||
|
||||
val htif = Module(new Htif(CSRs.mreset)) // One HTIF module per chip
|
||||
val outmemsys = Module(new OuterMemorySystem) // NoC, LLC and SerDes
|
||||
outmemsys.io.incoherent := htif.io.cpu.map(_.reset)
|
||||
outmemsys.io.htif_uncached <> htif.io.mem
|
||||
outmemsys.io.incoherent foreach (_ := false)
|
||||
outmemsys.io.tiles_uncached <> io.tiles_uncached
|
||||
outmemsys.io.tiles_cached <> io.tiles_cached
|
||||
|
||||
val scrFile = Module(new SCRFile("UNCORE_SCR", 0))
|
||||
scrFile.io.smi <> htif.io.scr
|
||||
// scrFile.io.scr <> (... your SCR connections ...)
|
||||
|
||||
buildMMIONetwork(p.alterPartial({case TLId => "MMIO_Outermost"}))
|
||||
|
||||
// Wire the htif to the memory port(s) and host interface
|
||||
io.mem_axi <> outmemsys.io.mem_axi
|
||||
io.mem_ahb <> outmemsys.io.mem_ahb
|
||||
if(p(UseHtifClockDiv)) {
|
||||
VLSIUtils.padOutHTIFWithDividedClock(htif.io.host, scrFile.io.scr, io.host, htifW)
|
||||
} else {
|
||||
io.host <> htif.io.host
|
||||
}
|
||||
|
||||
// Tie off HTIF CSR ports
|
||||
htif.io.cpu.foreach { _.csr.resp.valid := Bool(false) }
|
||||
|
||||
def buildMMIONetwork(implicit p: Parameters) = {
|
||||
val ioAddrMap = p(GlobalAddrMap).subMap("io")
|
||||
@ -254,9 +236,7 @@ class Uncore(implicit val p: Parameters) extends Module
|
||||
prci.io.interrupts(i).seip := plic.io.harts(plic.cfg.context(i, 'S'))
|
||||
prci.io.interrupts(i).debug := debugModule.io.debugInterrupts(i)
|
||||
|
||||
io.prci(i).reset := reset || Reg(init = Bool(true),
|
||||
next=Reg(init = Bool(true),
|
||||
next=htif.io.cpu(i).reset)) // TODO
|
||||
io.prci(i).reset := reset
|
||||
}
|
||||
|
||||
val bootROM = Module(new ROMSlave(TopUtils.makeBootROM()))
|
||||
@ -289,14 +269,13 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
|
||||
val io = new Bundle {
|
||||
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
||||
val tiles_uncached = Vec(nUncachedTilePorts, new ClientUncachedTileLinkIO).flip
|
||||
val htif_uncached = (new ClientUncachedTileLinkIO).flip
|
||||
val incoherent = Vec(nTiles, Bool()).asInput
|
||||
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
|
||||
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
|
||||
val mmio = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => "L2toMMIO"}))
|
||||
}
|
||||
|
||||
// Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory
|
||||
// Create a simple L1toL2 NoC between the tiles and the banks of outer memory
|
||||
// Cached ports are first in client list, making sharerToClientId just an indentity function
|
||||
// addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
|
||||
def sharerToClientId(sharerId: UInt) = sharerId
|
||||
@ -320,10 +299,10 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
|
||||
})))
|
||||
io.mmio <> mmioManager.io.outer
|
||||
|
||||
// Wire the tiles and htif to the TileLink client ports of the L1toL2 network,
|
||||
// Wire the tiles to the TileLink client ports of the L1toL2 network,
|
||||
// and coherence manager(s) to the other side
|
||||
l1tol2net.io.clients_cached <> io.tiles_cached
|
||||
l1tol2net.io.clients_uncached <> io.tiles_uncached ++ Seq(io.htif_uncached)
|
||||
l1tol2net.io.clients_uncached <> io.tiles_uncached
|
||||
l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
|
||||
|
||||
// Create a converter between TileLinkIO and MemIO for each channel
|
||||
|
@ -17,6 +17,56 @@ object TestBenchGeneration extends FileSystemUtilities {
|
||||
// bit collection on the DirectC side. I had to individually define the
|
||||
// wires.
|
||||
|
||||
val daw = p(DMKey).nDebugBusAddrSize
|
||||
val dow = DbBusConsts.dbOpSize
|
||||
val ddw = DbBusConsts.dbDataSize
|
||||
val drw = DbBusConsts.dbRespSize
|
||||
|
||||
val debugDefs = s"""
|
||||
wire debug_req_valid_delay;
|
||||
reg debug_req_valid;
|
||||
assign #0.1 debug_req_valid_delay = debug_req_valid;
|
||||
|
||||
wire debug_req_ready, debug_req_ready_delay;
|
||||
assign #0.1 debug_req_ready = debug_req_ready_delay;
|
||||
|
||||
wire [${daw-1}:0] debug_req_bits_addr_delay;
|
||||
reg [${daw-1}:0] debug_req_bits_addr;
|
||||
assign #0.1 debug_req_bits_addr_delay = debug_req_bits_addr;
|
||||
|
||||
wire [${dow-1}:0] debug_req_bits_op_delay;
|
||||
reg [${dow-1}:0] debug_req_bits_op;
|
||||
assign #0.1 debug_req_bits_op_delay = debug_req_bits_op;
|
||||
|
||||
wire [${ddw-1}:0] debug_req_bits_data_delay;
|
||||
reg [${ddw-1}:0] debug_req_bits_data;
|
||||
assign #0.1 debug_req_bits_data_delay = debug_req_bits_data;
|
||||
|
||||
wire debug_resp_valid, debug_resp_valid_delay;
|
||||
assign #0.1 debug_resp_valid = debug_resp_valid_delay;
|
||||
|
||||
wire debug_resp_ready_delay;
|
||||
reg debug_resp_ready;
|
||||
assign #0.1 debug_resp_ready_delay = debug_resp_ready;
|
||||
|
||||
wire [${drw-1}:0] debug_resp_bits_resp, debug_resp_bits_resp_delay;
|
||||
assign #0.1 debug_resp_bits_resp = debug_resp_bits_resp_delay;
|
||||
|
||||
wire [${ddw-1}:0] debug_resp_bits_data, debug_resp_bits_data_delay;
|
||||
assign #0.1 debug_resp_bits_data = debug_resp_bits_data_delay;
|
||||
"""
|
||||
|
||||
val debugBus = s"""
|
||||
.io_debug_req_ready(debug_req_ready_delay),
|
||||
.io_debug_req_valid(debug_req_valid_delay),
|
||||
.io_debug_req_bits_addr(debug_req_bits_addr_delay),
|
||||
.io_debug_req_bits_op(debug_req_bits_op_delay),
|
||||
.io_debug_req_bits_data(debug_req_bits_data_delay),
|
||||
.io_debug_resp_ready(debug_resp_ready_delay),
|
||||
.io_debug_resp_valid(debug_resp_valid_delay),
|
||||
.io_debug_resp_bits_resp(debug_resp_bits_resp_delay),
|
||||
.io_debug_resp_bits_data(debug_resp_bits_data_delay)
|
||||
"""
|
||||
val nasti_defs = (0 until nMemChannel) map { i => s"""
|
||||
wire ar_valid_$i;
|
||||
reg ar_ready_$i;
|
||||
@ -52,25 +102,6 @@ object TestBenchGeneration extends FileSystemUtilities {
|
||||
|
||||
""" } mkString
|
||||
|
||||
val delays = s"""
|
||||
wire htif_clk;
|
||||
wire htif_in_valid_delay;
|
||||
wire htif_in_ready_delay;
|
||||
wire [`HTIF_WIDTH-1:0] htif_in_bits_delay;
|
||||
|
||||
wire htif_out_valid_delay;
|
||||
wire htif_out_ready_delay;
|
||||
wire [`HTIF_WIDTH-1:0] htif_out_bits_delay;
|
||||
|
||||
assign #0.1 htif_in_valid_delay = htif_in_valid;
|
||||
assign #0.1 htif_in_ready = htif_in_ready_delay;
|
||||
assign #0.1 htif_in_bits_delay = htif_in_bits;
|
||||
|
||||
assign #0.1 htif_out_valid = htif_out_valid_delay;
|
||||
assign #0.1 htif_out_ready_delay = htif_out_ready;
|
||||
assign #0.1 htif_out_bits = htif_out_bits_delay;
|
||||
"""
|
||||
|
||||
val nasti_delays = (0 until nMemChannel) map { i => s"""
|
||||
wire ar_valid_delay_$i;
|
||||
wire ar_ready_delay_$i;
|
||||
@ -195,27 +226,8 @@ object TestBenchGeneration extends FileSystemUtilities {
|
||||
.io_interrupts_$i (1'b0),
|
||||
""" } mkString
|
||||
|
||||
val daw = p(DMKey).nDebugBusAddrSize
|
||||
val dow = DbBusConsts.dbOpSize
|
||||
val ddw = DbBusConsts.dbDataSize
|
||||
val debug_bus = s"""
|
||||
.io_debug_req_ready( ),
|
||||
.io_debug_req_valid(1'b0),
|
||||
.io_debug_req_bits_addr($daw'b0),
|
||||
.io_debug_req_bits_op($dow'b0),
|
||||
.io_debug_req_bits_data($ddw'b0),
|
||||
.io_debug_resp_ready(1'b0),
|
||||
.io_debug_resp_valid( ),
|
||||
.io_debug_resp_bits_resp( ),
|
||||
.io_debug_resp_bits_data( ),
|
||||
"""
|
||||
|
||||
|
||||
val instantiation = s"""
|
||||
`ifdef FPGA
|
||||
assign htif_clk = clk;
|
||||
`endif
|
||||
|
||||
Top dut
|
||||
(
|
||||
.clk(clk),
|
||||
@ -225,22 +237,7 @@ object TestBenchGeneration extends FileSystemUtilities {
|
||||
|
||||
$interrupts
|
||||
|
||||
$debug_bus
|
||||
|
||||
`ifndef FPGA
|
||||
.io_host_clk(htif_clk),
|
||||
.io_host_clk_edge(),
|
||||
`else
|
||||
.io_host_clk (),
|
||||
.io_host_clk_edge (),
|
||||
`endif // FPGA
|
||||
|
||||
.io_host_in_valid(htif_in_valid_delay),
|
||||
.io_host_in_ready(htif_in_ready_delay),
|
||||
.io_host_in_bits(htif_in_bits_delay),
|
||||
.io_host_out_valid(htif_out_valid_delay),
|
||||
.io_host_out_ready(htif_out_ready_delay),
|
||||
.io_host_out_bits(htif_out_bits_delay)
|
||||
$debugBus
|
||||
);
|
||||
"""
|
||||
|
||||
@ -302,7 +299,7 @@ object TestBenchGeneration extends FileSystemUtilities {
|
||||
""" } mkString
|
||||
|
||||
val f = createOutputFile(s"$topModuleName.$configClassName.tb.vfrag")
|
||||
f.write(nasti_defs + delays + nasti_delays + instantiation + ticks)
|
||||
f.write(debugDefs + nasti_defs + nasti_delays + instantiation + ticks)
|
||||
f.close
|
||||
}
|
||||
|
||||
|
@ -1,112 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package rocketchip
|
||||
|
||||
import Chisel._
|
||||
import cde.Parameters
|
||||
import junctions._
|
||||
import uncore._
|
||||
|
||||
object VLSIUtils {
|
||||
def doOuterMemorySystemSerdes(
|
||||
llcs: Seq[NastiIO],
|
||||
mems: Seq[NastiIO],
|
||||
backup: MemSerializedIO,
|
||||
en: Bool,
|
||||
nMemChannels: Int,
|
||||
htifWidth: Int,
|
||||
blockOffsetBits: Int)
|
||||
(implicit p: Parameters) {
|
||||
|
||||
val arb = Module(new NastiArbiter(nMemChannels))
|
||||
val conv = Module(new MemIONastiIOConverter(blockOffsetBits))
|
||||
val mem_serdes = Module(new MemSerdes(htifWidth))
|
||||
|
||||
conv.io.nasti <> arb.io.slave
|
||||
mem_serdes.io.wide <> conv.io.mem
|
||||
backup <> mem_serdes.io.narrow
|
||||
|
||||
llcs zip mems zip arb.io.master foreach { case ((llc, mem), wide) =>
|
||||
llc.ar.ready := Mux(en, wide.ar.ready, mem.ar.ready)
|
||||
mem.ar.valid := llc.ar.valid && !en
|
||||
mem.ar.bits := llc.ar.bits
|
||||
wide.ar.valid := llc.ar.valid && en
|
||||
wide.ar.bits := llc.ar.bits
|
||||
|
||||
llc.aw.ready := Mux(en, wide.aw.ready, mem.aw.ready)
|
||||
mem.aw.valid := llc.aw.valid && !en
|
||||
mem.aw.bits := llc.aw.bits
|
||||
wide.aw.valid := llc.aw.valid && en
|
||||
wide.aw.bits := llc.aw.bits
|
||||
|
||||
llc.w.ready := Mux(en, wide.w.ready, mem.w.ready)
|
||||
mem.w.valid := llc.w.valid && !en
|
||||
mem.w.bits := llc.w.bits
|
||||
wide.w.valid := llc.w.valid && en
|
||||
wide.w.bits := llc.w.bits
|
||||
|
||||
llc.b.valid := Mux(en, wide.b.valid, mem.b.valid)
|
||||
llc.b.bits := Mux(en, wide.b.bits, mem.b.bits)
|
||||
mem.b.ready := llc.b.ready && !en
|
||||
wide.b.ready := llc.b.ready && en
|
||||
|
||||
llc.r.valid := Mux(en, wide.r.valid, mem.r.valid)
|
||||
llc.r.bits := Mux(en, wide.r.bits, mem.r.bits)
|
||||
mem.r.ready := llc.r.ready && !en
|
||||
wide.r.ready := llc.r.ready && en
|
||||
}
|
||||
}
|
||||
|
||||
private def makeHTIFClockDivider(scr: SCRIO, host: HostIO, htifW: Int) = {
|
||||
val hio = Module((new SlowIO(512)) { Bits(width = htifW) })
|
||||
hio.io.set_divisor.valid := scr.wen && (scr.waddr === UInt(63))
|
||||
hio.io.set_divisor.bits := scr.wdata
|
||||
scr.rdata(63) := hio.io.divisor
|
||||
scr.allocate(63, "HTIF_IO_CLOCK_DIVISOR")
|
||||
host.clk := hio.io.clk_slow
|
||||
host.clk_edge := Reg(next=host.clk && !Reg(next=host.clk))
|
||||
hio
|
||||
}
|
||||
|
||||
def padOutHTIFWithDividedClock(
|
||||
htif: HostIO,
|
||||
scr: SCRIO,
|
||||
host: HostIO,
|
||||
htifW: Int) {
|
||||
val hio = makeHTIFClockDivider(scr, host, htifW)
|
||||
|
||||
hio.io.out_fast <> htif.out
|
||||
host.out <> hio.io.out_slow
|
||||
hio.io.in_slow <> host.in
|
||||
htif.in <> hio.io.in_fast
|
||||
}
|
||||
|
||||
def padOutHTIFWithDividedClock(
|
||||
htif: HostIO,
|
||||
scr: SCRIO,
|
||||
child: MemSerializedIO,
|
||||
parent: MemBackupCtrlIO,
|
||||
host: HostIO,
|
||||
htifW: Int) {
|
||||
val hio = makeHTIFClockDivider(scr, host, htifW+1)
|
||||
|
||||
hio.io.out_fast.valid := htif.out.valid || child.req.valid
|
||||
hio.io.out_fast.bits := Cat(htif.out.valid, Mux(htif.out.valid, htif.out.bits, child.req.bits))
|
||||
htif.out.ready := hio.io.out_fast.ready
|
||||
child.req.ready := hio.io.out_fast.ready && !htif.out.valid
|
||||
host.out.valid := hio.io.out_slow.valid && hio.io.out_slow.bits(htifW)
|
||||
host.out.bits := hio.io.out_slow.bits
|
||||
parent.out_valid := hio.io.out_slow.valid && !hio.io.out_slow.bits(htifW)
|
||||
hio.io.out_slow.ready := Mux(hio.io.out_slow.bits(htifW), host.out.ready, parent.out_ready)
|
||||
|
||||
val mem_backup_resp_valid = parent.en && parent.in_valid
|
||||
hio.io.in_slow.valid := mem_backup_resp_valid || host.in.valid
|
||||
hio.io.in_slow.bits := Cat(mem_backup_resp_valid, host.in.bits)
|
||||
host.in.ready := hio.io.in_slow.ready
|
||||
child.resp.valid := hio.io.in_fast.valid && hio.io.in_fast.bits(htifW)
|
||||
child.resp.bits := hio.io.in_fast.bits
|
||||
htif.in.valid := hio.io.in_fast.valid && !hio.io.in_fast.bits(htifW)
|
||||
htif.in.bits := hio.io.in_fast.bits
|
||||
hio.io.in_fast.ready := Mux(hio.io.in_fast.bits(htifW), Bool(true), htif.in.ready)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user