Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to poke value to dynamically generated MixedVec Bundle #1031

Closed
SihaoLiu opened this issue Mar 11, 2019 · 6 comments · Fixed by #1045
Closed

Unable to poke value to dynamically generated MixedVec Bundle #1031

SihaoLiu opened this issue Mar 11, 2019 · 6 comments · Fixed by #1045

Comments

@SihaoLiu
Copy link
Contributor

Hi, I'm using MixedVec to dynamically generate Bundle based on String as shown below (real case is a little bit more complicated but the error is the same).

You can simply run BugMain below to reproduce such error.

Reproduce Step:
1. create a array of String in "BugMain", io of module "bug_hw" is instantiate based on that array.
2. method "get_io" take string array and generate different io types in MixedVec.
3. Verilog file can be generated successfully.
4. In "BugUnitTester", io is actually "java.util.NoSuchElementException" (supposed to be MixedVec[Data])

Type of issue: bug report

Impact: unknown

HOW TO REPRODUCE:
Code:

package bug
import chisel3._
import chisel3.iotesters.PeekPokeTester
import chisel3.util._
object io {
  def get_io (p:Array[String]) ={
    MixedVec(p map(s=>{
      s match {
        case "INPUT" => Input(Bool())
        case "OUTPUT" => Output(Bool())
        case "Data" => DecoupledIO(UInt(15.W))
      }
    }))
  }
}
import io._
class bug_hw(p:Array[String]) extends Module{
  val io = IO(get_io(p))
  val input_port = io(0).asInstanceOf[Bool]
  val data_port = io(1).asInstanceOf[DecoupledIO[UInt]]
  data_port.bits := 1.U
  data_port.valid := input_port
}
class BugUnitTester(b:bug_hw) extends PeekPokeTester(b) {
  private val bug = b
  val io = bug.io
  val input_p = io(0).asInstanceOf[Bool]
  poke(input_p,0)
  step(2)
}
object BugMain extends App {
  val properties = Array("INPUT","Data")
  iotesters.Driver.execute(args, () =>
    new bug_hw(properties)
  ){
    c => new BugUnitTester(c)
  }
}

What is the current behavior?
Error Stack

