Comments (10)
Looks good! I think USB data transfer is a good test case also.
from neorv32.
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.
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.
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.
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.
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.
Yes, this approach sounds good to me.
from neorv32.
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.
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.
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)
- Processor doesn't park itself in a know good state prior to going to sleep HOT 3
- Nexys 4 DDR FPGA board flashing zephyr RTOS hello_world no output on default UART HOT 11
- Atomic accesses documentation error HOT 2
- neorv32_fifo vivado implementation issue HOT 1
- Implementation problem in XILINX ISE HOT 2
- Illegal instruction in coremark HOT 5
- Utilizing on-board SRAM HOT 16
- [idea] Add indirect CSR accesses (Smcsrind ISA extension)? HOT 3
- Illegal compressed instruction reports 2 traps. HOT 7
- Variation in counter values HOT 16
- CSR reads fail for un-implemented features like HPM counters HOT 7
- Cannot upload neorv32_exe.bin for demo CFS on NexysA7 HOT 10
- Reserved compressed instructions do not trigger illegal instruction exception HOT 4
- FPU fflags no being asserted correctly HOT 15
- Instruction to halt TRNG operation HOT 2
- ERR_EXE when uploading neorv32_exe.bin for demo_blink_led on DE2-115 Board HOT 2
- FPU more fflags issues and a few logic bugs HOT 11
- Compressed instruction decoder edge case not handled HOT 3
- hpmevent_cfg_t fails synthesis for hpm_num=0 HOT 5
- c.srli HINT flagged as illegal HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from neorv32.