firrtl-interpreter icon indicating copy to clipboard operation
firrtl-interpreter copied to clipboard

Wire assignment to output of Reg does not always work

Open nullromo opened this issue 7 years ago • 7 comments

From @nullromo on November 4, 2018 6:8

Type of issue: bug report

Other information This could be a bug with the firrtl interpreter.

If the current behavior is a bug, please provide the steps to reproduce the problem: Steps to reproduce:

This module is a pared down version of a work in progress, so the actual behavior of the module is irrelevant. The point is that byteOut is assigned to the output of the byteIn register, but the waveform output shows byteOut taking on old values.

import chisel3._
import chisel3.util._

/*
 * This module has a problem. It is very sad. When it is run, byteOut is set to always
 * byteIn. The output waveform shows times when byteOut is equal to old values of
 * byteIn. e.g. byteIn=3, byteOut=2 after 13 steps; or byteIn=7, byteOut=5 after
 * 37 steps when running the associated test.
 */
class SadModule extends Module {
  val io = IO(new Bundle {
    val in = Flipped(Decoupled(Input(UInt(8.W))))
    val out = Decoupled(Output(UInt(8.W)))
  })
  val sAccept :: sSend :: Nil = Enum(2)
  val state = RegInit(sAccept)
  val byteIn = RegInit(0.U(8.W))
  val byteOut = Wire(UInt(8.W))
  byteOut := byteIn

  when(state === sAccept) {
    byteIn := io.in.deq()
    io.out.noenq()
    when(io.in.fire()) {
      state := sSend
    }
  }.otherwise {
    io.in.nodeq()
    when(byteIn === 0.U) {
      io.out.noenq()
      state := sAccept
    }.otherwise {
      io.out.enq(byteOut)
    }
    when(io.out.fire()) {
        state := sAccept
        byteIn := io.in.bits
    }
  }
}

This is the associated test:

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

class SadModuleTester(c: SadModule) extends PeekPokeTester(c) {
  val input = List(2, 3, 0, 0, 0, 0, 0, 5, 7, 0, 8, 9, 0, 0, 0, 1).map {
    _.toByte
  }
  var output = List[BigInt]()
  poke(c.io.out.ready, true)
  poke(c.io.in.valid, true)
  var i = 0
  while (i < input.length) {
    poke(c.io.in.bits, input(i))
    step(1)
    if (peek(c.io.out.valid) != BigInt(0)) {
      output = output :+ peek(c.io.out.bits)
      i = i + 1
    } else if (peek(c.io.in.ready) != BigInt(0)) {
      output = output :+ peek(c.io.out.bits)
      i = i + 1
    }
  }
  println(input.toString())
  println(output.toString())
}

class CompressionTester extends ChiselFlatSpec {
  "SadModule" should "fail" in {
    Driver.execute(Array("-fiwv", "--backend-name", "firrtl", "--target-dir", "test_run_dir/sad", "--top-name", "sad"), () => new SadModule) {
      c => new SadModuleTester(c)
    } should be(true)
  }
}

Here is a picture of the waveform output: capture

What is the current behavior? Wires assigned to certain values do not always take on that value.

What is the expected behavior? Wires should always asynchronously have the value that they are assigned.

Please tell us about your environment: - OS: Windows 10

Copied from original issue: freechipsproject/chisel3#925

nullromo avatar Nov 05 '18 05:11 nullromo

From @edwardcwang on November 4, 2018 6:11

Does it work with either verilator or treadle?

nullromo avatar Nov 05 '18 05:11 nullromo

I do not have verilator installed, and treadle does not produce a vcd, so I cannot immediately answer that.

nullromo avatar Nov 05 '18 05:11 nullromo

From @edwardcwang on November 4, 2018 7:42

If you use val args = Array("--backend-name", "treadle", "--tr-write-vcd") you can get treadle to produce VCDs.

nullromo avatar Nov 05 '18 05:11 nullromo

Ah yes. Adding dontTouch(byteOut) and using treadle with --tr-write-vcd produced a waveform that looks correct (byteOut always has the same value as byteIn). Does that imply that this is in fact a potential firrtl interpreter bug?

nullromo avatar Nov 05 '18 05:11 nullromo

From @edwardcwang on November 4, 2018 20:55

It's possible; I've run into bugs where firrtl-interpreter was doing weird things like this in VCD output. IIRC the plan was for treadle to replace firrtl-interpreter though, so...

nullromo avatar Nov 05 '18 05:11 nullromo

Should I migrate this to the firrtl repo then?

nullromo avatar Nov 05 '18 05:11 nullromo

From @chick on November 5, 2018 3:11

Migrate to the firrtl-interpreter repo.

nullromo avatar Nov 05 '18 05:11 nullromo