Search code examples
scalachisel

Not sign-extended in AND operation in firrtl


I tried a simple test like below in chisel3.

import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
import chisel3._

class TestTesterUnit(c: Test) extends PeekPokeTester(c) {
  val value = 31
  poke(c.io.a, value)
  poke(c.io.b, 1)
  step(1)
  expect(c.io.out, value)
}

class TestTester extends ChiselFlatSpec {
  for (backendName <- backends) {
    "Test" should s"should sign-extended AND operation (with $backendName)" in {
      Driver(() => new Test, backendName) {
        c => new TestTesterUnit(c)
      } should be (true)
    }
  }
}

class Test extends Module {
  val io = IO(new Bundle {
    val a = Input(SInt(32.W))
    val b = Input(SInt(1.W))
    val out = Output(SInt(32.W))
  })

  io.out := io.a & io.b
}

I've thought Test module calculates io.a AND io.b with sign-extended, and io.out receives 31 as a result. However, in the firrtl test, io.out receives 1, whereas io.out receives 31 in verilator test.

As another way, I add Wire(SInt(32.W)) as a bridge between io.b and AND operand like a following code, and this works well.

val node = Wire(SInt(32.W))
node := io.b
io.out := io.a & node 

My questions are "Does firrtl not support operations with sign-extended?", and "Do I have to put bridges like above when I want to use sign-extended operands?".

Following is Test module on firrtl.

circuit Test : 
  module Test : 
    input clock : Clock
    input reset : UInt<1>
    output io : {flip a : SInt<32>, flip b : SInt<1>, out : SInt<32>}

    node _T_11 = and(io.a, io.b) @[Multiple.scala 16:18]
    node _T_12 = asSInt(_T_11) @[Multiple.scala 16:18]
    io.out <= _T_12 @[Multiple.scala 16:10]

Solution

  • This looks like a bug in the firrt-interpreter. The treadle back-end seems to work correctly, so if possible I would suggest using that in the meantime. Treadle is the more modern scala based simulator.

    I have created Interpreter Issue 145 to get this fixed