Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Aug 20 07:06
    jijingg commented #226
  • Aug 20 07:03
    jijingg commented #226
  • Aug 17 13:42
    Dolu1990 commented #226
  • Aug 14 13:30
    jijingg commented #226
  • Aug 13 16:47
    Dolu1990 commented #226
  • Aug 13 11:33
    jijingg commented #226
  • Aug 13 10:18
    Dolu1990 commented #226
  • Aug 13 04:45
    jijingg opened #226
  • Aug 12 10:21
    FrankBuss commented #225
  • Aug 12 07:52
    Dolu1990 commented #225
  • Aug 10 19:28
    FrankBuss commented #225
  • Aug 10 18:49
    Dolu1990 commented #225
  • Aug 10 14:04
    FrankBuss opened #225
  • Aug 07 13:06
    Dolu1990 commented #210
  • Aug 07 13:02
    jijingg commented #210
  • Aug 07 12:59
    jijingg commented #210
  • Aug 07 10:35
    Dolu1990 commented #210
  • Aug 07 07:49
    jijingg commented #210
  • Aug 07 07:23

    Dolu1990 on dev

    Add SpinalReport.getRtlString (compare)

  • Aug 05 08:47
    Dolu1990 commented #202
AndrewCapon
@AndrewCapon
Nice, thanks very much for all the help.
Marlon
@jijingg
@AndrewCapon SpinalHDL have good Ducuments ,If you're interested, SpinalDoc is a good starting for learning
AndrewCapon
@AndrewCapon
Thanks, I have read through the documentation a few times, it is the concepts I am finding hard to grasp though ;)
The clocking stuff I have had a problem getting my head around, it is starting to make a bit more sense now though.
Marlon
@jijingg
hi @Dolu1990, i have already download scala2.12.7/spinal1.3.6, but jupyter always loaded version 2.11.11, i have no idea how to load2.12 version, any suggestion ?
image.png
Dolu1990
@Dolu1990
never used Jupyter, sorry, can't say
Marlon
@jijingg
@Dolu1990 ther issue of "new Componet/Bundle Compile Fail" was sovled , just switch scala2.12 is ok . thank you : )
Dolu1990
@Dolu1990
Good to know :)
AndrewCapon
@AndrewCapon

Hi Guys,

I'm having some timing issues in nextpnr when setting registers in a StateMachine

Setting bit register in StateMachine

ERROR: Max frequency for clock   'clk_$glb_clk': 174.61 MHz (FAIL at 200.00 MHz)

Setting bit register in when block

Info: Max frequency for clock   'clk_$glb_clk': 276.32 MHz (PASS at 200.00 MHz)

This is confusing me, Why would this be?

Dolu1990
@Dolu1990
Which FPGA is it ?
what is the code ?
AndrewCapon
@AndrewCapon

FPGA is hx8k

Sorry I don't have the test code I used for those figures now, I do have this though:

With StateMachine : Info: Max frequency for clock 'clk25_$glb_clk': 96.62 MHz

  val fsm = new StateMachine{
    val stateDecode   = new State with EntryPoint
    val stateReceive  = new State
    val stateSend     = new State

    val counter = Counter(256)
    val skipByte = Reg(Bool) init(True)

    stateDecode
      .whenIsActive{
        sendByte := 0xfe
        when(qspiSlaveCtrl.io.rxReady.rise())
        {
          when(qspiSlaveCtrl.io.rxPayload === 0x01){
            goto(stateReceive)
          } otherwise when(qspiSlaveCtrl.io.rxPayload === 0x02){
            goto(stateSend)
          }
        }      
      }

    stateReceive
      .onEntry(counter := 0)
      .onEntry(skipByte := True)
      .whenIsActive{
        sendByte := 0xfd
        when(qspiSlaveCtrl.io.rxReady.rise())
        {
          when(skipByte){
            skipByte := False
          } otherwise{
            mem(counter) := qspiSlaveCtrl.io.rxPayload;
            counter.increment()
          }
        }      

        when(io.ss){
          goto(stateDecode)
        }
      }

    stateSend
      .onEntry(counter := 0)
      .onEntry(skipByte := True)
      .whenIsActive{
        when(qspiSlaveCtrl.io.txReady.rise())
        {
          when(skipByte){
            skipByte := False
            sendByte := mem(counter)
          } otherwise{
            sendByte := mem(counter)
            counter.increment()
          }
        }      

        when(io.ss){
          goto(stateDecode)
        }
      }
  }

The following code without StateMachine : Info: Max frequency for clock 'clk25_$glb_clk': 158.53 MHz

  // alternative to StateMachine()
  object FSMState extends SpinalEnum {
    val sDecode, sReceive, sSend = newElement()
  }

  val stateNext = Reg(FSMState())
  stateNext := FSMState.sDecode

  val counter = Counter(256)
  val skipByte = Reg(Bool) init(True)

  switch(stateNext){
    is(FSMState.sDecode){
      when(qspiSlaveCtrl.io.rxReady.rise())
      {
        counter := 0
        skipByte := True

        when(qspiSlaveCtrl.io.rxPayload === 0x01){
          stateNext := FSMState.sReceive
        } otherwise when(qspiSlaveCtrl.io.rxPayload === 0x02){
          stateNext := FSMState.sSend
        }
      }      
    }

    is(FSMState.sReceive){
      stateNext := FSMState.sReceive
      when(qspiSlaveCtrl.io.rxReady.rise())
      {
        when(skipByte){
          skipByte := False
        } otherwise{
          mem(counter) := qspiSlaveCtrl.io.rxPayload;
          counter.increment()
        }
      }      

      when(io.ss){
        stateNext := FSMState.sDecode
      }
    }

    is(FSMState.sSend){
      stateNext := FSMState.sSend
      when(qspiSlaveCtrl.io.txReady.rise())
      {
        when(skipByte){
          skipByte := False
          sendByte := mem(counter)
        } otherwise{
          sendByte := mem(counter)
          counter.increment()
        }
      }      

      when(io.ss){
        stateNext := FSMState.sDecode
      }
    }
  }
Marlon
@jijingg
@Dolu1990 I have a dynamic bits width inference question need your help, it nagged me for days
The situation was that n Duts connected one by one(for simple,use 3).
image.png

but the Dut's port gap width not only depending on config parameter expand but also which connected to.

case class myConfig(expand: Int)
class Top extends Component {
  val gap = in Vec(UInt(), 3) //lazy Width

  lazy val Dut0 = new Dut(myConfig(4))
  lazy val Dut1 = new Dut(myConfig(2))
  lazy val Dut2 = new Dut(myConfig(3))

  Dut0 ---> Dut1
  Dut1 ---> Dut2

  Dut0.io.gap := gap(0) //9bit
  Dut1.io.gap := gap(1) //5bit
  Dut2.io.gap := gap(2) //3bit
}

so, myquestion is how to make width inference automatically?
(Maybe this is the simplest example of parameter negotiation.)

class Dut(mc: myConfig) extends Component {
  val io = new Bundle{
    val gap = in UInt(???  bits)// width depending on which connected(--->)
  }
  // not real code, but get idea
  val gapWidth: Int = if(isLast) mc.expand else (mc.expand + nxt.width)

  private var isLast: Boolean = true
  def --->(that: Dut) = {
    isLast = false
  }
}
Snoopy87
@Snoopy87
@jijingg Try to build a software model of your design and then from the model you can generate the hardware.
Marlon
@jijingg
@Snoopy87 Yes, I agree. But I haven't fully understood the implementation behind Spinal, so maybe it will take some time. I saw the implementation of Simulator of digital circuits in 《Programing in Scala》, but the content is too short. I didn't find good information on Google either. If anyone have good articles or books about how to implement digital circuits with function Programing , thak you to share with me
AndrewCapon
@AndrewCapon
Hi Guys, Is there an example of using inout signals anywhere, I'm basically trying to do a QSPI Slave. I have tried Tristate and InOutWrapper on the TopLevel with .read, .write and .writeenable and just get: [error] IO BUNDLE ERROR : A direction less (toplevel/io_io0_read : Bool) signal was defined into toplevel component's io bundle
Snoopy87
@Snoopy87
@AndrewCapon both state machine are not equal. in the first you are using .onEntry() and in the second you are using another logic. So, you can not compare both statemachine...
In your code your are using "otherwise when(xxx)" which is weird, use elsewhen(xx) instead.
In your code you are using several time "qspiSlaveCtrl.io.txReady.rise()" each time you call .rise() you will create hardware to dectect edge. At the beginning of your state machine you can write "val txReadyRise = qspiSlaveCtrl.io.txReady.rise()" and then use txReadyRise in your code in order to generate the hardware once.
@AndrewCapon Can you show me your code. here are some doc about inoutWrapper
https://spinalhdl.github.io/SpinalDoc-RTD/SpinalHDL/Other%20language%20features/analog_inout.html
AndrewCapon
@AndrewCapon
@Snoopy87 Thanks for the pointers, I did try without the .OnEntry() but didn't notice much of a difference, thanks for the tips about elsewhere and .rise() I will make changes. Concerning the inout stuff, I stopped using InoutWrapper and got it to work from the verilog with TriStateArrays.
Dolu1990
@Dolu1990
@AndrewCapon Having general on entry and on exit stuff in a state machine isn't the same than putting the code at the same place where you change the state
basicaly, it compare the current state and the next state to figure out there is a transition
That's probably why it isn't going as fast
Also, StateMachine has an additional hidden boot state

@jijingg In general, i would recommand to not use to much the width inference, especialy when it cross componnents. at the end i consider that this feature is a bad good idea which do not especialy well mix with internal DSL.

The reason is you sometime need the width of something, but havint connected it fully to its width inferance hardware

Dolu1990
@Dolu1990
Or it force you to describe your hardware in a very specific order
@Snoopy87 +1
Marlon
@jijingg
@Dolu1990 thanks for your advice. I need to reorganizing my code. Maybe it's true of that relying entirely on bit-width inferences can make the code confusing and unreadable. in addition, parameter negotiation should not be entangled with circuit code, and should be clearly separated.
Dolu1990
@Dolu1990
right :D
Marlon
@jijingg
But for some very basic units, I think bit inference is useful, such as a counter. I hope that the bit width of the register depends on who it is connected to. It would be tedious to have it manually specified. is there any way to achive that ?
class MyCounter extends Component{
  val end = in UInt()  //width inference from which who connected
  ...
  val value = Reg(cloneOf(end)) init 0  // failed !  what is the right way?
  ...
}
Dolu1990
@Dolu1990
Reg(UInt()) init(0) isn't ok ?
Marlon
@jijingg
No, because end does not have a direct assignment process to value
class CounterTo extends Component{
  val start,ready = in Bool()
  val end  = in UInt()
  val counter = out UInt()
  val vld  = out Bool()
  val cntEnd = out Bool()

  val cntEn = Reg(Bool()) init False
  val value = Reg(UInt(widthOf(end) bits)) init 0

  when(start) {
    cntEn := True
    value := 0
  }.elsewhen(cntEnd) {
    cntEn := False
    value := 0
  }.elsewhen(cntEn && ready) {
    value := value + 1
  }

  cntEnd  := cntEn && ready && (value === end)
  counter := value
  vld := cntEn
}
Dolu1990
@Dolu1990
ahhhh
Damned XD
Then there is no way
I mean, no proper way
Marlon
@jijingg
o(╥﹏╥)o
Dolu1990
@Dolu1990
we could imagine additional SpinalHDL tag that you can add to signals to help the width inferance
But it start to go into dangerous waters XD
Honnestly, width inferance is a sexy shortcut, but that's alsy quite dirty, it work for simple cases, but as soon you go into complicated stuff, it break
Marlon
@jijingg
yes , it's pandora box , hah
Dolu1990
@Dolu1990
yes
Marlon
@jijingg
what about any way rely on lazy feature
Dolu1990
@Dolu1990
It also do not fit well with the internal dsl paradigm, where you elaborate things yourself
Marlon
@jijingg
ok
wifasoi
@wifasoi
If someone is at cccamp we can organise a join incursion in the hardware hacker area
Dolu1990
@Dolu1990
Not there sorry