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

add initialize argument to StreamFifo #1680

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

facebreeze
Copy link
Contributor

Closes #

Context, Motivation & Description

Register constructed StreamFifo can be fully initialized when necessary.

Impact on code generation

Checklist

  • Unit tests were added
  • API changes are or will be documented:

@facebreeze
Copy link
Contributor Author

Hi,
The test passed on scala 2.13.12, but failed on scala 2.11.12 with following error.


A null pointer access has been detected in the JVM.
This could happen when in your SpinalHDL description, you access an signal which is only defined further.
For instance :
  val result = Bool()
  result := a ^ b  //a and b can't be accessed there because they are only defined one line below (Software rule of execution order)
  val a,b = Bool()
          
[info] - port2 *** FAILED ***
[info]   java.lang.NullPointerException: Cannot throw exception because the return value of "spinal.lib.StreamFifo$$anonfun$apply$24.apply()" is null
[info]   at spinal.lib.StreamFifo$$anonfun$apply$24.apply(Stream.scala:1198)
[info]   at spinal.lib.StreamFifo$$anonfun$114$$anon$65$$anonfun$115.apply(Stream.scala:1264)
[info]   at spinal.lib.StreamFifo$$anonfun$114$$anon$65$$anonfun$115.apply(Stream.scala:1264)
[info]   at spinal.lib.Stream$$anon$29.<init>(Stream.scala:396)
[info]   at spinal.lib.Stream.m2sPipe(Stream.scala:392)
[info]   at spinal.lib.StreamFifo$$anonfun$114$$anon$65.<init>(Stream.scala:1264)
[info]   at spinal.lib.StreamFifo$$anonfun$114.apply(Stream.scala:1262)
[info]   at spinal.lib.StreamFifo$$anonfun$114.apply(Stream.scala:1262)
[info]   at spinal.core.internals.BooleanPimped.generate(Misc.scala:[285](https://github.com/SpinalHDL/SpinalHDL/actions/runs/13835797025/job/38710654563?pr=1680#step:5:286))
[info]   at spinal.lib.StreamFifo.<init>(Stream.scala:1262)

I have no idea how to fix this on scala 2.11.12. need help!!!

@Dolu1990
Copy link
Member

Ahh i already have seen that kinda of scala weird behaviour.

It is related to initPayload : => T = null.asInstanceOf[T]
Sometimes it doesn't likes it :/ now sure why.

@facebreeze
Copy link
Contributor Author

How about initPayload : => Option[T] = None ?

@Dolu1990
Copy link
Member

Look good

@facebreeze
Copy link
Contributor Author

Spinal error occurs for following StreamFifo instance:

case class FifoDemo() extends Component {
  val io = new Bundle {
    val input = slave Stream (Bool())
    val output = master Stream (Bool())
  }
  val fifo = new StreamFifo(cloneOf(io.input.payload), 1, initPayload = Some(io.input.payload.getZero))
  fifo.io.push << io.input
  io.output << fifo.io.pop
}

Error message:

HIERARCHY VIOLATION : Bool(x) is used to drive the (toplevel/fifo/io_push_rData :  Bool) := Bool(x) statement, but isn't readable in the fifo component
    spinal.lib.Stream$$anon$29.<init>(Stream.scala:426)
    spinal.lib.Stream.m2sPipe(Stream.scala:422)
    spinal.lib.StreamFifo$$anonfun$114$$anon$66.<init>(Stream.scala:1338)
    spinal.lib.StreamFifo$$anonfun$114.apply(Stream.scala:1335)
    spinal.lib.StreamFifo$$anonfun$114.apply(Stream.scala:1335)
    spinal.lib.StreamFifo.<init>(Stream.scala:1335)

Looks the problem happens on m2sPipe. Is it possible to change initPayload type of the m2sPipe ?

@Dolu1990
Copy link
Member

is it possible to change initPayload type of the m2sPipe ?

into what ?

@facebreeze
Copy link
Contributor Author

If change the initPayload : => T = null.asInstanceOf[T] of m2sPipe into initPayload : Option[T] = None, would it have an negative impact on those calling m2sPipe ?

@facebreeze
Copy link
Contributor Author

Hi,
To avoid x propgating during simulation, it's necessary to initialize a pipeline which holds control information. For following code:

case class FrameCtrl() extends Bundle {
  val frameStart = Bool()
  val frameEnd = Bool()
}

case class StreamM2SPipe[T<:Data] (dataType: HardType[T], initPayload: Option[T] = None) extends Component {
  val io = new Bundle {
    val in = slave(Stream(dataType))
    val out = master(Stream(dataType))
  }
  initPayload match {
    case Some(initValue) => io.out << io.in.m2sPipe(holdPayload = true, initPayload = initValue.asInstanceOf[T])
    case None => io.out << io.in.m2sPipe(holdPayload = true)
  }
}

object StreamM2SPipeInst extends App {
  Config.spinal.generateVerilog(StreamM2SPipe(cloneOf(FrameCtrl()), Some(FrameCtrl().getZero)))
  //Config.spinal.generateVerilog(StreamM2SPipe(Bits(32 bits)))
}

Spinal errors:

`
Hardware assignement done outside any Component

Design's errors are listed above.
SpinalHDL compiler exit stack :

at spinal.core.SpinalExit$.apply(Misc.scala:459)
at spinal.core.SpinalError$.apply(Misc.scala:514)
at spinal.core.BaseType.assignFromImpl(BaseType.scala:233)
at spinal.core.Assignable.compositAssignFrom(Trait.scala:285)
at spinal.core.Assignable.compositAssignFrom$(Trait.scala:281)
at spinal.core.BaseType.compositAssignFrom(BaseType.scala:55)
at spinal.core.Data.assignFrom(Data.scala:417)
at spinal.core.Data.assignFrom$(Data.scala:417)
at spinal.core.BaseType.assignFrom(BaseType.scala:55)
at spinal.core.internals.BoolLiteral$.apply(Expression.scala:2624)
at spinal.core.BoolFactory.Bool(Bool.scala:36)
at spinal.core.BoolFactory.Bool$(Bool.scala:36)
at spinal.core.package$.Bool(core.scala:35)
at spinal.core.package$.False(core.scala:270)
at spinal.core.Bool.getZero(Bool.scala:301)
at spinal.core.Bool.getZero(Bool.scala:50)
at spinal.core.MultiData.$anonfun$getZero$1(MultiData.scala:221)
at spinal.core.MultiData.$anonfun$getZero$1$adapted(MultiData.scala:220)
at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:576)
at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:574)
at scala.collection.AbstractIterable.foreach(Iterable.scala:933)
at spinal.core.MultiData.getZero(MultiData.scala:220)
at projectname.StreamM2SPipeInst$.$anonfun$new$3(StreamM2SPipe.scala:22)
at spinal.core.internals.PhaseCreateComponent.$anonfun$impl$319(Phase.scala:2883)
at spinal.core.fiber.Engine$.$anonfun$create$1(AsyncCtrl.scala:173)
at spinal.core.fiber.AsyncThread.$anonfun$jvmThread$1(AsyncThread.scala:60)
at spinal.core.fiber.EngineContext.$anonfun$newJvmThread$1(AsyncCtrl.scala:39)
at spinal.sim.JvmThread.run(SimManager.scala:51)

`

@Dolu1990
Copy link
Member

Dolu1990 commented Apr 8, 2025

Ahhh would realy need to have a lambda function in the mix :/

Because the Some(FrameCtrl().getZero) does try to generate hardware directly. (that would be delayed to withing the component via a lambda function)

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 this pull request may close these issues.

2 participants