1
0

Add JTAG DTM and test support in simulation

Initial cut

checkpoint which compiles and runs but there is some off-by-1 in the protocol

Debugging the clock crossing logic

checkpoint which works

Clean up the AsyncMailbox black box
This commit is contained in:
Megan Wachs
2016-08-19 09:46:43 -07:00
parent ceff6dd0c8
commit dd4a50c452
14 changed files with 1813 additions and 23 deletions

View File

@ -122,6 +122,7 @@ class BasePlatformConfig extends Config (
case BuildCoreplex => (p: Parameters) => Module(new DefaultCoreplex(p))
case NExtInterrupts => 2
case AsyncDebugBus => false
case IncludeJtagDTM => false
case AsyncMMIOChannels => false
case ExtraDevices => Nil
case ExtraTopPorts => (p: Parameters) => new Bundle
@ -277,4 +278,18 @@ class WithTestRAM extends Config(
}
Seq(new TestRAMDevice)
}
})
}
)
class WithAsyncDebug extends Config (
(pname, site, here) => pname match {
case AsyncDebugBus => true
}
)
class WithJtagDTM extends Config (
(pname, site, here) => pname match {
case IncludeJtagDTM => true
}
)

View File

@ -87,9 +87,10 @@ class TopIO(implicit p: Parameters) extends BasicTopIO()(p) {
val mmio_axi = Vec(p(NExtMMIOAXIChannels), new NastiIO)
val mmio_ahb = Vec(p(NExtMMIOAHBChannels), new HastiMasterIO)
val mmio_tl = Vec(p(NExtMMIOTLChannels), new ClientUncachedTileLinkIO()(outermostMMIOParams))
val debug_clk = if (p(AsyncDebugBus)) Some(Clock(INPUT)) else None
val debug_rst = if (p(AsyncDebugBus)) Some(Bool(INPUT)) else None
val debug = new DebugBusIO()(p).flip
val debug_clk = if (p(AsyncDebugBus) & !p(IncludeJtagDTM)) Some(Clock(INPUT)) else None
val debug_rst = if (p(AsyncDebugBus) & !p(IncludeJtagDTM)) Some(Bool(INPUT)) else None
val debug = if (!p(IncludeJtagDTM)) Some(new DebugBusIO()(p).flip) else None
val jtag = if ( p(IncludeJtagDTM)) Some(new JtagIO(true).flip) else None
val extra = p(ExtraTopPorts)(p)
}
@ -137,10 +138,18 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
periphery.io.mem_in <> coreplex.io.mem
coreplex.io.ext_clients <> periphery.io.clients_out
coreplex.io.debug <>
if (p(IncludeJtagDTM)) {
// JtagDTMWithSync is a wrapper which
// handles the synchronization as well.
val jtag_dtm = Module (new JtagDTMWithSync()(p))
jtag_dtm.io.jtag <> io.jtag.get
coreplex.io.debug <> jtag_dtm.io.debug
} else {
coreplex.io.debug <>
(if (p(AsyncDebugBus))
AsyncDebugBusFrom(io.debug_clk.get, io.debug_rst.get, io.debug)
else io.debug)
AsyncDebugBusFrom(io.debug_clk.get, io.debug_rst.get, io.debug.get)
else io.debug.get)
}
def asyncAxiTo(clocks: Seq[Clock], resets: Seq[Bool], inner_axis: Seq[NastiIO]): Seq[NastiIO] =
(clocks, resets, inner_axis).zipped.map {

View File

@ -6,6 +6,7 @@ import Chisel._
import cde.{Parameters, Field}
import rocket.Util._
import junctions._
import uncore.devices.{IncludeJtagDTM}
class TestHarness(implicit p: Parameters) extends Module {
val io = new Bundle {
@ -26,9 +27,6 @@ class TestHarness(implicit p: Parameters) extends Module {
require(dut.io.mmio_axi.isEmpty)
require(dut.io.mmio_ahb.isEmpty)
require(dut.io.mmio_tl.isEmpty)
require(dut.io.debug_clk.isEmpty)
require(dut.io.debug_rst.isEmpty)
require(dut.io.debug_rst.isEmpty)
require(dut.io.extra.elements.isEmpty)
for (int <- dut.io.interrupts)
@ -41,14 +39,42 @@ class TestHarness(implicit p: Parameters) extends Module {
Module(new SimAXIMem(memSize / dut.io.mem_axi.size)).io.axi <> axi
}
val dtm = Module(new SimDTM)
dut.io.debug <> dtm.io.debug
dtm.io.clk := clock
dtm.io.reset := reset
io.success := dut.io.success.getOrElse(dtm.io.exit === 1)
when (dtm.io.exit >= 2) {
printf("*** FAILED *** (exit code = %d)\n", dtm.io.exit >> 1)
stop(1)
if (p(IncludeJtagDTM)) {
val jtag_vpi = Module (new JtagVpi)
dut.io.jtag.get <> jtag_vpi.io.jtag
// To be proper,
// TRST should really be synchronized
// with TCK. But this is a fairly
// accurate representation of how
// HW may drive this signal.
// Neither OpenOCD nor JtagVPI drive TRST.
dut.io.jtag.get.TRST := reset
jtag_vpi.io.enable := ~reset
jtag_vpi.io.init_done := ~reset
io.success := Bool(false)
}
else {
val dtm = Module(new SimDTM)
dut.io.debug.get <> dtm.io.debug
// Todo: enable the usage of different clocks.
val dtm_clock = clock
val dtm_reset = reset
dtm.io.clk := dtm_clock
dtm.io.reset := dtm_reset
if (dut.io.debug_clk.isDefined)
dut.io.debug_clk.get := dtm_clock
if (dut.io.debug_rst.isDefined)
dut.io.debug_rst.get := dtm_reset
io.success := dut.io.success.getOrElse(dtm.io.exit === 1)
when (dtm.io.exit >= 2) {
printf("*** FAILED *** (exit code = %d)\n", dtm.io.exit >> 1)
stop(1)
}
}
}
@ -114,3 +140,13 @@ class SimDTM(implicit p: Parameters) extends BlackBox {
val exit = UInt(OUTPUT, 32)
}
}
class JtagVpi(implicit val p: Parameters) extends BlackBox {
val io = new Bundle {
val jtag = new JtagIO(false)
val enable = Bool(INPUT)
val init_done = Bool(INPUT)
}
}