Hi,I've design a Nios system in which I insert my custom module interfacing it using the slave MM wrapper. This custom block receives a start command and sends 32 bit data (values from 32 to 126) to Nios II continuously, setting also a ready flag when data is ready. I tried to do polling on this ready flag to know when I could read 32 bit data...but I saw data are wrong without order... Is it possible that when I try to read the data register of my custom module, using the macro (data=IORD(BASE,OFFSET)), its value has changed....???? Could I gain something using interrupt instead of polling??? Regards
Does your component waits until the value was read before providing a new one to the CPU? It may be a good idea to look what's going on in your component using SignalTap.Using interrupts is mostly a performance improvement, as it allows the CPU to do something else when data isn't available, instead of polling continuously. But you should first find out why you get the wrong data before thinking about using interrupts.
I tried to insert a "go" input signal in my custom block. When a 32bit data is ready, custom block sets "ready" signal to '1' and waits without sending other data until nios II polling on this "ready signal" and asserts "go" signal to '1' when it finishes to read 32bit data from custom block. So custom block sets "ready" signal to '0' and re-begins to send another 32bit data and so on.In this way I succeed in getting my correct data....but I think this is an inefficient procedure....as regards data rate, and cpu performance... Regards
You are on the right track, I always think it's better to start with something that is secure and that works well, before thinking about optimization for performance. Now you have a starting point and can try to get it better.Now you can save one access by removing the "go" signal. Your component knows when the data is read, as you get a "read" signal on the Avalon Slave interface. You can use that to trigger the next value read. Without interrupts this is the best you can do for this kind of transfer. As I said with an iterrupt you wouldn't need the ready signal any more and could just wake up the CPU when new data is available, but it requires a bit more work on the software side. If you have a lot of data and want to transfer in efficiently to main memory, you should be looking for a DMA instead, such as Altera's SGDMA or the modular SGDMA available on the wiki. Then your component will just have to present the data on an Avalon Stream interface, and the DMA will take care of the rest.
Alternatively, if you have a very simple 'round robin' scheduler (not really a scheduler at all) that just call each 'task' running on your card in turn, it may well be simplest to just check the 'need data' / 'data available' bit every time the scheduler loop calls the task.That might mean you need to instrument (and optimise code for) the 'worst case' code path.