diff --git a/rocket-chip b/rocket-chip index f3299ae9..fef522a0 160000 --- a/rocket-chip +++ b/rocket-chip @@ -1 +1 @@ -Subproject commit f3299ae91d3f01d0349eb4746886e303e8fb1b41 +Subproject commit fef522a0059a472a708be978abea72d7bf3cd055 diff --git a/src/main/scala/example/Configs.scala b/src/main/scala/example/Configs.scala index d718908a..d04cdeda 100644 --- a/src/main/scala/example/Configs.scala +++ b/src/main/scala/example/Configs.scala @@ -1,7 +1,7 @@ package example -import cde.{Parameters, Config, CDEMatchError} +import config.{Parameters, Config} import testchipip.WithSerialAdapter class DefaultExampleConfig extends Config( - new WithSerialAdapter ++ new rocketchip.BaseConfig) + new WithSerialAdapter ++ new rocketchip.DefaultConfig) diff --git a/src/main/scala/example/TestHarness.scala b/src/main/scala/example/TestHarness.scala index a6d8c290..32fe4954 100644 --- a/src/main/scala/example/TestHarness.scala +++ b/src/main/scala/example/TestHarness.scala @@ -5,24 +5,26 @@ import diplomacy.LazyModule import rocketchip._ import testchipip._ import chisel3._ -import cde.Parameters +import config.Parameters class TestHarness(implicit val p: Parameters) extends Module { val io = IO(new Bundle { val success = Output(Bool()) }) - def buildTop(p: Parameters): ExampleTop = LazyModule(new ExampleTop(p)) + def buildTop(p: Parameters): ExampleTop = LazyModule(new ExampleTop()(p)) - val dut = buildTop(p).module + val dut = Module(buildTop(p).module) val ser = Module(new SimSerialWrapper(p(SerialInterfaceWidth))) - val nMemChannels = dut.io.mem_axi.size - for (axi <- dut.io.mem_axi) { - val mem = Module(new SimAXIMem(BigInt(p(ExtMemSize) / nMemChannels))) - mem.io.axi <> axi + dut.io.debug.map { dbg => + dbg.req.valid := false.B + dbg.resp.ready := false.B } + val nMemChannels = p(coreplex.BankedL2Config).nMemoryChannels + val mem = Module(LazyModule(new SimAXIMem(nMemChannels)).module) + mem.io.axi4 <> dut.io.mem_axi4 ser.io.serial <> dut.io.serial io.success := ser.io.exit } diff --git a/src/main/scala/example/Top.scala b/src/main/scala/example/Top.scala index 3174227d..b1ba4a02 100644 --- a/src/main/scala/example/Top.scala +++ b/src/main/scala/example/Top.scala @@ -1,23 +1,39 @@ package example import chisel3._ -import cde.Parameters +import config.Parameters import testchipip._ import rocketchip._ -class ExampleTop(q: Parameters) extends BaseTop(q) - with PeripheryBootROM with PeripheryCoreplexLocalInterrupter - with PeripherySerial with PeripheryMasterMem { - override lazy val module = Module( - new ExampleTopModule(p, this, new ExampleTopBundle(p))) +class ExampleTop(implicit p: Parameters) extends BaseTop()(p) + with PeripheryMasterAXI4Mem + with PeripheryBootROM + with PeripheryZero + with PeripheryCounter + with PeripheryDebug + with HardwiredResetVector + with RocketPlexMaster + with PeripherySerial { + override lazy val module = new ExampleTopModule(this, () => new ExampleTopBundle(this)) } -class ExampleTopBundle(p: Parameters) extends BaseTopBundle(p) - with PeripheryBootROMBundle with PeripheryCoreplexLocalInterrupterBundle - with PeripheryMasterMemBundle with PeripherySerialBundle +class ExampleTopBundle[+L <: ExampleTop](l: L) extends BaseTopBundle(l) + with PeripheryMasterAXI4MemBundle + with PeripheryBootROMBundle + with PeripheryZeroBundle + with PeripheryCounterBundle + with PeripheryDebugBundle + with HardwiredResetVectorBundle + with RocketPlexMasterBundle + with PeripherySerialBundle -class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, l: L, b: => B) - extends BaseTopModule(p, l, b) - with PeripheryBootROMModule with PeripheryCoreplexLocalInterrupterModule - with PeripheryMasterMemModule with PeripherySerialModule - with HardwiredResetVector with DirectConnection with NoDebug +class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](l: L, b: () => B) + extends BaseTopModule(l, b) + with PeripheryMasterAXI4MemModule + with PeripheryBootROMModule + with PeripheryZeroModule + with PeripheryCounterModule + with PeripheryDebugModule + with HardwiredResetVectorModule + with RocketPlexMasterModule + with PeripherySerialModule diff --git a/src/main/scala/pwm/Configs.scala b/src/main/scala/pwm/Configs.scala index bd5b6d68..4096a6a0 100644 --- a/src/main/scala/pwm/Configs.scala +++ b/src/main/scala/pwm/Configs.scala @@ -1,29 +1,8 @@ package pwm -import cde.{Parameters, Config, CDEMatchError} +import config.{Parameters, Config} import testchipip.WithSerialAdapter import uncore.tilelink.ClientUncachedTileLinkIO -import rocketchip.PeripheryUtils import chisel3._ -class WithPWMAXI extends Config( - (pname, site, here) => pname match { - case BuildPWM => (port: ClientUncachedTileLinkIO, p: Parameters) => { - val pwm = Module(new PWMAXI()(p)) - pwm.io.axi <> PeripheryUtils.convertTLtoAXI(port) - pwm.io.pwmout - } - case _ => throw new CDEMatchError - }) - -class WithPWMTL extends Config( - (pname, site, here) => pname match { - case BuildPWM => (port: ClientUncachedTileLinkIO, p: Parameters) => { - val pwm = Module(new PWMTL()(p)) - pwm.io.tl <> port - pwm.io.pwmout - } - }) - -class PWMAXIConfig extends Config(new WithPWMAXI ++ new example.DefaultExampleConfig) -class PWMTLConfig extends Config(new WithPWMTL ++ new example.DefaultExampleConfig) +class PWMConfig extends Config(new example.DefaultExampleConfig) diff --git a/src/main/scala/pwm/PWM.scala b/src/main/scala/pwm/PWM.scala index c6eeee77..463e2d96 100644 --- a/src/main/scala/pwm/PWM.scala +++ b/src/main/scala/pwm/PWM.scala @@ -2,22 +2,24 @@ package pwm import chisel3._ import chisel3.util._ -import cde.{Parameters, Field} +import config.{Parameters, Field} import uncore.tilelink._ +import uncore.tilelink2._ import junctions._ import diplomacy._ import rocketchip._ +import _root_.util.UIntIsOneOf -class PWMBase extends Module { +class PWMBase(w: Int) extends Module { val io = IO(new Bundle { val pwmout = Output(Bool()) - val period = Input(UInt(64.W)) - val duty = Input(UInt(64.W)) + val period = Input(UInt(w.W)) + val duty = Input(UInt(w.W)) val enable = Input(Bool()) }) // The counter should count up until period is reached - val counter = Reg(UInt(64.W)) + val counter = Reg(UInt(w.W)) when (counter >= (io.period - 1.U)) { counter := 0.U @@ -30,62 +32,70 @@ class PWMBase extends Module { io.pwmout := io.enable && (counter < io.duty) } -class PWMTL(implicit p: Parameters) extends Module { +class PWMTL(address: AddressSet, beatBytes: Int)(implicit p: Parameters) extends LazyModule { + val node = TLManagerNode(Seq(TLManagerPortParameters( + Seq(TLManagerParameters( + address = List(address), + regionType = RegionType.PUT_EFFECTS, + executable = false, + supportsGet = TransferSizes(1, beatBytes), + supportsPutFull = TransferSizes(1, beatBytes), + fifoId = Some(0))), // requests are handled in order + beatBytes = beatBytes, + minLatency = 1))) + + lazy val module = new PWMTLModule(this, beatBytes) +} + +class PWMTLModule(outer: PWMTL, beatBytes: Int) extends LazyModuleImp(outer) { val io = IO(new Bundle { val pwmout = Output(Bool()) - val tl = Flipped(new ClientUncachedTileLinkIO()) + val tl = outer.node.bundleIn }) + val w = beatBytes * 8 // How many clock cycles in a PWM cycle? - val period = Reg(UInt(64.W)) + val period = Reg(UInt(w.W)) // For how many cycles should the clock be high? - val duty = Reg(UInt(64.W)) + val duty = Reg(UInt(w.W)) // Is the PWM even running at all? val enable = Reg(init = false.B) - val base = Module(new PWMBase) + val base = Module(new PWMBase(w)) io.pwmout := base.io.pwmout base.io.period := period base.io.duty := duty base.io.enable := enable + val tl = io.tl.head + + tl.b.valid := false.B + tl.c.ready := false.B + tl.e.ready := false.B + // One entry queue to hold the acquire message - val acq = Queue(io.tl.acquire, 1) + val acq = Queue(tl.a, 1) - // We assume that the TileLink interface is 64 bits wide - require(io.tl.tlDataBits == 64) + // We have 3 32-bit registers + val index = acq.bits.address(3, 2) - // Then addr_block and addr_beat together form the word address - val full_addr = Cat(acq.bits.addr_block, acq.bits.addr_beat) - // Since we have 3 registers, we only need the lower two bits to distinguish them - val index = full_addr(1, 0) - - // Make sure the acquires we get are only the types we expect - assert(!acq.valid || - acq.bits.isBuiltInType(Acquire.getType) || - acq.bits.isBuiltInType(Acquire.putType)) - - // Make sure write masks are full - assert(!acq.valid || !acq.bits.hasData() || - acq.bits.wmask() === Acquire.fullWriteMask) + val edge = outer.node.edgesIn(0) + val hasData = edge.hasData(acq.bits) // Base the grant on the stored acquire - io.tl.grant.valid := acq.valid - acq.ready := io.tl.grant.ready - io.tl.grant.bits := Grant( - is_builtin_type = true.B, - g_type = acq.bits.getBuiltInGrantType(), - client_xact_id = acq.bits.client_xact_id, - manager_xact_id = 0.U, - addr_beat = acq.bits.addr_beat, - // For gets, map the index to the three registers - data = MuxLookup(index, 0.U, Seq( + tl.d.valid := acq.valid + acq.ready := tl.d.ready + tl.d.bits := edge.AccessAck(acq.bits, 0.U) + tl.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData) + tl.d.bits.data := MuxLookup(index, 0.U, + Seq( 0.U -> period, 1.U -> duty, - 2.U -> enable))) + 2.U -> enable)) + tl.d.bits.error := index > 2.U // If this is a put, update the registers according to the index - when (acq.fire() && acq.bits.hasData()) { + when (acq.fire() && acq.bits.opcode === TLMessages.PutFullData) { switch (index) { is (0.U) { period := acq.bits.data } is (1.U) { duty := acq.bits.data } @@ -94,79 +104,24 @@ class PWMTL(implicit p: Parameters) extends Module { } } -class PWMAXI(implicit p: Parameters) extends Module { - val io = IO(new Bundle { - val pwmout = Output(Bool()) - val axi = Flipped(new NastiIO()) - }) +trait PeripheryPWM extends LazyModule with HasPeripheryParameters { + implicit val p: Parameters + val peripheryBus: TLXbar - // How many clock cycles in a PWM cycle? - val period = Reg(UInt(64.W)) - // For how many cycles should the clock be high? - val duty = Reg(UInt(64.W)) - // Is the PWM even running at all? - val enable = Reg(init = false.B) - - val base = Module(new PWMBase) - io.pwmout := base.io.pwmout - base.io.period := period - base.io.duty := duty - base.io.enable := enable - - val ar = Queue(io.axi.ar, 1) - val aw = Queue(io.axi.aw, 1) - val w = Queue(io.axi.w, 1) - - // Start from 3rd bit since 64-bit words - // Only need 2 bits, since 3 registers - val read_index = ar.bits.addr(4, 3) - val write_index = aw.bits.addr(4, 3) - - io.axi.r.valid := ar.valid - ar.ready := io.axi.r.ready - io.axi.r.bits := NastiReadDataChannel( - id = ar.bits.id, - data = MuxLookup(read_index, 0.U, Seq( - 0.U -> period, - 1.U -> duty, - 2.U -> enable))) - - io.axi.b.valid := aw.valid && w.valid - aw.ready := io.axi.b.ready && w.valid - w.ready := io.axi.b.ready && aw.valid - io.axi.b.bits := NastiWriteResponseChannel(id = aw.bits.id) - - when (io.axi.b.fire()) { - switch (write_index) { - is (0.U) { period := w.bits.data } - is (1.U) { duty := w.bits.data } - is (2.U) { enable := w.bits.data(0) } - } - } - - require(io.axi.w.bits.nastiXDataBits == 64) - - assert(!io.axi.ar.valid || (io.axi.ar.bits.len === 0.U && io.axi.ar.bits.size === 3.U)) - assert(!io.axi.aw.valid || (io.axi.aw.bits.len === 0.U && io.axi.aw.bits.size === 3.U)) - assert(!io.axi.w.valid || PopCount(io.axi.w.bits.strb) === 8.U) -} - -trait PeripheryPWM extends LazyModule { - val pDevices: ResourceManager[AddrMapEntry] - - pDevices.add(AddrMapEntry("pwm", MemSize(4096, MemAttr(AddrMapProt.RW)))) + private val address = AddressSet(0x2000, 0xfff) + val pwm = LazyModule(new PWMTL(address, peripheryBusConfig.beatBytes)(p)) + pwm.node := TLFragmenter( + peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) } trait PeripheryPWMBundle { val pwmout = Output(Bool()) } -case object BuildPWM extends Field[(ClientUncachedTileLinkIO, Parameters) => Bool] - trait PeripheryPWMModule extends HasPeripheryParameters { implicit val p: Parameters - val pBus: TileLinkRecursiveInterconnect val io: PeripheryPWMBundle + val outer: PeripheryPWM - io.pwmout := p(BuildPWM)(pBus.port("pwm"), outerMMIOParams) + io.pwmout := outer.pwm.module.io.pwmout } diff --git a/src/main/scala/pwm/TestHarness.scala b/src/main/scala/pwm/TestHarness.scala index eb8487f8..0415b649 100644 --- a/src/main/scala/pwm/TestHarness.scala +++ b/src/main/scala/pwm/TestHarness.scala @@ -1,12 +1,12 @@ package pwm import util.GeneratorApp -import cde.Parameters +import config.Parameters import diplomacy.LazyModule class TestHarness(q: Parameters) extends example.TestHarness()(q) { override def buildTop(p: Parameters) = - LazyModule(new ExampleTopWithPWM(p)) + LazyModule(new ExampleTopWithPWM()(p)) } object Generator extends GeneratorApp { diff --git a/src/main/scala/pwm/Top.scala b/src/main/scala/pwm/Top.scala index b6e3bc6d..32add8fb 100644 --- a/src/main/scala/pwm/Top.scala +++ b/src/main/scala/pwm/Top.scala @@ -2,16 +2,16 @@ package pwm import chisel3._ import example._ -import cde.Parameters +import config.Parameters -class ExampleTopWithPWM(q: Parameters) extends ExampleTop(q) +class ExampleTopWithPWM(implicit p: Parameters) extends ExampleTop()(p) with PeripheryPWM { - override lazy val module = Module( - new ExampleTopWithPWMModule(p, this, new ExampleTopWithPWMBundle(p))) + override lazy val module = new ExampleTopWithPWMModule(this, () => new ExampleTopWithPWMBundle(this)) } -class ExampleTopWithPWMBundle(p: Parameters) extends ExampleTopBundle(p) +class ExampleTopWithPWMBundle[+L <: ExampleTopWithPWM](l: L) + extends ExampleTopBundle(l) with PeripheryPWMBundle -class ExampleTopWithPWMModule(p: Parameters, l: ExampleTopWithPWM, b: => ExampleTopWithPWMBundle) - extends ExampleTopModule(p, l, b) with PeripheryPWMModule +class ExampleTopWithPWMModule[+L <: ExampleTopWithPWM, +B <: ExampleTopWithPWMBundle[L]](l: L, b: () => B) + extends ExampleTopModule(l, b) with PeripheryPWMModule diff --git a/testchipip b/testchipip index 4b6fe076..a9d2ee6c 160000 --- a/testchipip +++ b/testchipip @@ -1 +1 @@ -Subproject commit 4b6fe076cfab3c685fd6201559221cbad858c77e +Subproject commit a9d2ee6cb632f1506f658f581d39cd49c3617e21 diff --git a/tests/pwm.c b/tests/pwm.c index e4c5266f..3b6762cd 100644 --- a/tests/pwm.c +++ b/tests/pwm.c @@ -1,16 +1,16 @@ #define PWM_PERIOD 0x2000 -#define PWM_DUTY 0x2008 -#define PWM_ENABLE 0x2010 +#define PWM_DUTY 0x2004 +#define PWM_ENABLE 0x2008 -static inline void write_reg(unsigned long addr, unsigned long data) +static inline void write_reg(unsigned long addr, unsigned int data) { - volatile unsigned long *ptr = (volatile unsigned long *) addr; + volatile unsigned int *ptr = (volatile unsigned int *) addr; *ptr = data; } static inline unsigned long read_reg(unsigned long addr) { - volatile unsigned long *ptr = (volatile unsigned long *) addr; + volatile unsigned int *ptr = (volatile unsigned int *) addr; return *ptr; } diff --git a/vsim/Makefile b/vsim/Makefile index 1eeeeca4..0498d007 100644 --- a/vsim/Makefile +++ b/vsim/Makefile @@ -19,6 +19,7 @@ include $(base_dir)/Makefrag sim_vsrcs = \ $(build_dir)/$(PROJECT).$(MODEL).$(CONFIG).v \ $(base_dir)/rocket-chip/vsrc/TestDriver.v \ + $(base_dir)/rocket-chip/vsrc/AsyncResetReg.v \ $(base_dir)/testchipip/vsrc/SimSerial.v sim_csrcs = \