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

Can't infer width of Payload #1404

Closed
NikLeberg opened this issue Apr 29, 2024 · 7 comments
Closed

Can't infer width of Payload #1404

NikLeberg opened this issue Apr 29, 2024 · 7 comments

Comments

@NikLeberg
Copy link

Hi there!
Amazing project I have to say! Right when VHDL got on my nerves with its verbosity I found this. And the advanced generator functionality is what really drives it home.

Right, so I played around with Payload and am trying to build, of course, a RISC-V core with it. Thats when I stumbled over:

package curlyrv
import spinal.core._
import spinal.lib._
import spinal.lib.misc.pipeline._

case class Foo() extends Area {
  val decode = CtrlLink()
  val OPCODE = Payload(Bits(7 bits))
  val decoder = new decode.Area {
    switch(OPCODE) { // <-- confusion here
      is(B"0001111") {}
      default {}
    }
  }
  Builder(decode)
}

Where sbt gives me this:

[error] /workspaces/curly-engine/hw/spinal/curlyrv/Bug.scala:11:5: inferred type arguments [spinal.core.NamedType[spinal.core.Bits]] do not conform to method apply's type parameter bounds [T <: spinal.core.BaseType]
[error]     switch(OPCODE) { // <-- confusion here
[error]     ^
[error] /workspaces/curly-engine/hw/spinal/curlyrv/Bug.scala:11:12: type mismatch;
[error]  found   : spinal.core.NamedType[spinal.core.Bits]
[error]  required: T
[error]     switch(OPCODE) { // <-- confusion here
[error]            ^
[error] two errors found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 4 s, completed Apr 29, 2024, 5:08:32 AM

Please tell me if I'm doing something wrong. I expected OPCODE to be implicitly converted to Bits, but it is not? If i wrap it in B() it works fine.

Interestingly if I do OPCODE.asBits in a bit less mimized version of my design I get the metals environment to spit out interesting errors:

Exception in thread "main" spinal.core.SpinalExit: 

 Can't infer width on     curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

getWidth call result during elaboration differ from inferred width on
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Negative width on (toplevel/cpu/switch_Cpu_l164 :  Bits[? bits]) at     curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Can't infer width on     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:166)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Negative width on (toplevel/cpu/??? :  Bits[? bits]) at     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:166)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Can't infer width on     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:171)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Negative width on (toplevel/cpu/??? :  Bits[? bits]) at     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:171)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Can't infer width on     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:178)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Negative width on (toplevel/cpu/??? :  Bits[? bits]) at     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:178)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Can't infer width on     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:182)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)

Negative width on (toplevel/cpu/??? :  Bits[? bits]) at     curlyrv.CommonImmediateOps$$anon$2.$anonfun$new$1(Cpu.scala:182)
    curlyrv.CommonImmediateOps$$anon$2.<init>(Cpu.scala:164)
    curlyrv.CommonImmediateOps.build(Cpu.scala:161)
    curlyrv.Cpu.$anonfun$build$1(Cpu.scala:447)
    curlyrv.Cpu.$anonfun$build$1$adapted(Cpu.scala:447)
    curlyrv.Cpu.build(Cpu.scala:447)
    curlyrv.Cpu.<init>(Cpu.scala:475)
    curlyrv.Top.<init>(Top.scala:20)
    curlyrv.TopLevelVhdl$.$anonfun$new$1(Top.scala:25)
    spinal.sim.JvmThread.run(SimManager.scala:51)


********************************************************************************
********************************************************************************

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

        at spinal.core.SpinalExit$.apply(Misc.scala:455)
        at spinal.core.SpinalError$.apply(Misc.scala:515)
        at spinal.core.internals.PhaseInferWidth.impl(Phase.scala:1469)
        at spinal.core.internals.PhaseContext.doPhase(Phase.scala:183)
        at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$6(Phase.scala:2799)
        at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$6$adapted(Phase.scala:2797)
        at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
        at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
        at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
        at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$1(Phase.scala:2797)
        at spinal.core.ScopeProperty$.sandbox(ScopeProperty.scala:71)
        at spinal.core.internals.SpinalVhdlBoot$.singleShot(Phase.scala:2732)
        at spinal.core.internals.SpinalVhdlBoot$.apply(Phase.scala:2727)
        at spinal.core.Spinal$.apply(Spinal.scala:412)
        at spinal.core.SpinalConfig.generateVhdl(Spinal.scala:178)
        at curlyrv.TopLevelVhdl$.delayedEndpoint$curlyrv$TopLevelVhdl$1(Top.scala:25)
        at curlyrv.TopLevelVhdl$delayedInit$body.apply(Top.scala:24)
        at scala.Function0.apply$mcV$sp(Function0.scala:39)
        at scala.Function0.apply$mcV$sp$(Function0.scala:39)
        at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
        at scala.App.$anonfun$main$1$adapted(App.scala:80)
        at scala.collection.immutable.List.foreach(List.scala:431)
        at scala.App.main(App.scala:80)
        at scala.App.main$(App.scala:78)
        at curlyrv.TopLevelVhdl$.main(Top.scala:24)
        at curlyrv.TopLevelVhdl.main(Top.scala)

 *  The terminal process "/bin/bash '-c', '/"usr"/"lib"/"jvm"/"java-17-openjdk-amd64"/"bin"/"java" "-Duser.dir=/workspaces/curly-engine" -classpath "/workspaces/curly-engine/.metals/.tmp/classpath_C74931EEBB31CAE88CA52069ED9DDEA7.jar" curlyrv.TopLevelVhdl '" terminated with exit code: 1. 

As I'm no expert in Scala, what is happening here?

Thanks!

@NikLeberg
Copy link
Author

In a similar fashion.. why do none of these work?

case class BoolPayload() extends Area {
  val BOOL_PAYLOAD = Payload(Bool())
  val a = BOOL_PAYLOAD ? B"1" | B"0"
  val b = (BOOL_PAYLOAD === True) ? B"1" | B"0"
  val c = (B(BOOL_PAYLOAD) === B"1") ? B"1" | B"0"
  val d = (BOOL_PAYLOAD.asBits === B"1") ? B"1" | B"0"
  val e = Bits(1 bit)
  when(BOOL_PAYLOAD) {
    e := B"1"
  }.otherwise {
    e := B"0"
  }
}

@Dolu1990
Copy link
Member

Hi,

Sometime, scala has some limitation / restrictions with the range of implicits and need a bit of help XD

