You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.
I've then created three tests with fork. I've found that test2 and test3 fail. The forked pokes on input b are not showing up correctly.
classMulTestextendsAnyFlatSpecwithChiselScalatestTester {
behavior.of("Mul")
valtest1= it should "Mul without Input B delayed inside the module" in {
test(newMul(shouldDelayInputB =true))
.withAnnotations(Seq(WriteVcdAnnotation)) { dut =>
fork {
dut.io.in.a.poke(3.U)
dut.io.in.b.poke(4.U)
dut.clock.step(1)
dut.io.in.a.poke(7.U)
dut.io.in.b.poke(8.U)
dut.clock.step(1)
}
dut.clock.step(dut.delay)
dut.io.out.expect(3*4)
dut.clock.step(1)
dut.io.out.expect(7*8)
}
}
// This fails both expectsvaltest2= it should "Mul without Input B delayed inside the testbench" in {
test(newMul(shouldDelayInputB =false))
.withAnnotations(Seq(WriteVcdAnnotation)) { dut =>valf= fork {
dut.io.in.a.poke(3.U)
fork {
dut.clock.step(dut.delay -1)
dut.io.in.b.poke(4.U)
}
dut.clock.step(1)
dut.io.in.a.poke(7.U)
fork {
dut.clock.step(dut.delay -1)
dut.io.in.b.poke(8.U)
}
dut.clock.step(1)
}
// f.fork.withRegion(Monitor) {
dut.clock.step(dut.delay)
dut.io.out.expect(3*4)
dut.clock.step(1)
dut.io.out.expect(7*8)
// }
}
}
// This fails the second expectvaltest3=
it should "Mul without Input B delayed inside the testbench and separate forks" in {
test(newMul(shouldDelayInputB =false))
.withAnnotations(Seq(WriteVcdAnnotation)) { dut =>valf1= fork {
dut.io.in.a.poke(3.U)
dut.clock.step(1)
dut.io.in.a.poke(7.U)
dut.clock.step(1)
}
valf2= fork {
dut.clock.step(dut.delay -1)
dut.io.in.b.poke(4.U)
dut.clock.step(1)
dut.io.in.b.poke(8.U)
}
// f2.fork.withRegion(Monitor) {
dut.clock.step(dut.delay)
dut.io.out.expect(3*4)
dut.clock.step(1)
dut.io.out.expect(7*8)
// }
}
}
}
In both cases, the solution is to add the commented fork.withRegion(Monitor) calls. However, I don't understand why that is necessary here.
From RegionsTests.scala, I had the impression that fork.withRegion(Monitor) resolved combinatorial read-after-write dependencies for the threads. Here, even with the pipeline balancing of b done within the testbench, the register io.out := RegNext(a_d * b_d) still prevents such dependencies. I must have misunderstood what fork.withRegion(Monitor) is doing precisely. Are there any pointers you could give here?
The text was updated successfully, but these errors were encountered:
Update: I forgot the joinAndStep(dut.clock). The fork.withRegion was not fixing anything; it just ensured the testbench finished without executing the expect calls.
I have also found the actual issue. I was simply not adding the extra dut.clock.step(1) within the forked pokes for input b. It seems that forks have some default timescope behavior? Without stepping the clock, the poke is reverted?
The fix for test3 is here. Trying something similar for test2:
valtest2= it should "Mul without Input B delayed inside the testbench" in {
test(newMul(shouldDelayInputB =false))
.withAnnotations(Seq(WriteVcdAnnotation)) { dut =>valf= fork {
dut.io.in.a.poke(3.U)
fork {
dut.clock.step(dut.delay -1)
dut.io.in.b.poke(4.U)
dut.clock.step(1)
}
dut.clock.step(1)
dut.io.in.a.poke(7.U)
fork {
dut.clock.step(dut.delay -1)
dut.io.in.b.poke(8.U)
dut.clock.step(1)
}
dut.clock.step(1)
}
dut.clock.step(dut.delay)
dut.io.out.expect(3*4)
dut.clock.step(1)
dut.io.out.expect(7*8)
}
}
results in chiseltest.ThreadOrderDependentException: Mix of ending timescopes and old timescopes. Is there any solution for that?
Hi,
I've been experimenting with the fork/join capabilities to test pipelined modules. I am somewhat confused about the synchronization between threads.
To illustrate, I created a simple pipelined multiplier:
The pipeline balancing of input
b
(delay-1
input registers) can also be disabled to be done externally.I've then created three tests with
fork
. I've found thattest2
andtest3
fail. The forked pokes on inputb
are not showing up correctly.In both cases, the solution is to add the commented
fork.withRegion(Monitor)
calls. However, I don't understand why that is necessary here.From RegionsTests.scala, I had the impression that
fork.withRegion(Monitor)
resolved combinatorial read-after-write dependencies for the threads. Here, even with the pipeline balancing ofb
done within the testbench, the registerio.out := RegNext(a_d * b_d)
still prevents such dependencies. I must have misunderstood whatfork.withRegion(Monitor)
is doing precisely. Are there any pointers you could give here?The text was updated successfully, but these errors were encountered: