GithubHelp home page GithubHelp logo

Comments (11)

lk-davidegironi avatar lk-davidegironi commented on July 2, 2024 1

Thanks @Dolu1990
Not yet. My plan is to start XIP, then skip to the data stream.
I can maybe forget the floating point, doing some multiplication trick. Can't forget division but maybe on integer takes less resources.
Anyway I'll keep you updated here about the XIP, things are goings slower then I expect due to others task I'm involved in. Also due to the fact that I'm a really newbie in SpinalHDL.

from vexriscv.

Dolu1990 avatar Dolu1990 commented on July 2, 2024

Hi,

SpinalHDL does some linting to check that there is no important wire which is floating, and apparently that's the case :

[error] spinal.lib.bus.simple.PipelinedMemoryBus.(PipelinedMemoryBus.scala:42)
[error] vexriscv.demo.Murax$$anon$4.fromPipelinedMemoryBus(Murax.scala:313)

How did you implemented the ??? replacement ?

from vexriscv.

lk-davidegironi avatar lk-davidegironi commented on July 2, 2024

Thanks!

Not implemented, to be honest i thought '???' was a typo error. I've just find out it is a function that throws NotImplementedError.
I've read here #122 it was related to a word/byte based change in the way xip works.
If you have not update on this function I'll try to implement the buffer you are talking about, even if I'm not sure I'll be able to cause it's my first time in scala/spinalhdl (not in java and verilog luckily).

Meanwhile I ask you a suggestion for the softcore I would like to build, hopefully based on VexRiscv.
It will be integrated in a project that yet has an ethernet interface able to send/receive commands and a stream of data, and some external I/O driven by custom verilog code.
The main features of this soft core needs to be:

  • has to exchange commands with a payload of a few bytes (12 can be enough) with this ethernet interface, commands are asyncronous with a slow frequency (like 1Hz). Do you suggest Wishbone, AXILite, GPIO, other?
  • has to exchange a stream of 320 byte that are populated by an external verilog core. Those bytes contains raw DAC and ADC values. The logic has to make computation on that values and return the computed data back to the external verilog core (AXIStream or a big GPIO or wishbone or other?)
  • has to be OTA firmware enabled. The computation I was talking you about need to be changed without uploading a new firmware via JTAG. For this reason I was thinking at a SPI Flash, that could be possibly updated within the core, or by an external verilog ip, using an external arbiter to select which is the master for the SPI (if the verilog component or the softcore)
    For any of the above points indications and suggestions will be appreciated.

from vexriscv.

Dolu1990 avatar Dolu1990 commented on July 2, 2024

Not implemented, to be honest i thought '???' was a typo error.

Ahhh ??? is a scala thing to say "todo" ^^

has to exchange commands with a payload of a few bytes (12 can be enough) with this ethernet interface, commands are asyncronous with a slow frequency (like 1Hz). Do you suggest Wishbone, AXILite, GPIO, other?

Personnaly, i don't realy like wishbone (twisted stuff) neither axilite (overkilled / heavy).
I was going toward APB3 by the past (simple and stupid), but now i'm more toward tilelink, but i would say go apb3.

has to exchange a stream of 320 byte that are populated by an external verilog core. Those bytes contains raw DAC and ADC values. The logic has to make computation on that values and return the computed data back to the external verilog core (AXIStream or a big GPIO or wishbone or other?)

computation in the cpu right ?

As long as possible, stay with regular memory busses, ex apb3 and map stuff as peripheral. that should be fast enough, i mean, what speed the ADC values ?

that could be possibly updated within the core, or by an external verilog ip

Should be done with the core if possible, (as long as you can fit the function which "disable XIP -> update flash block -> enable XIP" software in the on-chip-ram)

from vexriscv.

lk-davidegironi avatar lk-davidegironi commented on July 2, 2024

Thanks for your reply!

Last week I've to work on a PCB design, so I'm back just today to this project. I'll check APB3 but I'm really a newbie on SoC and Scala, this will be difficult, anyway I'll try.

computation in the cpu right ?

Yes

ADC and DAC are on external I/O boards, data is exchanged using LVDS and muxed in the main FPGA board. I can not access directly ADC as peripheral. Anyway we are speaking of a payload (the 320bytes) at 100kHz rate. So 320byte updalod (ADC to FPGA)/320byte download(FPGA do DAC) that has to be processed at 100kHz. Simplifying, the 320byte contains the ADC 24bit raw values and let's say 64 ADC + other data, the 320 byte 16bit raw values of DAC + other data.
So it's a 100kHz processing job. Do you think is feasible?

Should be done with the core if possible, (as long as you can fit the function which "disable XIP -> update flash block -> enable XIP" software in the on-chip-ram)

That will be a long trip for me, but I'm gonna try it.

from vexriscv.

Dolu1990 avatar Dolu1990 commented on July 2, 2024

Anyway we are speaking of a payload (the 320bytes) at 100kHz rate.

hmm that's kinda a lot of data ^^ so it may not be faisable by the CPU alone.
Depend how much processing you do on each sample, but seems quite limite

from vexriscv.

lk-davidegironi avatar lk-davidegironi commented on July 2, 2024

First thank you again for your help, at this stage of my knowledge your experienced opinion matters.

I've started just today the work on the XIP, last week I was working on a another task (PCB side).

Moving to the computational side:
Computational may be reduced to just a few of all the bytes, also the output rate can be reduced down to 10kHz.
One consuming implementation could be process 8 PID on 8 feedback input signal. Let's say in that data we have 16 analog (24bit) input, 64 digital (1bit) input and 16 analog output (16bit) + 64 digital (1bit) output. So 56byte input, 40 byte output. Let's take 8 input raw data and transform it in float (24bit to float) (FPU plugin), process a PID algorithm on this data, output to 8 output (float to 16 bit). Do some simple logic on a few digital and skip the other raw data in the payload. The computation frequency should be 100kHz but we can slow down it to 10kHz if 100kHz is too much..

Another way I'm looking at is using an hardware core (like one Xilinx Cortex core, or the AE350 on the Tang Mega 138K board).

from vexriscv.

Dolu1990 avatar Dolu1990 commented on July 2, 2024

hmm did you tried to run that computer with some blank data already and checked the timings ?
Because especialy if you use floating point, that seems too much.

from vexriscv.

lk-davidegironi avatar lk-davidegironi commented on July 2, 2024

Finally I had time to dedicate to this.

I'm trying to build a sample project to test it. Luckily I know pretty well Java and Verilog... but Scala and Spinal are two different things, and it takes times to me to understand how they works. The most difficult thing to me is the lack of documentation for Spinal, another thing missing is a user forum (the spinal google group seems to be used just for meet notifications). I know it's mostly a one man band project and your effort @Dolu1990 is already huge, those above are just my note as a new entry.

Anyway, back to XIP, below my snipped code.
I'm trying to build a "fake" XIP / Pipiline bus environment. For sake of simplicity I'm first trying to replicate a simple 32 bits to 32 bits fromMemoryPBus, later I'll work on the 8 bit version. I've a few problems. To my understanding, but I may be wrong, something is missing cause the Murax/XIP is connected to SPI Ctrl which is connected to the XIP bus though Apb3SpiXdrMasterCtrl and SpiXdrMasterCtrl.driveFrom

val mapping = SpiXdrMasterCtrl.driveFrom(ctrl, Apb3SlaveFactory(io.apb, 0))(p)
io.xip <> mapping.xip.xipBus

I'm stuck on this issue. If you any help.
In any case I'll post update on XIP here.

I think I'll move to the APB3 interface for my data bus. Hoping will be simpler. If I've problem with this I'll post on spinal or vexriscv issue page.

case class NMemoryXBusConfig(
    addressWidth: Int,
    lengthWidth: Int
) {}
case class NMemoryXBusCmd(c: NMemoryXBusConfig) extends Bundle {
  val address = UInt(c.addressWidth bits)
  val length = UInt(c.lengthWidth bits)
}
case class NMemoryXBus(c: NMemoryXBusConfig) extends Bundle with IMasterSlave {
  val cmd = Stream(NMemoryXBusCmd(c))
  // this must be 8 bits
  val rsp = Stream(Fragment(Bits(32 bits)))
  override def asMaster(): Unit = {
    master(cmd)
    slave(rsp)
  }
  def fromMemoryPBus(c: NMemoryPBusConfig) = {
    val accessBus = new NMemoryPBus(c)

    // -- from murax.v
    // cmd.valid <> (accessBus.cmd.valid && !accessBus.cmd.write)
    // cmd.ready <> accessBus.cmd.ready
    // cmd.payload <> accessBus.cmd.address
    // rsp.valid <> accessBus.rsp.valid
    // rsp.payload <> accessBus.rsp.data
    // -- revised looking at signal direction
    // accessBus.cmd.valid := cmd.valid
    // accessBus.cmd.ready := cmd.ready
    // accessBus.cmd.payload.address := cmd.payload.address
    // accessBus.rsp.valid := rsp.valid
    // accessBus.rsp.payload.data := rsp.payload

    // accessBus.cmd.valid := cmd.valid
    cmd.valid <> (accessBus.cmd.valid && !accessBus.cmd.write)

    accessBus.cmd.ready := cmd.ready
    // cmd.ready <> accessBus.cmd.ready  ---  ASSIGNMENT OVERLAP completely the previous one of (toplevel/io_bus_cmd_ready : out Bool)

    // accessBus.cmd.payload.address := cmd.payload.address
    cmd.payload.address <> accessBus.cmd.address

    accessBus.rsp.valid := rsp.valid
    // rsp.valid <> accessBus.rsp.valid ---  ASSIGNMENT OVERLAP completely the previous one of (toplevel/io_bus_rsp_valid : out Bool)

    accessBus.rsp.payload.data := rsp.payload
    // rsp.payload <> accessBus.rsp.data --- ASSIGNMENT OVERLAP completely the previous one of (toplevel/io_bus_rsp_payload_fragment : out Bits[32 bits])

    accessBus
  }
}
case class NMemoryPBusConfig(
    addressWidth: Int,
    dataWidth: Int
) {}
case class NMemoryPBusRsp(c: NMemoryPBusConfig) extends Bundle {
  val data = Bits(c.dataWidth bits)
}
case class NMemoryPBusCmd(c: NMemoryPBusConfig) extends Bundle {
  val write = Bool()
  val address = UInt(c.addressWidth bits)
  val data = Bits(c.dataWidth bits)
  val mask = Bits(c.dataWidth / 8 bit)
}
case class NMemoryPBus(c: NMemoryPBusConfig) extends Bundle with IMasterSlave {
  val rsp = Flow(NMemoryPBusRsp(c))
  val cmd = Stream(NMemoryPBusCmd(c))
  override def asMaster(): Unit = {
    slave(rsp)
    master(cmd)
  }
  def <<(m: NMemoryPBus): Unit = {
    val s = this
    assert(m.c.addressWidth >= s.c.addressWidth)
    assert(m.c.dataWidth == s.c.dataWidth)
    s.cmd.valid := m.cmd.valid
    s.cmd.write := m.cmd.write
    s.cmd.address := m.cmd.address.resized
    s.cmd.data := m.cmd.data
    s.cmd.mask := m.cmd.mask
    m.cmd.ready := s.cmd.ready
    m.rsp.valid := s.rsp.valid
    m.rsp.data := s.rsp.data
  }
}
case class NMemoryBusCopyConfig(
    cp: NMemoryPBusConfig,
    cx: NMemoryXBusConfig
) {}
class NMemoryBusCopy(c: NMemoryBusCopyConfig) extends Component {
  val io = new Bundle {
    val bus = slave(NMemoryXBus(c.cx))
    val accessBus = slave(NMemoryPBus(c.cp))
  }
  io.bus.fromMemoryPBus(c.cp) << io.accessBus
  // fake mapping bus connector
  io.bus.cmd.ready := True
  io.bus.rsp.valid := True
  io.bus.rsp.payload := 20
  io.bus.rsp.last := True
}

object NMemoryBusSample {
  def main(args: Array[String]): Unit = {
    SpinalVerilog(
      new NMemoryBusCopy(
        NMemoryBusCopyConfig(
          cp = NMemoryPBusConfig(addressWidth = 24, dataWidth = 32),
          cx = NMemoryXBusConfig(addressWidth = 24, lengthWidth = 2)
        )
      )
    )
      .printPruned()
      .printPrunedIo()
      .printUnused()
  }
}

from vexriscv.

Dolu1990 avatar Dolu1990 commented on July 2, 2024

Hi,

You can consider the github issues / discution channel as a forum.
For chat there is : https://app.gitter.im/#/room/#SpinalHDL_VexRiscv:gitter.im which is quite active ^^
Yes, the mailing list is only for notification so far.
Missing documentation about SpinalHDL.core, or SpinalHDL.lib ?

I'm not sure the setup you have currently.
Can you push your code somewere + provide which main you are running when you hit the issue ?

from vexriscv.

lk-davidegironi avatar lk-davidegironi commented on July 2, 2024

Hello @Dolu1990
I'll consider both this and the gitter channel. The thing I'm missing more is samples, I can find some in tests, but I miss more :)

At present I've stop working to XIP and moved to stream data, for which I've just posted a question.

from vexriscv.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.