ClockDomain for input/output ports?
Per my current understanding, we sample input ports in a given clock domain (when it's not the default one) as follows:
case class DUT(monClock: ClockDomain = ClockDomain.external("monClock")) extends Component {
val io = new Bundle {
val monFire = in Bool()
}
val monArea = new ClockingArea(monClock) {
val fire = RegNext(io.monFire) init False
}
val cdcMonFire = BufferCC(monArea.fire, False)
// ...
}
I didn't manage to find a way to specify that monFire is clocked by and should only be sampled in monClock. Since it's mentioned in the document that SpinalHDL checks CDCs:
SpinalHDL checks at compile time that there are no unwanted/unspecified cross clock domain signal reads.
Is it possible to mark the input port with a specific clock domain to enforce this to the module ports as well?
To elaborate a bit, the purpose is to have the following trigger CLOCK CROSSING VIOLATION:
val monArea = new ClockingArea(monClock) {
val fire = in Bool()
}
val incorrectCdcFromPort = monArea.fire
To elaborate a bit, the purpose is to have the following trigger
CLOCK CROSSING VIOLATION:val monArea = new ClockingArea(monClock) { val fire = in Bool() } val incorrectCdcFromPort = monArea.fire
you can not assign clockdomain for a wire individually, but can be on a register
Is it what you are looking for ?
val cdA = ClockDomain.external("cdA")
val cdB = ClockDomain.external("cdB")
val a = in Bool()
val b = out Bool()
val tmp = Bool()
tmp := a
b := tmp
a.addTag(ClockDomainTag(cdA))
b.addTag(ClockDomainTag(cdB))
=>
CLOCK CROSSING VIOLATION :
- Source : (toplevel/a : in Bool) spinal.tester.code.Debug2$$anon$21.<init>(Debug.scala:318)
- Source clock : (cdA_clk : Bool)
- Destination : (toplevel/b : out Bool) spinal.tester.code.Debug2$$anon$21.<init>(Debug.scala:319)
- Destination clock : (cdB_clk : Bool)
- Source declaration :
spinal.tester.code.Debug2$$anon$21.<init>(Debug.scala:318)
spinal.tester.code.Debug2$.gen(Debug.scala:310)
spinal.tester.code.Debug2$.$anonfun$new$10(Debug.scala:618)
spinal.sim.JvmThread.run(SimManager.scala:51)
- Destination declaration :
spinal.tester.code.Debug2$$anon$21.<init>(Debug.scala:319)
spinal.tester.code.Debug2$.gen(Debug.scala:310)
spinal.tester.code.Debug2$.$anonfun$new$10(Debug.scala:618)
spinal.sim.JvmThread.run(SimManager.scala:51)
- Connection path :
>>> (toplevel/a : in Bool) at spinal.tester.code.Debug2$$anon$21.<init>(Debug.scala:318) >>>
>>> (toplevel/tmp : Bool) at spinal.tester.code.Debug2$$anon$21.<init>(Debug.scala:321) >>>
>>> (toplevel/b : out Bool) at spinal.tester.code.Debug2$$anon$21.<init>(Debug.scala:319) >>>
Nice! But looks like it doesn't work for BlackBoxes?
val cdA = ClockDomain.external("cdA")
val i = in Bool() addTag ClockDomainTag(cdA)
val bb = new BlackBox {
val i = in Bool()
val clk = in Bool()
val rst = in Bool()
mapCurrentClockDomain(clk, rst)
}
bb.i := i
hmm, did you tried i.addTag(ClockDomainTag(ClockDomain.current)) ?
Ok that works. But it seems like this tag is not implicitly added for all signals in a clock domain (either ClockArea or the default clock domain)? It's a bit tedious to add this to everything...
But it seems like this tag is not implicitly added for all signals in a clock domain
that's right
It's a bit tedious to add this to everything...
There is ways to automate that : getAllIo.foreach(_.addTag(ClockDomainTag(ClockDomain.current)))
Assuming they all use the blackbox current clockdomain
hmm overall i understand the point. There could be a baked in API to handle this.
@KireinaHoro Did this answer your question? If yes we should close it.
@andreasWallner it forms as a workaround, but since @Dolu1990 mentioned that there could be a baked API for this, I'm thinking of either keeping this open or having a tracking issue for that feature (request). What do you think?
Currently, the smootest api is :
class DemoBlackbox extends BlackBox {
val io = new Bundle{
val a = in Bool()
val b = out Bool()
}
ClockDomainTag(this.clockDomain)(
io.a,
io.b
)
}
You can also do :
class DemoBlackbox extends BlackBox {
val io = new Bundle{
val a = in Bool()
val b = out Bool()
}
ClockDomainTag(this.clockDomain)(io)
}
I also just pushed feature :
class DemoBlackbox extends BlackBox {
val io = new Bundle{
val a = in Bool()
val b = out Bool()
}
setIoCd() //This will add the tag to all the previsouly defined io
}