java.util.NoSuchElementException: head of empty list
	at scala.collection.immutable.Nil$.head(List.scala:431)
	at scala.collection.immutable.Nil$.head(List.scala:428)
	at scala.collection.mutable.Stack.top(Stack.scala:132)
	at chisel3.internal.naming.NamingStack.pop_return_context(Namer.scala:133)
	at chisel3.util.MixedVec.apply(MixedVec.scala:81)
	at bug.BugUnitTester.<init>(bug.scala:32)
	at bug.BugMain$$anonfun$2.apply(bug.scala:43)
	at bug.BugMain$$anonfun$2.apply(bug.scala:43)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply$mcZ$sp(Driver.scala:67)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply$mcZ$sp(Driver.scala:65)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at logger.Logger$$anonfun$makeScope$1.apply(Logger.scala:138)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at logger.Logger$.makeScope(Logger.scala:136)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply$mcZ$sp(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$.execute(Driver.scala:38)
	at chisel3.iotesters.Driver$.execute(Driver.scala:100)
	at bug.BugMain$.delayedEndpoint$bug$BugMain$1(bug.scala:42)
	at bug.BugMain$delayedInit$body.apply(bug.scala:36)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
	at scala.App$class.main(App.scala:76)
	at bug.BugMain$.main(bug.scala:36)
	at bug.BugMain.main(bug.scala)
Exception in thread "main" java.util.NoSuchElementException: head of empty list
	at scala.collection.immutable.Nil$.head(List.scala:431)
	at scala.collection.immutable.Nil$.head(List.scala:428)
	at scala.collection.mutable.Stack.top(Stack.scala:132)
	at chisel3.internal.naming.NamingStack.pop_return_context(Namer.scala:133)
	at chisel3.util.MixedVec.apply(MixedVec.scala:81)
	at bug.BugUnitTester.<init>(bug.scala:32)
	at bug.BugMain$$anonfun$2.apply(bug.scala:43)
	at bug.BugMain$$anonfun$2.apply(bug.scala:43)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply$mcZ$sp(Driver.scala:67)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply$mcZ$sp(Driver.scala:65)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at logger.Logger$$anonfun$makeScope$1.apply(Logger.scala:138)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at logger.Logger$.makeScope(Logger.scala:136)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply$mcZ$sp(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$.execute(Driver.scala:38)
	at chisel3.iotesters.Driver$.execute(Driver.scala:100)
	at bug.BugMain$.delayedEndpoint$bug$BugMain$1(bug.scala:42)
	at bug.BugMain$delayedInit$body.apply(bug.scala:36)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
	at scala.App$class.main(App.scala:76)
	at bug.BugMain$.main(bug.scala:36)
	at bug.BugMain.main(bug.scala)

What is the expected behavior?
I should be able to refer io of module in BugUnitTester to poke value

Please tell us about your environment:
sbt version = 1.1.2
scala version = 2.11.12
chisel version = 3.1.6
chisel iotester version = 1.2.8
firrtl interpreter version = 1.1.6
OS: Ubuntu 16.04 LTS

@SihaoLiu
Copy link
Contributor Author

For you guys convenience, such error can be reproduced by code simplified as below

package bug
import chisel3._
import chisel3.iotesters.PeekPokeTester
import chisel3.util._

class bug_hw(p1:Int,p2:Int) extends Module{
  val io = IO(new Bundle{
    val vec_in = Input(MixedVec((p1 to p2) map { i => UInt(i.W) }))
    val vec_out = Output(UInt(5.W))
  })
  io.vec_out := io.vec_in(0)
}

// --------------- Tester ------------------

class BugUnitTester(b:bug_hw) extends PeekPokeTester(b) {
  private val bug = b
  val io = bug.io
  poke(io.vec_in(0),5)
  step(2)
}
object BugMain extends App {
  iotesters.Driver.execute(args, () =>
    new bug_hw(5,10)
  ){
    c => new BugUnitTester(c)
  }
}

The way to use MixedVec is actually follow the way introduced in Chisel Documatation here :
https://github.com/freechipsproject/chisel3/wiki/Bundles-and-Vecs
Quoted as:

We can also programmatically create the types in a MixedVec:

class MyModule(x: Int, y: Int) extends Module {
  val io = IO(new Bundle {
    val vec = Input(MixedVec((x to y) map { i => UInt(i.W) }))
    // ...
  })
  // ...rest of the module goes here...
}

Exception Stack is the same

java.util.NoSuchElementException: head of empty list
	at scala.collection.immutable.Nil$.head(List.scala:431)
	at scala.collection.immutable.Nil$.head(List.scala:428)
	at scala.collection.mutable.Stack.top(Stack.scala:132)
	at chisel3.internal.naming.NamingStack.pop_return_context(Namer.scala:133)
	at chisel3.util.MixedVec.apply(MixedVec.scala:81)
	at bug.BugUnitTester.<init>(bug.scala:19)
	at bug.BugMain$$anonfun$3.apply(bug.scala:26)
	at bug.BugMain$$anonfun$3.apply(bug.scala:26)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply$mcZ$sp(Driver.scala:67)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply$mcZ$sp(Driver.scala:65)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at logger.Logger$$anonfun$makeScope$1.apply(Logger.scala:138)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at logger.Logger$.makeScope(Logger.scala:136)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply$mcZ$sp(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$.execute(Driver.scala:38)
	at chisel3.iotesters.Driver$.execute(Driver.scala:100)
	at bug.BugMain$.delayedEndpoint$bug$BugMain$1(bug.scala:25)
	at bug.BugMain$delayedInit$body.apply(bug.scala:22)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
	at scala.App$class.main(App.scala:76)
	at bug.BugMain$.main(bug.scala:22)
	at bug.BugMain.main(bug.scala)
Exception in thread "main" java.util.NoSuchElementException: head of empty list
	at scala.collection.immutable.Nil$.head(List.scala:431)
	at scala.collection.immutable.Nil$.head(List.scala:428)
	at scala.collection.mutable.Stack.top(Stack.scala:132)
	at chisel3.internal.naming.NamingStack.pop_return_context(Namer.scala:133)
	at chisel3.util.MixedVec.apply(MixedVec.scala:81)
	at bug.BugUnitTester.<init>(bug.scala:19)
	at bug.BugMain$$anonfun$3.apply(bug.scala:26)
	at bug.BugMain$$anonfun$3.apply(bug.scala:26)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply$mcZ$sp(Driver.scala:67)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1$$anonfun$apply$mcZ$sp$2.apply(Driver.scala:66)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply$mcZ$sp(Driver.scala:65)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1$$anonfun$apply$mcZ$sp$1.apply(Driver.scala:39)
	at logger.Logger$$anonfun$makeScope$1.apply(Logger.scala:138)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at logger.Logger$.makeScope(Logger.scala:136)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply$mcZ$sp(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at chisel3.iotesters.Driver$$anonfun$execute$1.apply(Driver.scala:39)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
	at chisel3.iotesters.Driver$.execute(Driver.scala:38)
	at chisel3.iotesters.Driver$.execute(Driver.scala:100)
	at bug.BugMain$.delayedEndpoint$bug$BugMain$1(bug.scala:25)
	at bug.BugMain$delayedInit$body.apply(bug.scala:22)
	at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
	at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.App$$anonfun$main$1.apply(App.scala:76)
	at scala.collection.immutable.List.foreach(List.scala:392)
	at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
	at scala.App$class.main(App.scala:76)
	at bug.BugMain$.main(bug.scala:22)
	at bug.BugMain.main(bug.scala)

@edwardcwang
Copy link
Contributor

May be related to #1027

@Martoni
Copy link
Contributor

Martoni commented Oct 14, 2019

I have the same error with Chisel 3.1.8.

I declared a MixedVec in my interface:

class WbInterconOneMaster(val awbm: WbMaster,
                          val awbs: Seq[WbSlave]) extends Module {
    val io = IO(new Bundle{
      val wbm = Flipped(new WbMaster(awbm.dwidth, awbm.awidth))
      val wbs = MixedVec(awbs.map{i => Flipped(new WbSlave(i.dwidth, i.awidth, i.iname))})
    })

And tryied to poke value in my testbench :

  for(wbs <- dut.io.wbs) {
    poke(wbs.ack_o, 0)
  }

But got this error at execution time (verilator backend):

[info]   java.util.NoSuchElementException: head of empty list
[info]   at scala.collection.immutable.Nil$.head(List.scala:420)
[info]   at scala.collection.immutable.Nil$.head(List.scala:417)
[info]   at scala.collection.mutable.Stack.top(Stack.scala:132)
[info]   at chisel3.internal.naming.NamingStack.pop_return_context(Namer.scala:133)
[info]   at chisel3.util.MixedVec.length(MixedVec.scala:81)
[info]   at scala.collection.IndexedSeqLike$class.iterator(IndexedSeqLike.scala:90)
[info]   at chisel3.util.MixedVec.iterator(MixedVec.scala:81)
[info]   at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
[info]   at chisel3.util.MixedVec.foreach(MixedVec.scala:81)
[info]   at wbplumbing.TestWbInterconDualSlave.<init>(testwbplumbing.scala:61)

@edwardcwang
Copy link
Contributor

Does it work with master?

@Martoni
Copy link
Contributor

Martoni commented Oct 14, 2019

I don't tested with master. If I want to test master, do I just have to change Chisel version with snapshot in build.sbt?

@chick
Copy link
Contributor

chick commented Oct 14, 2019

@edwardcwang Did you do some PR that addresses this. I have an example that fails as described here but works properly when I use current chisel master. Would be nice to reference the fix, whatever it is then close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants