From 1308680f7561f51094360fc27db89f773808cdb1 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Wed, 14 Sep 2016 16:30:59 -0700 Subject: [PATCH 1/2] Add some async/clock utilities --- src/main/scala/junctions/crossing.scala | 41 ++++++++++++++ .../uncore/tilelink2/RegisterCrossing.scala | 54 +++++++++++++++++++ vsim/Makefrag | 3 ++ vsrc/ClockToSignal.v | 19 +++++++ vsrc/SignalToClock.v | 18 +++++++ 5 files changed, 135 insertions(+) create mode 100644 vsrc/ClockToSignal.v create mode 100644 vsrc/SignalToClock.v diff --git a/src/main/scala/junctions/crossing.scala b/src/main/scala/junctions/crossing.scala index 948c3a21..e803d950 100644 --- a/src/main/scala/junctions/crossing.scala +++ b/src/main/scala/junctions/crossing.scala @@ -50,3 +50,44 @@ object AsyncDecoupledFrom AsyncDecoupledCrossing(from_clock, from_reset, from_source, scope.clock, scope.reset, depth, sync) } } + + +/** Because Chisel/FIRRTL does not allow us + * to directly assign clocks from Signals, + * we need this black box module. + * This may even be useful because some back-end + * flows like to have this sort of transition + * flagged with a special cell or module anyway. + */ + +class SignalToClock extends BlackBox { + val io = new Bundle { + val signal_in = Bool(INPUT) + val clock_out = Clock(OUTPUT) + } + + // io.clock_out := io.signal_in +} + +object SignalToClock { + def apply(signal: Bool): Clock = { + val s2c = Module(new SignalToClock) + s2c.io.signal_in := signal + s2c.io.clock_out + } +} + +class ClockToSignal extends BlackBox { + val io = new Bundle { + val clock_in = Clock(INPUT) + val signal_out = Bool(OUTPUT) + } +} + +object ClockToSignal { + def apply(clk: Clock): Bool = { + val c2s = Module(new ClockToSignal) + c2s.io.clock_in := clk + c2s.io.signal_out + } +} diff --git a/src/main/scala/uncore/tilelink2/RegisterCrossing.scala b/src/main/scala/uncore/tilelink2/RegisterCrossing.scala index cb66aca5..1a6ecd3f 100644 --- a/src/main/scala/uncore/tilelink2/RegisterCrossing.scala +++ b/src/main/scala/uncore/tilelink2/RegisterCrossing.scala @@ -4,6 +4,7 @@ package uncore.tilelink2 import Chisel._ import junctions._ +import uncore.util.{AsyncResetRegVec} // A very simple flow control state machine, run in the specified clock domain class BusyRegisterCrossing(clock: Clock, reset: Bool) @@ -130,3 +131,56 @@ class RegisterReadCrossing[T <: Data](gen: T, sync: Int = 3) extends Module { crossing.io.deq.ready := io.master_port.request.valid && !reg.io.busy crossing.io.enq.valid := Bool(true) } + +/** Wrapper to create an + * asynchronously reset + * slave register which + * can be both read + * and written using + * crossing FIFOs. + */ + +object AsyncRWSlaveRegField { + + def apply(slave_clock: Clock, + slave_reset: Bool, + width: Int, + init: Int, + master_allow: Bool = Bool(true), + slave_allow: Bool = Bool(true) + ): (UInt, RegField) = { + + val async_slave_reg = Module(new AsyncResetRegVec(width, init)) + async_slave_reg.reset := slave_reset + async_slave_reg.clock := slave_clock + + val wr_crossing = Module (new RegisterWriteCrossing(UInt(width = width))) + + val scope = Module (new AsyncScope()) + + wr_crossing.io.master_clock := scope.clock + wr_crossing.io.master_reset := scope.reset + wr_crossing.io.master_allow := master_allow + wr_crossing.io.slave_clock := slave_clock + wr_crossing.io.slave_reset := slave_reset + wr_crossing.io.slave_allow := slave_allow + + async_slave_reg.io.en := wr_crossing.io.slave_valid + async_slave_reg.io.d := wr_crossing.io.slave_register + + val rd_crossing = Module (new RegisterReadCrossing(UInt(width = width ))) + + rd_crossing.io.master_clock := scope.clock + rd_crossing.io.master_reset := scope.reset + rd_crossing.io.master_allow := master_allow + rd_crossing.io.slave_clock := slave_clock + rd_crossing.io.slave_reset := slave_reset + rd_crossing.io.slave_allow := slave_allow + + rd_crossing.io.slave_register := async_slave_reg.io.q + + (async_slave_reg.io.q, RegField(width, rd_crossing.io.master_port, wr_crossing.io.master_port)) + + } + +} diff --git a/vsim/Makefrag b/vsim/Makefrag index a0e1c3de..31ee449b 100644 --- a/vsim/Makefrag +++ b/vsim/Makefrag @@ -9,6 +9,9 @@ bb_vsrcs = $(base_dir)/vsrc/DebugTransportModuleJtag.v \ $(base_dir)/vsrc/AsyncMailbox.v \ $(base_dir)/vsrc/AsyncResetReg.v \ $(base_dir)/vsrc/ClockDivider.v \ + $(base_dir)/vsrc/ClockToSignal.v \ + $(base_dir)/vsrc/SignalToClock.v \ + sim_vsrcs = \ $(generated_dir)/$(MODEL).$(CONFIG).v \ diff --git a/vsrc/ClockToSignal.v b/vsrc/ClockToSignal.v new file mode 100644 index 00000000..db8b8b37 --- /dev/null +++ b/vsrc/ClockToSignal.v @@ -0,0 +1,19 @@ + +/* This blackbox is needed by + * Chisel in order to do type conversion. + * It may be useful for some synthesis flows + * as well which require special + * flagging on conversion from data to clock. + */ + + +module ClockToSignal( + output signal_out, + input clock_in + ); + + + assign signal_out = clock_in; + +endmodule // ClockToSignal + diff --git a/vsrc/SignalToClock.v b/vsrc/SignalToClock.v new file mode 100644 index 00000000..553bc580 --- /dev/null +++ b/vsrc/SignalToClock.v @@ -0,0 +1,18 @@ + +/* This blackbox is needed by + * Chisel in order to do type conversion. + * It may be useful for some synthesis flows + * as well which require special + * flagging on conversion from data to clock. + */ + + +module SignalToClock ( + output clock_out, + input signal_in + ); + + + assign clock_out = signal_in; + +endmodule // SignalToClock From 97809b183ff01028dd94d3acf61ede97c9880d17 Mon Sep 17 00:00:00 2001 From: Yunsup Lee Date: Wed, 14 Sep 2016 18:10:21 -0700 Subject: [PATCH 2/2] refactor unittest framework as a result, there's another SUITE that needs to run --- .travis.yml | 1 + Makefrag | 4 +- regression/Makefile | 38 ++++++++++------- src/main/scala/coreplex/UnitTest.scala | 26 ------------ src/main/scala/rocketchip/TestConfigs.scala | 24 ----------- src/main/scala/rocketchip/UnitTest.scala | 46 +++++++++++++++++++++ 6 files changed, 71 insertions(+), 68 deletions(-) delete mode 100644 src/main/scala/coreplex/UnitTest.scala create mode 100644 src/main/scala/rocketchip/UnitTest.scala diff --git a/.travis.yml b/.travis.yml index 5265a984..ddbc3865 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,7 @@ env: matrix: - SUITE=RocketSuite - SUITE=GroundtestSuite + - SUITE=UnittestSuite # blacklist private branches branches: diff --git a/Makefrag b/Makefrag index e05f6d69..a3ff6e37 100644 --- a/Makefrag +++ b/Makefrag @@ -4,8 +4,8 @@ $(error Please set environment variable RISCV. Please take a look at README) endif MODEL ?= TestHarness -PROJECT := rocketchip -CFG_PROJECT := $(PROJECT) +PROJECT ?= rocketchip +CFG_PROJECT ?= $(PROJECT) CXX ?= g++ CXXFLAGS := -O1 diff --git a/regression/Makefile b/regression/Makefile index 0b4f34c5..ca210738 100644 --- a/regression/Makefile +++ b/regression/Makefile @@ -39,14 +39,20 @@ $(error Set SUITE to the regression suite you want to run) endif ifeq ($(SUITE),RocketSuite) +PROJECT=rocketchip CONFIGS=DefaultConfig DefaultL2Config DefaultBufferlessConfig TinyConfig endif ifeq ($(SUITE),GroundtestSuite) +PROJECT=rocketchip CONFIGS=MemtestConfig MemtestBufferlessConfig MemtestStatelessConfig FancyMemtestConfig \ BroadcastRegressionTestConfig BufferlessRegressionTestConfig CacheRegressionTestConfig \ - ComparatorConfig ComparatorBufferlessConfig ComparatorL2Config ComparatorStatelessConfig \ - UnitTestConfig + ComparatorConfig ComparatorBufferlessConfig ComparatorL2Config ComparatorStatelessConfig +endif + +ifeq ($(SUITE),UnittestSuite) +PROJECT=rocketchip.utest +CONFIGS=UnitTestConfig endif ifeq ($(SUITE), JtagDtmSuite) @@ -117,65 +123,65 @@ $(RISCV)/install.stamp: # Builds the various simulators stamps/%/emulator-verilog.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/emulator CONFIG=$* RISCV=$(abspath $(RISCV)) verilog + +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/emulator PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) verilog date > $@ stamps/%/emulator-ndebug.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/emulator CONFIG=$* RISCV=$(abspath $(RISCV)) + +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/emulator PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) date > $@ stamps/%/emulator-debug.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/emulator CONFIG=$* RISCV=$(abspath $(RISCV)) debug + +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/emulator PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) debug date > $@ stamps/%/vsim-verilog.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/vsim CONFIG=$* RISCV=$(abspath $(RISCV)) verilog + +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/vsim PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) verilog date > $@ stamps/%/vsim-ndebug.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/vsim CONFIG=$* RISCV=$(abspath $(RISCV)) + +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/vsim PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) date > $@ stamps/%/vsim-debug.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/vsim CONFIG=$* RISCV=$(abspath $(RISCV)) debug + +flock -x $(dir $@)/chisel-lock $(MAKE) -C $(abspath $(TOP))/vsim PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) debug date > $@ # Runs tests on one of the simulators stamps/%/emulator-asm-tests.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - $(MAKE) -C $(abspath $(TOP))/emulator CONFIG=$* RISCV=$(abspath $(RISCV)) run-asm-tests-fast + $(MAKE) -C $(abspath $(TOP))/emulator PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) run-asm-tests-fast date > $@ stamps/%/emulator-bmark-tests.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - $(MAKE) -C $(abspath $(TOP))/emulator CONFIG=$* RISCV=$(abspath $(RISCV)) run-bmark-tests-fast + $(MAKE) -C $(abspath $(TOP))/emulator PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) run-bmark-tests-fast date > $@ stamps/%/emulator-regression-tests.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - $(MAKE) -C $(abspath $(TOP))/emulator CONFIG=$* RISCV=$(abspath $(RISCV)) clean-run-output - $(MAKE) -C $(abspath $(TOP))/emulator CONFIG=$* RISCV=$(abspath $(RISCV)) run-regression-tests-fast + $(MAKE) -C $(abspath $(TOP))/emulator PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) clean-run-output + $(MAKE) -C $(abspath $(TOP))/emulator PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) run-regression-tests-fast date > $@ stamps/%/vsim-asm-tests.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - $(MAKE) -C $(abspath $(TOP))/vsim CONFIG=$* RISCV=$(abspath $(RISCV)) run-asm-tests-fast + $(MAKE) -C $(abspath $(TOP))/vsim PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) run-asm-tests-fast date > $@ stamps/%/vsim-bmark-tests.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - $(MAKE) -C $(abspath $(TOP))/vsim CONFIG=$* RISCV=$(abspath $(RISCV)) run-bmark-tests-fast + $(MAKE) -C $(abspath $(TOP))/vsim PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) run-bmark-tests-fast date > $@ stamps/%/vsim-regression-tests.stamp: stamps/other-submodules.stamp $(RISCV)/install.stamp mkdir -p $(dir $@) - $(MAKE) -C $(abspath $(TOP))/vsim CONFIG=$* RISCV=$(abspath $(RISCV)) clean-run-output - $(MAKE) -C $(abspath $(TOP))/vsim CONFIG=$* RISCV=$(abspath $(RISCV)) run-regression-tests-fast + $(MAKE) -C $(abspath $(TOP))/vsim PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) clean-run-output + $(MAKE) -C $(abspath $(TOP))/vsim PROJECT=$(PROJECT) CONFIG=$* RISCV=$(abspath $(RISCV)) run-regression-tests-fast date > $@ # The torture tests run subtly differently on the different targets, so they diff --git a/src/main/scala/coreplex/UnitTest.scala b/src/main/scala/coreplex/UnitTest.scala deleted file mode 100644 index ca8e66da..00000000 --- a/src/main/scala/coreplex/UnitTest.scala +++ /dev/null @@ -1,26 +0,0 @@ -package coreplex - -import Chisel._ -import unittest.UnitTestSuite -import rocket.Tile -import uncore.tilelink.TLId -import cde.Parameters - -class UnitTestCoreplex(tp: Parameters, tc: CoreplexConfig) extends Coreplex()(tp, tc) { - require(tc.nSlaves == 0) - require(tc.nMemChannels == 0) - - io.master.mmio.foreach { port => - port.acquire.valid := Bool(false) - port.grant.ready := Bool(false) - } - - io.debug.req.ready := Bool(false) - io.debug.resp.valid := Bool(false) - - val l1params = p.alterPartial({ case TLId => "L1toL2" }) - val tests = Module(new UnitTestSuite()(l1params)) - - override def hasSuccessFlag = true - io.success.get := tests.io.finished -} diff --git a/src/main/scala/rocketchip/TestConfigs.scala b/src/main/scala/rocketchip/TestConfigs.scala index 3af73d31..96127f16 100644 --- a/src/main/scala/rocketchip/TestConfigs.scala +++ b/src/main/scala/rocketchip/TestConfigs.scala @@ -7,7 +7,6 @@ import uncore.tilelink._ import uncore.coherence._ import uncore.agents._ import uncore.devices.NTiles -import unittest._ import junctions._ import scala.collection.mutable.LinkedHashSet import scala.collection.immutable.HashMap @@ -16,29 +15,6 @@ import scala.math.max import coreplex._ import ConfigUtils._ -class WithUnitTest extends Config( - (pname, site, here) => pname match { - case BuildCoreplex => { - val groundtest = if (site(XLen) == 64) - DefaultTestSuites.groundtest64 - else - DefaultTestSuites.groundtest32 - TestGeneration.addSuite(groundtest("p")) - TestGeneration.addSuite(DefaultTestSuites.emptyBmarks) - (p: Parameters, c: CoreplexConfig) => Module(new UnitTestCoreplex(p, c)) - } - case UnitTests => (testParams: Parameters) => - JunctionsUnitTests(testParams) ++ UncoreUnitTests(testParams) - case NMemoryChannels => Dump("N_MEM_CHANNELS", 0) - case FPUKey => None - case UseAtomics => false - case UseCompressed => false - case RegressionTestNames => LinkedHashSet("rv64ui-p-simple") - case _ => throw new CDEMatchError - }) - -class UnitTestConfig extends Config(new WithUnitTest ++ new BaseConfig) - class WithGroundTest extends Config( (pname, site, here) => pname match { case BuildCoreplex => diff --git a/src/main/scala/rocketchip/UnitTest.scala b/src/main/scala/rocketchip/UnitTest.scala new file mode 100644 index 00000000..d310caac --- /dev/null +++ b/src/main/scala/rocketchip/UnitTest.scala @@ -0,0 +1,46 @@ +// See LICENSE for license details. + +package rocketchip.utest + +import scala.collection.mutable.LinkedHashSet + +import Chisel._ +import cde.{Parameters, Config, Dump, Knob, CDEMatchError} +import util.{ParameterizedBundle} +import rocket._ +import uncore.tilelink._ +import uncore.tilelink2.{LazyModule, LazyModuleImp} +import coreplex._ +import rocketchip._ +import unittest._ + +class WithUnitTest extends Config( + (pname, site, here) => pname match { + case UnitTests => (testParams: Parameters) => { + val groundtest = if (site(XLen) == 64) + DefaultTestSuites.groundtest64 + else + DefaultTestSuites.groundtest32 + TestGeneration.addSuite(groundtest("p")) + TestGeneration.addSuite(DefaultTestSuites.emptyBmarks) + JunctionsUnitTests(testParams) ++ UncoreUnitTests(testParams) + } + case RegressionTestNames => LinkedHashSet("rv64ui-p-simple") + case _ => throw new CDEMatchError + }) + +class UnitTestConfig extends Config(new WithUnitTest ++ new BaseConfig) + +class TestHarness(implicit val p: Parameters) extends Module { + val io = new Bundle { + val success = Bool(OUTPUT) + } + + p(NCoreplexExtClients).assign(0) + p(ConfigString).assign("") + + val l1params = p.alterPartial({ case TLId => "L1toL2" }) + val tests = Module(new UnitTestSuite()(l1params)) + + io.success := tests.io.finished +}