update to tilelink2

This commit is contained in:
Howard Mao
2017-04-20 17:44:05 -07:00
parent 2fecb10cfc
commit 27bd063441
11 changed files with 117 additions and 164 deletions

View File

@@ -1,7 +1,7 @@
package example package example
import cde.{Parameters, Config, CDEMatchError} import config.{Parameters, Config}
import testchipip.WithSerialAdapter import testchipip.WithSerialAdapter
class DefaultExampleConfig extends Config( class DefaultExampleConfig extends Config(
new WithSerialAdapter ++ new rocketchip.BaseConfig) new WithSerialAdapter ++ new rocketchip.DefaultConfig)

View File

@@ -5,24 +5,26 @@ import diplomacy.LazyModule
import rocketchip._ import rocketchip._
import testchipip._ import testchipip._
import chisel3._ import chisel3._
import cde.Parameters import config.Parameters
class TestHarness(implicit val p: Parameters) extends Module { class TestHarness(implicit val p: Parameters) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val success = Output(Bool()) 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 ser = Module(new SimSerialWrapper(p(SerialInterfaceWidth)))
val nMemChannels = dut.io.mem_axi.size dut.io.debug.map { dbg =>
for (axi <- dut.io.mem_axi) { dbg.req.valid := false.B
val mem = Module(new SimAXIMem(BigInt(p(ExtMemSize) / nMemChannels))) dbg.resp.ready := false.B
mem.io.axi <> axi
} }
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 ser.io.serial <> dut.io.serial
io.success := ser.io.exit io.success := ser.io.exit
} }

View File

@@ -1,23 +1,39 @@
package example package example
import chisel3._ import chisel3._
import cde.Parameters import config.Parameters
import testchipip._ import testchipip._
import rocketchip._ import rocketchip._
class ExampleTop(q: Parameters) extends BaseTop(q) class ExampleTop(implicit p: Parameters) extends BaseTop()(p)
with PeripheryBootROM with PeripheryCoreplexLocalInterrupter with PeripheryMasterAXI4Mem
with PeripherySerial with PeripheryMasterMem { with PeripheryBootROM
override lazy val module = Module( with PeripheryZero
new ExampleTopModule(p, this, new ExampleTopBundle(p))) 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) class ExampleTopBundle[+L <: ExampleTop](l: L) extends BaseTopBundle(l)
with PeripheryBootROMBundle with PeripheryCoreplexLocalInterrupterBundle with PeripheryMasterAXI4MemBundle
with PeripheryMasterMemBundle with PeripherySerialBundle 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) class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](l: L, b: () => B)
extends BaseTopModule(p, l, b) extends BaseTopModule(l, b)
with PeripheryBootROMModule with PeripheryCoreplexLocalInterrupterModule with PeripheryMasterAXI4MemModule
with PeripheryMasterMemModule with PeripherySerialModule with PeripheryBootROMModule
with HardwiredResetVector with DirectConnection with NoDebug with PeripheryZeroModule
with PeripheryCounterModule
with PeripheryDebugModule
with HardwiredResetVectorModule
with RocketPlexMasterModule
with PeripherySerialModule

View File

