Skip to content

Commit ff1de98

Browse files
committed
Annotate Chisel Memories
- Added "createAnno" from DefMemory, DefSeqMemory, FirrtlMemory and DefMemPort case - Implement "createAnnoMem" to create a TyeavesAnnotation for memory (a memory does not extend the Data type) - Return empty annotations from Connect, DefInvalid - Add warning message for "Unhandled circuit commands" - Added the following tests: - ROM of ground type - SyncReadMem (when UNUSED) of ground type, aggregate types (bundle) - Mem (when UNUSED) of ground type, aggregate types (bundle) - SRAM of ground type (with different combs of ports), aggregate types - SyncReadMem (when USED) of ground type, aggregate types (this instantiate MPORT) - Mem (when USED) of ground type, aggregate types (this instantiate MPORT)
1 parent e6de3b6 commit ff1de98

File tree

4 files changed

+673
-13
lines changed

4 files changed

+673
-13
lines changed

core/src/main/scala/chisel3/tywaves/TywavesAnnotation.scala

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package chisel3.tywaves
22

33
import chisel3.{Aggregate, Bits, Bundle, Data, Record, Vec, VecLike}
44
import chisel3.experimental.{annotate, BaseModule, ChiselAnnotation}
5+
import chisel3.internal.HasId
56
import chisel3.internal.firrtl.Converter.convert
67
import chisel3.internal.firrtl.ir._
78
import firrtl.annotations.{Annotation, IsMember, ReferenceTarget, SingleTargetAnnotation}
@@ -61,23 +62,32 @@ object TywavesChiselAnnotation {
6162
def generate(port: Port, typeAliases: Seq[String]): Seq[ChiselAnnotation] = createAnno(port.id)
6263

6364
def generate(command: Command, typeAliases: Seq[String]): Seq[ChiselAnnotation] = {
65+
def createAnnoMem(target: HasId, binding: String, size: BigInt, innerType: Data): Seq[ChiselAnnotation] = {
66+
val name = s"$binding[${innerType.typeName}[$size]]"
67+
// TODO: what if innerType is a Vec or a Bundle?
68+
69+
Seq(new ChiselAnnotation {
70+
override def toFirrtl: Annotation = TywavesAnnotation(target.toTarget, name)
71+
}) //++ createAnno(chisel3.Wire(innerType))
72+
}
6473

6574
command match {
6675
case e: DefPrim[_] => ???
67-
case e @ DefWire(info, id) => createAnno(id)
68-
case e @ DefReg(info, id, clock) => createAnno(id)
69-
case e @ DefRegInit(info, id, clock, reset, init) => createAnno(id)
70-
case e @ DefMemory(info, id, t, size) => ???
71-
case e @ DefSeqMemory(info, id, t, size, ruw) => ???
72-
case e @ FirrtlMemory(info, id, t, size, readPortNames, writePortNames, readwritePortNames) => ???
73-
case e: DefMemPort[_] => ???
74-
case Connect(info, loc, exp) => println(s"Connect: $info, $loc, $exp"); Seq.empty
76+
case e @ DefWire(info, id) => createAnno(id)
77+
case e @ DefReg(info, id, clock) => createAnno(id)
78+
case e @ DefRegInit(info, id, clock, reset, init) => createAnno(id)
79+
case e @ DefMemory(info, id, t, size) => createAnnoMem(id, id.getClass.getSimpleName, size, t)
80+
case e @ DefSeqMemory(info, id, t, size, ruw) => createAnnoMem(id, id.getClass.getSimpleName, size, t)
81+
case e @ FirrtlMemory(info, id, t, size, readPortNames, writePortNames, readwritePortNames) =>
82+
createAnnoMem(id, id.getClass.getSimpleName, size, t)
83+
case e @ DefMemPort(info, id, source, dir, idx, clock) => createAnno(id)
84+
case Connect(info, loc, exp) => Seq.empty // TODO: check connect
7585
case PropAssign(info, loc, exp) => ???
7686
case Attach(info, locs) => ???
77-
case DefInvalid(info, arg) => ???
78-
case e @ DefInstance(info, id, _) => Seq.empty // Seq(createAnno(id))
87+
case DefInvalid(info, arg) => Seq.empty // TODO: check invalid
88+
case e @ DefInstance(info, id, _) => Seq.empty // TODO: check instance
7989
case e @ DefInstanceChoice(info, _, default, option, choices) => ???
80-
case e @ DefObject(info, _, className) => println(s"DefObject: $info, $className"); Seq.empty
90+
case e @ DefObject(info, _, className) => Seq.empty // TODO: check object
8191
case e @ Stop(_, info, clock, ret) => ???
8292
case e @ Printf(_, info, clock, pable) => ???
8393
case e @ ProbeDefine(sourceInfo, sink, probeExpr) => ???
@@ -86,11 +96,12 @@ object TywavesChiselAnnotation {
8696
case e @ ProbeForce(sourceInfo, clock, cond, probe, value) => ???
8797
case e @ ProbeRelease(sourceInfo, clock, cond, probe) => ???
8898
case e @ Verification(_, op, info, clk, pred, pable) => ???
89-
case _ => Seq.empty
99+
case e =>
100+
println(s"Unknown command: $e") // TODO: replace with logger
101+
Seq.empty
90102
}
91103
// TODO: Add tywaves annotation
92104

93-
// ???
94105
}
95106

96107
/**

src/test/scala/circtTests/tywavesTests/TywavesAnnotationCircuits.scala

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,54 @@ object TywavesAnnotationCircuits {
224224
}
225225
}
226226

227+
object MemCircuits {
228+
// Test memory ROM: https://www.chisel-lang.org/docs/explanations/memories#rom
229+
class ROMs {
230+
231+
import chisel3.experimental.BundleLiterals._
232+
233+
val romFromVec: Vec[UInt] = Wire(Vec(4, UInt(8.W)))
234+
val romFromVecInit: Vec[UInt] = VecInit(1.U, 2.U, 4.U, 8.U)
235+
for (i <- 0 until 4) {
236+
romFromVec(i) := romFromVecInit(i)
237+
}
238+
val bundle = new Bundle {
239+
val a: UInt = UInt(8.W)
240+
}
241+
val romOfBundles =
242+
VecInit(bundle.Lit(_.a -> 1.U), bundle.Lit(_.a -> 2.U), bundle.Lit(_.a -> 4.U), bundle.Lit(_.a -> 8.U))
243+
}
244+
245+
// TODO: having children in the roms object does not imply the same hierarchy in firrtl (roms is pure scala)
246+
class TopCircuitROM extends RawModule {
247+
val roms = new ROMs
248+
}
249+
250+
class TopCircuitSyncMem[T <: Data](gen: T, withConnection: Boolean /* If true connect memPort */ ) extends Module {
251+
val mem = SyncReadMem(4, gen)
252+
if (withConnection) {
253+
val idx = IO(Input(UInt(2.W)))
254+
val in = IO(Input(gen))
255+
val out = IO(Output(gen))
256+
mem.write(idx, in)
257+
out := mem.read(idx)
258+
}
259+
}
260+
261+
class TopCircuitMem[T <: Data](gen: T, withConnection: Boolean) extends Module {
262+
val mem = Mem(4, gen)
263+
if (withConnection) {
264+
val idx = IO(Input(UInt(2.W)))
265+
val in = IO(Input(gen))
266+
val out = IO(Output(gen))
267+
mem(idx) := in
268+
out := mem(idx)
269+
}
270+
}
271+
272+
class TopCircuitSRAM[T <: Data](gen: T, size: Int, numReadPorts: Int, numWritePorts: Int, numReadwritePorts: Int)
273+
extends Module {
274+
val mem = SRAM(size, gen, numReadPorts, numWritePorts, numReadwritePorts)
275+
}
276+
}
227277
}

0 commit comments

Comments
 (0)