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
The chisel code (provided below) passes the tests and gets compiled, however there occurs an error when trying to generate the verilog file.
Chisel Code:
import chisel3._
import chisel3.core.VecInit
import chisel3.util._
//A n-bit adder with carry in and carry out
class AdderNbit(val n: Int) extends Module {
val io = IO( new Bundle {
val A = Input(UInt(n.W))
val B = Input(UInt(n.W))
val Cin = Input(UInt(1.W))
val Sum = Output(UInt(n.W))
val Cout = Output(UInt(1.W))
})
val FAs = Vec(Seq.fill(n) {Module(new FullAdder()).io })
val carry = Wire(Vec(n+1, UInt(1.W)))
val sum = Wire(Vec(n, Bool()))
carry(0) := io.Cin
for(i <- 0 until n) {
FAs(i).a := io.A(i)
FAs(i).b := io.B(i)
FAs(i).cin := carry(i)
sum(i) := FAs(i).sum.toBool()
carry(i+1) := FAs(i).cout
}
io.Sum := sum.asUInt()
io.Cout := carry(n)
}
//Binary to thermometer code converter
class BinThermConv(n: Int) extends Module {
val io = IO(new Bundle {
val bin = Input(UInt(n.W))
val therm = Output(UInt())
})
val w = (math.pow(2,n).toInt)-1
val x = 0.U(w.W)
val z = Wire(UInt(w.W))
z := (x | ((1.U << io.bin)-1.U))
io.therm := z
}
//4-bit adder with carry in and carry out and coverts sum into thermometer code
class Adder4bit extends Module {
val io = IO(new Bundle {
val A = Input(UInt(4.W))
val B = Input(UInt(4.W))
val Cin = Input(UInt(1.W))
val SumTherm = Output(UInt())
val Cout = Output(UInt(1.W))
})
val Ad = Module(new AdderNbit(4))
Ad.io.A := io.A
Ad.io.B := io.B
Ad.io.Cin := io.Cin
val Btc = Module(new BinThermConv(Ad.n))
Btc.io.bin := Ad.io.Sum
io.SumTherm := Btc.io.therm
io.Cout := Ad.io.Cout
}
Test Harness:
import chisel3.iotesters.{PeekPokeTester, Driver, ChiselFlatSpec}
class Adder4bitTests(c: Adder4bit) extends PeekPokeTester(c) {
for (t <- 0 until 1024) {
val rnd0 = rnd.nextInt(16)
val rnd1 = rnd.nextInt(16)
val rnd2 = rnd.nextInt(2)
poke(c.io.A, rnd0)
poke(c.io.B, rnd1)
poke(c.io.Cin, rnd2)
step(1)
val rsum = (rnd0 & 0xF) + (rnd1 & 0xF) + (rnd2 & 0x1)
val rsumTherm = 1 << (rsum & 0xF)
expect(c.io.SumTherm, ((rsumTherm-1) & 0x7FFF))
expect(c.io.Cout, rsum >> 4)
}
}
class Adder4bitTester extends ChiselFlatSpec {
behavior of "Adder4bit"
backends foreach {backend =>
it should s"correctly add randomly generated numbers $backend" in {
Driver(() => new Adder4bit,backend)((c) => new Adder4bitTests(c)) should be (true)
}
}
}
Error encountered:
> test:run-main examples.Launcher Adder4bit --backend-name=verilator
[info] Running examples.Launcher Adder4bit --backend-name=verilator
Starting tutorial Adder4bit
[info] [0.001] Elaborating design...
[info] [0.086] Done elaborating.
Total FIRRTL Compile Time: 345.5 ms
java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:347)
at chisel3.internal.firrtl.UnknownWidth.get(IR.scala:183)
at chisel3.core.Data.getWidth(Data.scala:371)
at chisel3.iotesters.VerilatorCppHarnessGenerator$$anonfun$codeGen$2.apply(VerilatorBackend.scala:92)
at chisel3.iotesters.VerilatorCppHarnessGenerator$$anonfun$codeGen$2.apply(VerilatorBackend.scala:90)
at scala.collection.immutable.List.foreach(List.scala:392)
at chisel3.iotesters.VerilatorCppHarnessGenerator$.codeGen(VerilatorBackend.scala:90)
at chisel3.iotesters.setupVerilatorBackend$.apply(VerilatorBackend.scala:247)
at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply$mcZ$sp(Driver.scala:53)
at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:38)
at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:38)
at logger.Logger$$anonfun$makeScope$1.apply(Logger.scala:129)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
at logger.Logger$.makeScope(Logger.scala:127)
at chisel3.iotesters.Driver$$anonfun$execute$1.apply$mcZ$sp(Driver.scala:38)
at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:38)
at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:38)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
at chisel3.iotesters.Driver$.execute(Driver.scala:37)
at examples.Launcher$$anonfun$22.apply(Launcher.scala:125)
at examples.Launcher$$anonfun$22.apply(Launcher.scala:124)
at utils.TutorialRunner$$anonfun$apply$2.apply(TutorialRunner.scala:43)
at utils.TutorialRunner$$anonfun$apply$2.apply(TutorialRunner.scala:36)
at scala.collection.immutable.List.foreach(List.scala:392)
at utils.TutorialRunner$.apply(TutorialRunner.scala:36)
at examples.Launcher$.main(Launcher.scala:131)
at examples.Launcher.main(Launcher.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sbt.Run.invokeMain(Run.scala:67)
at sbt.Run.run0(Run.scala:61)
at sbt.Run.sbt$Run$$execute$1(Run.scala:51)
at sbt.Run$$anonfun$run$1.apply$mcV$sp(Run.scala:55)
at sbt.Run$$anonfun$run$1.apply(Run.scala:55)
at sbt.Run$$anonfun$run$1.apply(Run.scala:55)
at sbt.Logger$$anon$4.apply(Logger.scala:84)
at sbt.TrapExit$App.run(TrapExit.scala:248)
at java.lang.Thread.run(Thread.java:748)
================================================================================
Errors: 1: in the following tutorials
Tutorial Adder4bit: exception None.get
================================================================================
Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-1"
java.lang.RuntimeException: Nonzero exit code: 1
at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last test:runMain for the full output.
[error] (test:runMain) Nonzero exit code: 1
[error] Total time: 1 s, completed Jul 15, 2018 10:39:45 AM
Here, we are trying to calculate the sum of two 4-bit numbers, and converting it to thermometer code.
We have been able to isolate the problem, it appears that the error is due to bit-width inference. It seems that SumTherm does not get bit width in a proper way because Btc.io.therm doesn't have it explicitly defined either. If, however, the port is defined in the following way: val SumTherm = Output(UInt(15.W)) everything works great.
But this problem should not have occurred because val w = ((math.pow(2,n).toInt)-1) is there to calculate the appropriate width for thermometer code, and the variables z, x should be of appropriate sizes. So Btc.io.therm should get a UInt value of width w, and so should io.SumTherm.
Any ideas for this strange behavior?
I received the following feedback on stackoverflow: This appears to be a bug in the chisel-testers. Verilog actually is being generated but it appears that the chisel-testers Verilator backend is trying to get the width of the Chisel objects which do not have defined width as you noted. Rather, it should get the widths from the resulting FIRRTL or at least be able to handle ports that don't have defined width.
Link -> https://stackoverflow.com/questions/51537418/bit-width-inference-issue
The text was updated successfully, but these errors were encountered:
The chisel code (provided below) passes the tests and gets compiled, however there occurs an error when trying to generate the verilog file.
Chisel Code:
Test Harness:
Error encountered:
Here, we are trying to calculate the sum of two 4-bit numbers, and converting it to thermometer code.
We have been able to isolate the problem, it appears that the error is due to bit-width inference. It seems that
SumTherm
does not get bit width in a proper way becauseBtc.io.therm
doesn't have it explicitly defined either. If, however, the port is defined in the following way:val SumTherm = Output(UInt(15.W))
everything works great.But this problem should not have occurred because
val w = ((math.pow(2,n).toInt)-1)
is there to calculate the appropriate width for thermometer code, and the variablesz
,x
should be of appropriate sizes. SoBtc.io.therm
should get aUInt
value of widthw
, and so shouldio.SumTherm
.Any ideas for this strange behavior?
I received the following feedback on stackoverflow: This appears to be a bug in the chisel-testers. Verilog actually is being generated but it appears that the chisel-testers Verilator backend is trying to get the width of the Chisel objects which do not have defined width as you noted. Rather, it should get the widths from the resulting FIRRTL or at least be able to handle ports that don't have defined width.
Link -> https://stackoverflow.com/questions/51537418/bit-width-inference-issue
The text was updated successfully, but these errors were encountered: