Giter Site home page Giter Site logo

Comments (10)

jeremyherbert avatar jeremyherbert commented on May 4, 2024 1

Looks good! I think USB data transfer is a good test case also.

from neorv32.

stnolting avatar stnolting commented on May 4, 2024

An example scenario is when using a DAC at a fixed sample rate to generate some complex, non-periodic waveform where the samples are computed by the software; the TX empty interrupt is not enough, as this is too late. It means that the DAC will likely have to stall or have some conversions with no data.

Good example! I did not think about this when implementing the SLINK. But it makes sense. So I agree that the IRQ conditions should be changed.

However, there is a problem: there is only one global TX interrupt. So if this interrupt indicates "TX FIFO half full" how does the software check which link's FIFO actually caused this interrupt? Right now there are only status flags that indicate if a certain TX is ready to send (so if the FIFO can take more data). There is the same problem with the global RX interrupt.

We could change the status flags or we could add more status flags that also indicate if a certain FIFO is half-full. 🤔

from neorv32.

jeremyherbert avatar jeremyherbert commented on May 4, 2024

Assuming that there would just be more status bits, what would be the current behaviour if, while the interrupt was being serviced, a separate tx halfway interrupt occurred? Are all of the status bits just ORed into the global interrupt line? If no interrupts would be missed, then I think just adding more status bits would be ok, splitting all of the status bits into their own 32 bit register perhaps?

I think having a configurable threshold rather than halfway is probably also useful for future proofing. I had a look at some STM32 data sheets with ethernet peripherals (where this functionality is common and often necessary) and they all had configurable levels with no fixed halfway interrupt. But this is obviously more costly in terms of registers as one would need to store the threshold.

from neorv32.

stnolting avatar stnolting commented on May 4, 2024

Assuming that there would just be more status bits, what would be the current behaviour if, while the interrupt was being serviced, a separate tx halfway interrupt occurred? Are all of the status bits just ORed into the global interrupt line?

Yes and no. The status flags are checked for edges and then they are OR-ed to generate the interrupt request. So if any FIFO fulfills the IRQ condition at any time an IRQ is generated.

If no interrupts would be missed, then I think just adding more status bits would be ok, splitting all of the status bits into their own 32 bit register perhaps?

Right now we have the following behavior: If a SLINK interrupt is being serviced right now, one more SLINK IRQ can trigger and will be queued until the current IRQ service handler has finished. I see that this might not be optimal. The current SLINK was build for hardware simplicity - the RX/TX interrupts just indicate "that something has happened" and it is up to the software to check which RX/TX links actually rang the interrupt.

I think having a configurable threshold rather than halfway is probably also useful for future proofing. I had a look at some STM32 data sheets with ethernet peripherals (where this functionality is common and often necessary) and they all had configurable levels with no fixed halfway interrupt. But this is obviously more costly in terms of registers as one would need to store the threshold.

I agree that this feature comes handy! But I think I would prefer to allow customization during a pre-synthesis constant where the default level is "half full". Furthermore, I think this is something to be configured via a constant in the package and not via a generic as it is a more specific option and the entity is already quite complex 😅

from neorv32.

jeremyherbert avatar jeremyherbert commented on May 4, 2024

I agree that this feature comes handy! But I think I would prefer to allow customization during a pre-synthesis constant where the default level is "half full". Furthermore, I think this is something to be configured via a constant in the package and not via a generic as it is a more specific option and the entity is already quite complex 😅

I have been thinking about this a little today, and I agree with you. I can't think of a realistic example where you would need to change this threshold at runtime. So pre-synthesis sounds like a good idea (I guess also powers of two to simplify the logic).

The interrupt problem is tricky. I believe the way this is handled on STM32s (as far as I can recall) is that the interrupts are level triggered, not edge triggered. So the interrupt will constantly fire unless the status register bit is cleared or the interrupt is masked off, and it is the responsibility of the software to somehow do one of these two things. If you perform some action to clear the status bit and then the event occurs again while the interrupt is running, it will run the interrupt a second time.

from neorv32.

stnolting avatar stnolting commented on May 4, 2024

I have been thinking about this a little today, and I agree with you. I can't think of a realistic example where you would need to change this threshold at runtime. So pre-synthesis sounds like a good idea (I guess also powers of two to simplify the logic).

👍

Do you think it is better to have per-link configurations or just one global configuration for the FIFO-level IRQ?

The interrupt problem is tricky. I believe the way this is handled on STM32s (as far as I can recall) is that the interrupts are level triggered, not edge triggered.

I tried to avoid level-sensitive interrupts for the CPU core. The CPU supports nested interrupts so a level-sensitive interrupt being high all the time could cause a deadlock (in the hardware!) if no care is taken by the software programmer.

How about this (this is quite close to your proposal):
If any FIFO (RX or TX) of any link reaches the "threshold" level (like half-full)...

  • an interrupt request to the CPU is generated
  • the SLINK hardware sets a "sticky" flag in its control register (there is one sticky flag for each FIFO, so a total of max 16 flags)

Then, the interrupt service handler has to...

  • check these sticky flags to determine which link/FIFO caused the interrupt
  • clear that sticky flag again in order to allow a new interrupt request from the according link/FIFO

from neorv32.

jeremyherbert avatar jeremyherbert commented on May 4, 2024

Yes, this approach sounds good to me.

from neorv32.

stnolting avatar stnolting commented on May 4, 2024

I thought about this again and I think that there is no need to provide an option to specify the FIFO fill level that triggers an interrupt. I think it is sufficient to always use "half-full" as trigger level. If an application requires a different level you could still add an external FIFO that asserts its "free" signal if its fill level has fallen below the custom level (in case of a TX link).

from neorv32.

stnolting avatar stnolting commented on May 4, 2024

I have reworked the SLINK interrupt system according to the discussion above.
-> 📚 SLINK

It was tested in simulation and with a very simple hardware setup, but I do not have a real application for verification of all aspects yet. I think the FOMU setups + a more sophisticated USB bridge (#102) might be a good real world test scenario.

from neorv32.

stnolting avatar stnolting commented on May 4, 2024

I think this can be closed.
Please open a new issue/discussion/PR if you find any bugs or if you have further ideas 😉

from neorv32.

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.