Obviously simultaneous writes will cause problems.In our case, one Avalon Master is reading while the other Master is writing. So, the question is, will simultaneous write and read of the SAME address cause problems. It does not matter if I read "old" or "new" data as long as the write is successful and I don't read garbage or a combination of "old" and "new". The Master that writes also uses other portions of the RAM and I'm hoping to avoid the arbitration delays with a single port RAM. Thanks,
--- Quote Start --- Obviously simultaneous writes will cause problems. In our case, one Avalon Master is reading while the other Master is writing. So, the question is, will simultaneous write and read of the SAME address cause problems. It does not matter if I read "old" or "new" data as long as the write is successful and I don't read garbage or a combination of "old" and "new". The Master that writes also uses other portions of the RAM and I'm hoping to avoid the arbitration delays with a single port RAM. Thanks, --- Quote End --- What about (a) using a 2x faster clock for read and write but 1x clock for addressing (b) reading before writing. That way from the same address you first read and then write. Also (c) make the logic such that the enables for read and write are mutually exclusive i.e. when read is enabled, write is not and vice versa. That way, when the same address is on the bus, you can only do one of the two operations.
When you create an altsyncram component using the megawizard, you are given the option to specify that you want the old contents to appear on a read during write operation. It's found on the output tab under the group box entitled "Mixed Port Read During Write for Single Input Clock Ram"This option is available for M512, M4K, and M9K blocks but not for M-RAM. Of course for a dual-clock RAM, you're out of luck. Jake
I'm using the on-chip RAM component under SOPC Builder. Everything is off the same clock.Jake - I see the option you list if I add the altsyncram. It's unfortunate that SOPC Builder does not have a similar option.
There are a couple of workarounds.1 - The write-during read behavior is just a parameter passed to the altsyncram instance (which is all the SOPC builder instantiated memory is). In Quartus on the Heirarchy tab, you can browse to the altsyncram instance in your SOPC system and view the current parameter settings. If you then right click on the altsyncram instance and click Locate->Locate in Assignment Editor; you can add or override any of the parameter settings for that altsyncram instance by adding a "Parameter" assignment. So you would add a parameter assignment where the parameter name is "READ_DURING_WRITE_MODE_MIXED_PORTS" and set the value of that assignment to "OLD_DATA". 2 - Create your own custom SOPC component that just acts as a wrapper around an altsyncram instance. Then you can set it up how you want. Personally, I'd do number 1. Take about 10 seconds. EDIT: You may also want to check out this: http://www.altera.com/support/kdb/solutions/rd04172006_685.html?gsa_pos=2&wt.oss_r=1&wt.oss=altsyncr... as an explanation for why they do things the way they do. Jake
--- Quote Start --- I'm using the on-chip RAM component under SOPC Builder. Everything is off the same clock. Jake - I see the option you list if I add the altsyncram. It's unfortunate that SOPC Builder does not have a similar option. --- Quote End --- You don't need that option. The option is only for selecting the "read during write behavior", old data or new data. But you are saying you don't care. You only care about not getting garbage or a mixed result. This will never happen.
Jake,Thanks, I agree that# 1 looks best and will try that and the link was very helpful. Considering that I'm in a Cyclone part without MRAM it's kinda funny they don't have that as an option since there are no MRAM blocks. I tried a web and forum searches but forgot about the knowledge database :mad: . Interestingly, various web searches I just tried didn't turn up that link you posted in the first handful of results pages although I was able to find it by searching for a quoted phrase on the page.
vjAlter,From the Altera link "It will always set the altsyncram's parameter READ_DURING_WRITE_MODE_MIXED_PORTS to "DONT_CARE" which will result in unknown outputs when reading from the same memory location that is being written to by the other port." This parameter can be NEW_DATA, OLD_DATA, or DONT CARE I interpreted "Unknown outputs" as garbage values. You're saying that DONT CARE effectively means you don't care if you get NEW or OLD DATA. I'm guessing that the actual result (new vs. old) will then be part/optimizer/compiler specific. And yes, it doesn't matter whether I get new or old data. That does eliminate some fears about changing SOPC Builder and accidentally losing the setting. Thanks
From the cyclone II datasheet (same rules apply for other families):--- Quote Start --- Mixed-Port Read-During-Write Mode This mode applies to a RAM in simple or true dual-port mode, which has one port reading and the other port writing to the same address location with the same clock. In this mode, you also have two output choices: old data or don't care. In Old Data Mode, a read-during-write operation to different ports causes the RAM outputs to reflect the old data at that address location. In Don't Care Mode, the same operation results in a "don't care" or unknown value on the RAM outputs. --- Quote End --- There are accompanying waveforms as well. Unknown means unknown folks. It does not mean "New Data." If you are going to write and read from the same address at the same time, it had better be because you "Don't Care" what the read data is. Jake
--- Quote Start --- From the cyclone II datasheet (same rules apply for other families): There are accompanying waveforms as well. Unknown means unknown folks. It does not mean "New Data." If you are going to write and read from the same address at the same time, it had better be because you "Don't Care" what the read data is. --- Quote End --- After re-reading the datasheet, I see you are right. However, it doesn't make any sense to me. May be you or somebody else could elaborate. What's the purpose of having a hardware configuration mode that doesn't give you anything, except uncertainty? Why not making the "OLD_DATA" the only option, let alone the default one? If "Don't care" would give you something, more performance, less power consumption, or whatever, then it would make sense. But none is mentioned in the datasheet. So this mode seems even silly. The option at the MegaWizard does make some sense. It might be useful when porting the design to a different family, or changing the RAM type. But at the hardware level, I cannot understant its purpose.
It requires extra circuitry to provide the "old data" option. So there are two reasons for giving the option:1 - The "old data" option is not available for M-RAM blocks (available in Stratix series). So if you select the "old data" option and have chosen "Auto" as the RAM type, you are restricting the synthesis tool as to what types of RAM blocks it can use. You are taking away some flexibility from the compiler as it can no longer use M-RAM. 2 - Under certain circumstances you can get a performance decrease when using the "old data" option. For most designs, this data path will not be the limiting factor. Jake
FYI: We just ported the design to Quartus 8.0 SP1. Under that version there is now an option in the Component Editor for Old Data / Don't Care under a dual Port RAM.So Altera has updated the Component in this latest version to eliminate the problem of having to set the parameter manually as described earlier. Thanks for all your help.
Although there is an 'old data' / 'don't care' option, I think we've discovered (the hard way) that this gets ignored (in 9.1sp2 at least) because both clocks are specifed - even when they are identical.Quartos 12 has an extra 'tick box' for 'single clock operation'. The http://www.altera.com/support/kdb/solutions/rd04172006_685.html?gsa_pos=2&wt.oss_r=1&wt.oss=altsyncr... is just a lame excuse! If you request OLD_DATA then it shouldn't be discarded, but constrain the types of memory that can be used. Without OLD_DATA you get the old or new copy of each bit, changing randomly with different silicon and different builds of exactly the same vhdl.
Hi, sry for digging out this rather old thread. But I think it might be the most suitable thing to do. My problem:I have a EP4CE55 FPGA. On there I have a DPRAM attached to a NIOS with cache. From the other side I'd fill the ram with new process dataas its coming in using a DMA. For performance reasons I'd lke to attach it as tightly-coupled memory - only supported for dual-clock mode. But then the DPRAM doesn't support the "OLD DATA" option for read-during write access. Will the tightly coupled memory increase performance significantly? In any case to access this area of data I will bypass cache (alt_remap_uncached). Is the decision really only between NEW_DATA and OLD_DATA or is it possible to really get garbage? Further on scanning the Altera Documentation a I found the following on page 3-17 of the Cyclone IV Device Handbook: --- Quote Start --- For mixed-port read-during-write operation with dual clocks, the relationship between the clocks determines the output behavior of the memory. If you use the same clock for the two clocks, the output is the old data from the address location. However, if you use different clocks, the output is unknown during the mixed-port read-during-write operation. This unknown value may be the old or new data at the address location, depending on whether the read happens before or after the write. --- Quote End --- This would imply that I can just use it in Dual Clock Mode, connect the same clock and get the OLD_DATA behaviour? Or am I getting this one wrong? Thanks!
With M9K we got garbage - well the old or new value of each bit, not of the whole word.The error rate varied by device and by build. Minor changes to the logic caused different chips to fail. The Nios cpu reads tightly coupled memory every clock cycle, discarding the data if the instruction isn't a memory read or if the address doesn't match the memory block. If the instruction pipeline stalls (eg on an Avalon cycle) it needs to keep the data even though the address has been updated. On M9K this is done by deasserting clken (dual clock mode) or asserting 'address hold' (single clock mode). I don't know anything about DPRAM blocks. However if you are filling in buffers using dma then you probably don't want to process a mixture of the old and new data for an entire buffer - so a corrupt byte in the middle of such a buffer won't be read anyway. Using tightly coupled memory will give better performance, how significant it is depends rather on what your code is doing.
Thanks for the answer. This is the problem I'm trying to solve just now. How can a implement a mechanism that allows me to only process complete buffers. I thought about having a control structure in the DPRAM that manages a page flipping mechanism. But again within this control structure I could get corrupted data.A avalon mutex could be used to handle this problem. I could also retreat to using a single port ram. In this case the avalon arbitration would handle the accesses - of course not being able to implement it as tightly coupled memory. The CPU is basically performing closed-loop control tasks. The data in the dpram will for example contain the desired value for the controllers. This comes down to one acces per process variable per cycle. The target control frequency would be something around 3kHz. I can not judge how much in this case the performance would be in/decreased using tightly-coupled memory. Thanks!
You can safely detect 'changed' on a word even without OLD_DATA. In the simplest case if the word changes from 0 to 1 (and back) I don't believe you'll ever read an illegal value.So you could, for example, detect the last word of the buffer being changed by writing a reserved value to it, and waiting for it to change. But why not put the control bit somewhere outside the shared memory - like a PIO bit in the avalon slave with the control registers for your logic that is writing the buffers? Then your control loop polls the pio slave to determine when the buffer is available.
Once again thanks for your answer!Actually my slave is another NIOS that is interfacing two Ethernet MACs and handling UDP communication. If a relevant packet arrived it is copied to the DPRAM using a DMA. The idea was to avoid another copy on the application side - eg in the attached sdram - and use the data in the dpram. So it boils down to inter-cpu communication mechanism. I have a whole control data block in the beginning of the dpram that handles this communcation - but little of it is really critical. I also considered the PIO alternative as a mean of async communication. I should run the PIOs in the same clock domain as the CPUs- not slower - otherwise I'll build a bottleneck?!? Will the PIO solution outperform a mutex based solution? I have that feeling that there's a nifty (and easy) solution for it by somehow juggling with the possible bit change states as you suggested above. I didn't quite get what you meant with that: --- Quote Start --- The Nios cpu reads tightly coupled memory every clock cycle, discarding the data if the instruction isn't a memory read or if the address doesn't match the memory block. If the instruction pipeline stalls (eg on an Avalon cycle) it needs to keep the data even though the address has been updated. On M9K this is done by deasserting clken (dual clock mode) or asserting 'address hold' (single clock mode). I don't know anything about DPRAM blocks. --- Quote End --- Can you point me to the documentation where this is elaborated? Thanks a lot!
If you just detect a change to a memory location it wont matter if the value is being updated at the same time.If you need the new value, keep reading it until you get the same value twice. I don't think the way the nios accesses tightly coupled memory is documented anywhere. We worked it out from signaltap traces.