@@ -1,29 +1,8 @@
package pwm package pwm
import cde.{Parameters, Config, CDEMatchError} import config.{Parameters, Config}
import testchipip.WithSerialAdapter import testchipip.WithSerialAdapter
import uncore.tilelink.ClientUncachedTileLinkIO import uncore.tilelink.ClientUncachedTileLinkIO
import rocketchip.PeripheryUtils
import chisel3._ import chisel3._
class WithPWMAXI extends Config( class PWMConfig extends Config(new example.DefaultExampleConfig)
(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)

View File

@@ -2,22 +2,24 @@ package pwm
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import cde.{Parameters, Field} import config.{Parameters, Field}
import uncore.tilelink._ import uncore.tilelink._
import uncore.tilelink2._
import junctions._ import junctions._
import diplomacy._ import diplomacy._
import rocketchip._ import rocketchip._
import _root_.util.UIntIsOneOf
class PWMBase extends Module { class PWMBase(w: Int) extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val pwmout = Output(Bool()) val pwmout = Output(Bool())
val period = Input(UInt(64.W)) val period = Input(UInt(w.W))
val duty = Input(UInt(64.W)) val duty = Input(UInt(w.W))
val enable = Input(Bool()) val enable = Input(Bool())
}) })
// The counter should count up until period is reached // 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)) { when (counter >= (io.period - 1.U)) {
counter := 0.U counter := 0.U
@@ -30,62 +32,70 @@ class PWMBase extends Module {
io.pwmout := io.enable && (counter < io.duty) 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 io = IO(new Bundle {
val pwmout = Output(Bool()) 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? // 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? // 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? // Is the PWM even running at all?
val enable = Reg(init = false.B) val enable = Reg(init = false.B)
val base = Module(new PWMBase) val base = Module(new PWMBase(w))
io.pwmout := base.io.pwmout io.pwmout := base.io.pwmout
base.io.period := period base.io.period := period
base.io.duty := duty base.io.duty := duty
base.io.enable := enable 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 // 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 // We have 3 32-bit registers
require(io.tl.tlDataBits == 64) val index = acq.bits.address(3, 2)
// Then addr_block and addr_beat together form the word address val edge = outer.node.edgesIn(0)
val full_addr = Cat(acq.bits.addr_block, acq.bits.addr_beat) val hasData = edge.hasData(acq.bits)
// 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)
// Base the grant on the stored acquire // Base the grant on the stored acquire
io.tl.grant.valid := acq.valid tl.d.valid := acq.valid
acq.ready := io.tl.grant.ready acq.ready := tl.d.ready
io.tl.grant.bits := Grant( tl.d.bits := edge.AccessAck(acq.bits, 0.U)
is_builtin_type = true.B, tl.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData)
g_type = acq.bits.getBuiltInGrantType(), tl.d.bits.data := MuxLookup(index, 0.U,
client_xact_id = acq.bits.client_xact_id, Seq(
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(
0.U -> period, 0.U -> period,
1.U -> duty, 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 // 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) { switch (index) {
is (0.U) { period := acq.bits.data } is (0.U) { period := acq.bits.data }
is (1.U) { duty := 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 { trait PeripheryPWM extends LazyModule with HasPeripheryParameters {
val io = IO(new Bundle { implicit val p: Parameters
val pwmout = Output(Bool()) val peripheryBus: TLXbar
val axi = Flipped(new NastiIO())
})
// How many clock cycles in a PWM cycle? private val address = AddressSet(0x2000, 0xfff)
val period = Reg(UInt(64.W)) val pwm = LazyModule(new PWMTL(address, peripheryBusConfig.beatBytes)(p))
// For how many cycles should the clock be high? pwm.node := TLFragmenter(
val duty = Reg(UInt(64.W)) peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
// 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))))
} }
trait PeripheryPWMBundle { trait PeripheryPWMBundle {
val pwmout = Output(Bool()) val pwmout = Output(Bool())
} }
case object BuildPWM extends Field[(ClientUncachedTileLinkIO, Parameters) => Bool]
trait PeripheryPWMModule extends HasPeripheryParameters { trait PeripheryPWMModule extends HasPeripheryParameters {
implicit val p: Parameters implicit val p: Parameters
val pBus: TileLinkRecursiveInterconnect
val io: PeripheryPWMBundle val io: PeripheryPWMBundle
val outer: PeripheryPWM
io.pwmout := p(BuildPWM)(pBus.port("pwm"), outerMMIOParams) io.pwmout := outer.pwm.module.io.pwmout
} }

View File

@@ -1,12 +1,12 @@
package pwm package pwm
import util.GeneratorApp import util.GeneratorApp
import cde.Parameters import config.Parameters
import diplomacy.LazyModule import diplomacy.LazyModule
class TestHarness(q: Parameters) extends example.TestHarness()(q) { class TestHarness(q: Parameters) extends example.TestHarness()(q) {
override def buildTop(p: Parameters) = override def buildTop(p: Parameters) =
LazyModule(new ExampleTopWithPWM(p)) LazyModule(new ExampleTopWithPWM()(p))
} }
object Generator extends GeneratorApp { object Generator extends GeneratorApp {

View File

@@ -2,16 +2,16 @@ package pwm
import chisel3._ import chisel3._
import example._ 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 { with PeripheryPWM {
override lazy val module = Module( override lazy val module = new ExampleTopWithPWMModule(this, () => new ExampleTopWithPWMBundle(this))
new ExampleTopWithPWMModule(p, this, new ExampleTopWithPWMBundle(p)))
} }
class ExampleTopWithPWMBundle(p: Parameters) extends ExampleTopBundle(p) class ExampleTopWithPWMBundle[+L <: ExampleTopWithPWM](l: L)
extends ExampleTopBundle(l)
with PeripheryPWMBundle with PeripheryPWMBundle
class ExampleTopWithPWMModule(p: Parameters, l: ExampleTopWithPWM, b: => ExampleTopWithPWMBundle) class ExampleTopWithPWMModule[+L <: ExampleTopWithPWM, +B <: ExampleTopWithPWMBundle[L]](l: L, b: () => B)
extends ExampleTopModule(p, l, b) with PeripheryPWMModule extends ExampleTopModule(l, b) with PeripheryPWMModule

View File

@@ -1,16 +1,16 @@
#define PWM_PERIOD 0x2000 #define PWM_PERIOD 0x2000
#define PWM_DUTY 0x2008 #define PWM_DUTY 0x2004
#define PWM_ENABLE 0x2010 #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; *ptr = data;
} }
static inline unsigned long read_reg(unsigned long addr) 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; return *ptr;
} }

View File

@@ -19,6 +19,7 @@ include $(base_dir)/Makefrag
sim_vsrcs = \ sim_vsrcs = \
$(build_dir)/$(PROJECT).$(MODEL).$(CONFIG).v \ $(build_dir)/$(PROJECT).$(MODEL).$(CONFIG).v \
$(base_dir)/rocket-chip/vsrc/TestDriver.v \ $(base_dir)/rocket-chip/vsrc/TestDriver.v \
$(base_dir)/rocket-chip/vsrc/AsyncResetReg.v \
$(base_dir)/testchipip/vsrc/SimSerial.v $(base_dir)/testchipip/vsrc/SimSerial.v
sim_csrcs = \ sim_csrcs = \