Here is one workaround :
switch(apply(OPCODE)) { //decode.Area.apply

Another one :
switch[Bits](OPCODE) {

Interestingly if I do OPCODE.asBits in a bit less mimized version of my design I get the metals environment to spit out interesting errors:

I tried, but can't reproduce that issue, it may be related to something else ?

Also i just tried :

    val decode = CtrlLink()
    val BOOL_PAYLOAD = Payload(Bool())
    val decoder = new decode.Area {
      val a = BOOL_PAYLOAD ? B"1" | B"0"
      val b = (BOOL_PAYLOAD === True) ? B"1" | B"0"
      val c = (B(BOOL_PAYLOAD) === B"1") ? B"1" | B"0"
      val d = (BOOL_PAYLOAD.asBits === B"1") ? B"1" | B"0"
      val e = Bits(1 bit)
      when(BOOL_PAYLOAD) {
        e := B"1"
      }.otherwise {
        e := B"0"
      }
    }
    Builder(decode)

They all work for me

In your example i think the issue is that you aren't in a "Node" context (new decode.Area)

So, the pipeline API has no "Node" to extract the payload from.
Payload(xxx) is realy for pipelining things.

Right when VHDL got on my nerves with its verbosity

<3 Pain pain pain <3

@NikLeberg
Copy link
Author

Hi there @Dolu1990
Thank you so much for the immediate response... although it helped a bit to use apply(...) I still encountered strange errors. It took some time to come up with a small example that behaves the same as the while design:

package curlyrv

import spinal.core._
import spinal.lib._
import spinal.lib.misc.pipeline._

import scala.collection.mutable.ArrayBuffer

case class Pipes() extends Area {
  val decode = CtrlLink()

  val IR = Payload(Bits(32 bits))
  val OPCODE = Payload(Bits(7 bits))
  val RD = Payload(UInt(5 bits))

  Builder(decode)
}

case class DecodeOps(pipes: Pipes) {
  import pipes._

  val decoder = new decode.Area {
    OPCODE := IR(6 downto 0)
    RD := U(IR(11 downto 7))
  }
}

case class Bug() extends Component {
  val pipes = Pipes()
  val decodeOps = DecodeOps(pipes)
}

object BugTop extends App {
  Config.spinal.generateVhdl(Bug()).printPruned()
}

The compile fails with error Static bits extraction (11 downto 7) is outside the range (-2 downto 0) of (toplevel/pipes_decode_down_IR : Bits[32 bits]) which I find very confusing. It says that the valid range is -2 downto 0 which is weird by itself, and then continues to say that it is 32 bits which is correct but should have a range of 31 downto 0 right?

What am I missing?

Full output of `sbt runMain curlyrv.BugTop`
[info] compiling 1 Scala source to /workspaces/curly-engine/target/scala-2.12/classes ...
[info] running (fork) curlyrv.BugTop 
[info] [Runtime] SpinalHDL v1.10.1    git head : 2527c7c6b0fb0f95e5e1a5722a0be732b364ce43
[info] [Runtime] JVM max memory : 1984.0MiB
[info] [Runtime] Current date : 2024.05.18 07:10:53
[info] [Progress] at 0.000 : Elaborate components
[info] [Progress] at 0.318 : Checks and transforms
[info] **********************************************************************************************
[info] [Warning] Elaboration failed (2 errors).
[info]           Spinal will restart with scala trace to help you to find the problem.
[info] **********************************************************************************************
[info] [Progress] at 0.446 : Elaborate components
[info] [Progress] at 0.457 : Checks and transforms
[error] Exception in thread "main" spinal.core.SpinalExit: 
[error]  Error detected in phase PhaseNormalizeNodeInputs
[error] ********************************************************************************
[error] ********************************************************************************
[error] Static bits extraction (11 downto 7) is outside the range (-2 downto 0) of (toplevel/pipes_decode_down_IR :  Bits[32 bits]) at
[error]     curlyrv.DecodeOps$$anon$1.<init>(Bug.scala:26)
[error]     curlyrv.DecodeOps.<init>(Bug.scala:24)
[error]     curlyrv.Bug.<init>(Bug.scala:32)
[error]     curlyrv.BugTop$.$anonfun$new$1(Bug.scala:36)
[error]     spinal.sim.JvmThread.run(SimManager.scala:51)
[error] ********************************************************************************
[error] ********************************************************************************
[error] Design's errors are listed above.
[error] SpinalHDL compiler exit stack : 
[error]         at spinal.core.SpinalExit$.apply(Misc.scala:455)
[error]         at spinal.core.SpinalError$.apply(Misc.scala:510)
[error]         at spinal.core.internals.PhaseContext.checkPendingErrors(Phase.scala:177)
[error]         at spinal.core.internals.PhaseContext.doPhase(Phase.scala:193)
[error]         at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$6(Phase.scala:2799)
[error]         at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$6$adapted(Phase.scala:2797)
[error]         at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
[error]         at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
[error]         at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
[error]         at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$1(Phase.scala:2797)
[error]         at spinal.core.ScopeProperty$.sandbox(ScopeProperty.scala:71)
[error]         at spinal.core.internals.SpinalVhdlBoot$.singleShot(Phase.scala:2732)
[error]         at spinal.core.internals.SpinalVhdlBoot$.apply(Phase.scala:2727)
[error]         at spinal.core.Spinal$.apply(Spinal.scala:412)
[error]         at spinal.core.SpinalConfig.generateVhdl(Spinal.scala:178)
[error]         at curlyrv.BugTop$.delayedEndpoint$curlyrv$BugTop$1(Bug.scala:36)
[error]         at curlyrv.BugTop$delayedInit$body.apply(Bug.scala:35)
[error]         at scala.Function0.apply$mcV$sp(Function0.scala:39)
[error]         at scala.Function0.apply$mcV$sp$(Function0.scala:39)
[error]         at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
[error]         at scala.App.$anonfun$main$1$adapted(App.scala:80)
[error]         at scala.collection.immutable.List.foreach(List.scala:431)
[error]         at scala.App.main(App.scala:80)
[error]         at scala.App.main$(App.scala:78)
[error]         at curlyrv.BugTop$.main(Bug.scala:35)
[error]         at curlyrv.BugTop.main(Bug.scala)
[error] Nonzero exit code returned from runner: 1
[error] (Compile / runMain) Nonzero exit code returned from runner: 1
[error] Total time: 2 s, completed May 18, 2024, 7:10:54 AM

@NikLeberg
Copy link
Author

BTW if I rewrite it as:

val ir = U(IR)
RD := ir(11 downto 7)

The error becomes:

  • Can't infer width on curlyrv.DecodeOps$$anon$1.<init>(Bug.scala:25) and
  • Negative width on (Bits -> UInt of -1 bits) at curlyrv.DecodeOps$$anon$1.<init>(Bug.scala:25).
Full output of `sbt runMain curlyrv.BugTop`
[info] compiling 1 Scala source to /workspaces/curly-engine/target/scala-2.12/classes ...
[info] running (fork) curlyrv.BugTop 
[info] [Runtime] SpinalHDL v1.10.1    git head : 2527c7c6b0fb0f95e5e1a5722a0be732b364ce43
[info] [Runtime] JVM max memory : 1984.0MiB
[info] [Runtime] Current date : 2024.05.18 07:23:41
[info] [Progress] at 0.000 : Elaborate components
[info] [Progress] at 0.324 : Checks and transforms
[info] **********************************************************************************************
[info] [Warning] Elaboration failed (2 errors).
[info]           Spinal will restart with scala trace to help you to find the problem.
[info] **********************************************************************************************
[info] [Progress] at 0.523 : Elaborate components
[info] [Progress] at 0.541 : Checks and transforms
[error] Exception in thread "main" spinal.core.SpinalExit: 
[error]  Can't infer width on     curlyrv.DecodeOps$$anon$1.<init>(Bug.scala:25)
[error]     curlyrv.DecodeOps.<init>(Bug.scala:23)
[error]     curlyrv.Bug.<init>(Bug.scala:32)
[error]     curlyrv.BugTop$.$anonfun$new$1(Bug.scala:36)
[error]     spinal.sim.JvmThread.run(SimManager.scala:51)
[error] Negative width on (Bits -> UInt of -1 bits) at     curlyrv.DecodeOps$$anon$1.<init>(Bug.scala:25)
[error]     curlyrv.DecodeOps.<init>(Bug.scala:23)
[error]     curlyrv.Bug.<init>(Bug.scala:32)
[error]     curlyrv.BugTop$.$anonfun$new$1(Bug.scala:36)
[error]     spinal.sim.JvmThread.run(SimManager.scala:51)
[error] ********************************************************************************
[error] ********************************************************************************
[error] Design's errors are listed above.
[error] SpinalHDL compiler exit stack : 
[error]         at spinal.core.SpinalExit$.apply(Misc.scala:455)
[error]         at spinal.core.SpinalError$.apply(Misc.scala:515)
[error]         at spinal.core.internals.PhaseInferWidth.impl(Phase.scala:1469)
[error]         at spinal.core.internals.PhaseContext.doPhase(Phase.scala:183)
[error]         at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$6(Phase.scala:2799)
[error]         at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$6$adapted(Phase.scala:2797)
[error]         at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
[error]         at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
[error]         at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
[error]         at spinal.core.internals.SpinalVhdlBoot$.$anonfun$singleShot$1(Phase.scala:2797)
[error]         at spinal.core.ScopeProperty$.sandbox(ScopeProperty.scala:71)
[error]         at spinal.core.internals.SpinalVhdlBoot$.singleShot(Phase.scala:2732)
[error]         at spinal.core.internals.SpinalVhdlBoot$.apply(Phase.scala:2727)
[error]         at spinal.core.Spinal$.apply(Spinal.scala:412)
[error]         at spinal.core.SpinalConfig.generateVhdl(Spinal.scala:178)
[error]         at curlyrv.BugTop$.delayedEndpoint$curlyrv$BugTop$1(Bug.scala:36)
[error]         at curlyrv.BugTop$delayedInit$body.apply(Bug.scala:35)
[error]         at scala.Function0.apply$mcV$sp(Function0.scala:39)
[error]         at scala.Function0.apply$mcV$sp$(Function0.scala:39)
[error]         at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
[error]         at scala.App.$anonfun$main$1$adapted(App.scala:80)
[error]         at scala.collection.immutable.List.foreach(List.scala:431)
[error]         at scala.App.main(App.scala:80)
[error]         at scala.App.main$(App.scala:78)
[error]         at curlyrv.BugTop$.main(Bug.scala:35)
[error]         at curlyrv.BugTop.main(Bug.scala)
[error] Nonzero exit code returned from runner: 1
[error] (Compile / runMain) Nonzero exit code returned from runner: 1
[error] Total time: 2 s, completed May 18, 2024, 7:23:41 AM

@andreasWallner
Copy link
Collaborator

andreasWallner commented May 19, 2024

@NikLeberg
For you last example, the issue is that you build the pipeline before you add the hardware into it.
(Your call to Builder(...) happens before the actual content of the pipeline is instantiated).

After fixing that we have to also connect inputs/outputs, otherwise all the HW gets optimized away and we might miss some issues. It works as expected like this (just a quick fix, not "nice" code):

case class Pipes() extends Area {
  val decode = CtrlLink()

  val IR = Payload(Bits(32 bits))
  val OPCODE = Payload(Bits(7 bits))
  val RD = Payload(UInt(4 bits))
}

case class DecodeOps(pipes: Pipes) {
  import pipes._

  val decoder = new decode.Area {
    OPCODE := IR(6 downto 0)
    RD := U(IR(10 downto 7))
  }
}

case class Bug() extends Component {
  val io = new Bundle {
    val ir = in port Bits(32 bit)
    val rd = out port UInt(4 bits)
    val opcode = out port Bits(7 bits)
  }
  val pipes = Pipes()
  val decodeOps = DecodeOps(pipes)

  pipes.decode(pipes.IR) := io.ir
  io.rd := pipes.decode.down(pipes.RD)
  io.opcode := pipes.decode.down(pipes.OPCODE)

  Builder(pipes.decode)
}

object BugTop extends App {
  SpinalConfig().generateVhdl{Bug()}.printPruned()
}

We should have a look whether we can generate a separate error message in this case - the current one is just from the fallout and is an aftereffect.

OT: In most cases you should place the Payloads into a companion object, not into the case class - that way you don't have different objects for every instance which can become really hard to reference down the line (since you need an instance to refer to them, the global singleton does not suffice).

@Dolu1990
Copy link
Member

Hi,

I found one bug in the SpinalHDL library which was preventing width inferation on the very first signal created (if created by the pipelining API)

Here is the fix :
a4baf0d

It may fix your issue aswell.

@NikLeberg
Copy link
Author

Hi @Dolu1990

Awesome! If I compile my example from above (with the fix of calling Builder(decode) after defining the logic) it now does not throw the width infer error and compiles with success!
Conversely if I go back to the latest released version 1.10.1 it fails with the mentioned error.
Interestingly, if I do what @andreasWallner suggested and prevent optimization by routing the payload to an IO bundle, then the error disappears even on 1.10.1.

Thank you both for your work and suggestions. For me this issue is fixed and I'm closing it. Feel free to reopen if you want to track:

We should have a look whether we can generate a separate error message in this case - the current one is just from the fallout and is an aftereffect.

Thanks, Nik

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

No branches or pull requests

3 participants