12 Replies Latest reply on Feb 28, 2019 1:12 AM by DaGi_900591

    UDB A0 -> FIFO -> DMA




      I'm trying to build a UDB datapath component which measures the time between pulses, with the intention being to DMA the resulting byte stream into RAM. I've built a state machine and set up, hopefully, the appropriate set of instructions. However, it looks like data never gets written to my FIFO --- the 'F0 bus status (not empty)' signal never gets asserted.




      - there appears to be no way for an ALU operation to write to a FIFO. So, instead I add a datapath input for 'Load F0 with A0' which tests the FSM state. (And as far as I can tell this input does seem to be getting asserted.) This seems very contorted. Is there a better way?


      - are there any application notes describing how to set up output DMA for a datapath component? It's not simple, and there are a lot of subtleties in getting the maximum possible throughput.


      - is there a simulator or debugger or some way to observe the internal state of the component? Right now I have absolutely no idea whether my state machine even works!


      The full project's attached if anyone really cares to look --- the component is UdbSampler and it's on the 'Capture' page of the schematic.




      (In the picture below, fifoready is being exported as the component's drq; and push is defined as (FSM == ROLLOVER_STATE) || (FSM == PULSE_STATE).)


        • 1. Re: UDB A0 -> FIFO -> DMA

          Wouldn't be easier to use a standard Counter component designed for that?

          • 2. Re: UDB A0 -> FIFO -> DMA

            How would I use a counter to do this? Bearing in mind that if a pulse comes in the same tick as a counter overrun I need to generate an 0x80 byte (for the overrun) plus a 0x00 byte (for the pulse) at the same time.

            • 3. Re: UDB A0 -> FIFO -> DMA

              I have 'Load F0 with A0' set to 1 in the inputs section of the datapath; and I'm exporting 'F0 bus status (not empty)' as a wire.


              F0 is set to be level sensitive, so, every time the datapath clock ticks, it should push a new value into F0. And yet I never see the F0 bus status being asserted. It's never not empty.


              Do FIFOs need enabling or something before they work? There's no mention in the docs. I've tried resetting it with this code:






              ...but makes no difference.


              Does anyone have any ideas? I'm completely blocked on this and making no progress with my project.

              • 4. Re: UDB A0 -> FIFO -> DMA

                You can have a look at the chapter 7 of the Component author guide to set up DMA.

                • 5. Re: UDB A0 -> FIFO -> DMA

                  The UDB Editor does not support Dynamic FIFO Control. You can try to copy and paste the Verilog code generated by the UDB Editor and modify the Verilog file using data path configuration tool. 

                  • 6. Re: UDB A0 -> FIFO -> DMA

                    I'm pretty sure the DMA works fine --- I can trigger the DMA manually by using something like FSM==PULSE_STATE as the drq trigger and it will transfer data. But that just generates garbage, of course. I need to trigger the DMA based on whether the FIFO contains data, but it never signals as containing any data.


                    I'm not using dynamic FIFO control.

                    • 7. Re: UDB A0 -> FIFO -> DMA

                      Can you tell me what is rollover, rollover state and pulse state in your state in your state diagram.

                      • 8. Re: UDB A0 -> FIFO -> DMA

                        I'm measuring the intervals between pulses, using sampleclock to drive the counter. The state machine itself is clocked at BUS_CLK.


                        IDLE_STATE: I'm waiting for a sampleclock posedge.

                        COUNT_STATE: I've just received a sampleclock posedge. Increment A0.

                        PULSE_STATE: A pulse has arrived. Push A0 to the FIFO and set A0=0.

                        ROLLOVER_STATE: the counter has rolled over to 0x80. Push A0 to the FIFO and set A0=0.

                        RELAX_STATE: I've finished processing a sampleclock and am waiting for a sampleclock negedge before returning to IDLE_STATE.


                        ROLLOVER_STATE checks for rdata because if a pulse arrives at the same sampleclock tick as the counter rolls over, I need to push both a 0x80 and a 0x00 to the FIFO (which is why I have to have a FIFO in the first place).

                        • 9. Re: UDB A0 -> FIFO -> DMA

                          Please go through the Simple UART example on page 39 of the link below.


                          • 10. Re: UDB A0 -> FIFO -> DMA

                            The UART example uses an input FIFO rather than an output FIFO; the input FIFO direction is easier as the ALU is capable of reading directly from F0 via the register write functionality.


                            I've been unable to find any examples of using an output FIFO --- searching google for 'Load F0 with A0' only has two hits; one for the UDB document linked to above, and another for the Chinese translation. Does anyone have anything? (An RX UART example would be ideal!)

                            • 11. Re: UDB A0 -> FIFO -> DMA


                              I have attached a project that makes use of the F1 register as the output register, and we are able  to load values in it. This project is only made for testing purposes and is not a final project.

                              • 12. Re: UDB A0 -> FIFO -> DMA

                                So I have actually managed to make it work; but I don't know how... I just randomly rearranged things and suddenly started receiving data. UDB documents aren't diffable so figuring out what I actually changed to make this happen is very hard. (Plus it's all mixed up in other changes.) This makes me somewhat uncomfortable as I can't tell what future changes I might make might make it all stop working again!


                                Can I make a plea to Cypress to add some kind of simulation / testing support to the UDB datapath feature? It's amazingly powerful, but also amazingly hard to debug when it goes wrong. Too much of the state is internal and not easily accessible from outside the datapath (like the contents of the various registers).


                                Also, one gotcha I found in my state machine (although I don't this affected the FIFO issue): moving from one state to another based on computing signals (rollover in my diagram above) is counterintuitive: the value of the signal used to do the FSM transition is as it was on entry to the state, because the FSM transition happens in parallel with the datapath computation triggered by the state itself. So in fact I needed to test for A0 == 0x7F rather than 0x8F, because I would decide whether to move to ROLLOVER_STATE before incrementing the count.