Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Concurrent writes in multi-ported memories

Hello,

Do Altera FPGA s have a mechanism to handle concurrent writes? From what I could find from the documentation if both ports try write to same to the same address in the same clock cycle, the value at that location is undefined and it stays that way until one of the ports can write to the location.

I am trying to design multi-ported memories which can handle write conflicts and wanted to know if Altera already has something on this because I was unable to find information on this.

Thanks.

19 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    But I am confused over one thing. Won't the software code using synchronisation mechanisms make sure that writes are not issued to the same physical address in the same clock cycle? If it is resolved at the software level itself , why should we bother trying to add hardware features to resolve it?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    But I am confused over one thing. Won't the software / Operating system make sure that writes are not issued to the same physical address in the same clock cycle? If it is resolved at the software level itself , why should we bother trying to add hardware features to resolve it?

    --- Quote End ---

    Multiple-processors = Multiple-operating systems.

    The operating systems on two completely disparate machines, eg., an x86 running Linux and a DSP running uCOS-II do not have any way to stop a simultaneous write to a location that they both have in their address map. The x86 host can post a write to the PCI bus at the same instant the DSP performs a write, and although the bus arbiters in a system will ensure there is no electrical conflict when writing to a device such as SRAM, the arbitration logic will not guarantee which order the writes occur.

    Bottom line is you need an interlock between the operating systems on the processors and the interlock needs to be provided by the hardware.

    Cheers,

    Dave
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have two nios cpu that can access the same M9K memory.

    One cpu accesses it as 'tightly coupled data memory', the other as an avalon slave (the original plan was to tightly couple it to both cpu, but being able to directly read it over the PCIe is very useful for debug and post mortums).

    Most of the locations are only written by one of the cpus - but often read by the other.

    I use a modification of Dekker's algorithm when two values have to be modified together (modified because one of the cpu can only do a try_lock() action).

    But I know I have a lurking bug because there is one location which can potentially be written by both cpu - but neither does it very often at all. Fixing is difficult because I can't spin due to real-time constraints.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    But I know I have a lurking bug because there is one location which can potentially be written by both cpu - but neither does it very often at all. Fixing is difficult because I can't spin due to real-time constraints.

    --- Quote End ---

    In your case (since you have one location, infrequently accessed), would it be simpler to avoid the simultaneous write issue altogether and use altera_avalon_mutex as a special case?

    It is a little bit broader topic than the dual port undefined contents being discussed in this thread, but NIOS (Qsys fabric) is missing atomic exchange which would be useful in your case (and others).

    It would be relatively minor to get a workable solution to that using a custom instruction and conduits to guarantee the "atomic" aspect. For example, LOCK/UNLOCK primitives to guard your mutex try_lock() code.

    Not elegant, but kind of easy to implement.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have a 4W/8R port memory built from dual port block rams as building blocks ( built using the techniques published by an author) . The code is written in verilog and in the test bench, I specify the 4 write address, 4 write data and the read address to check if I am getting the read data after correct number of clock cycles. Now to solve the issue of concurrent writes , I can just put a comparator circuit before the memory which will

    1) compare the addresses being written in to the memory.

    2) If the write addresses match compare the data being written. If all the ports are writing the same data then there is no problem. But if the data is different then then use either priority (assigning a static priority to port is easy. But I haven't thought of how assign a dynamic priority) or some other technique to select only 1 port and write that data.

    Then I can synthesize this design in Quartus. Is this idea sensible?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Is this idea sensible?

    --- Quote End ---

    No. :)

    Provide a use-case where all four devices will write, and describe who should win, i.e., which write port should write.

    If the priority is static, then address comparators and an if statement is probably sufficient.

    If the priority is dynamic, then you would need a 4-bit register to determine "who gets to write next", eg., a shift-register with 1 bit set, that gets shifted once the writer corresponding to that bit gets to write, would be a round-robin scheduler.

    Although you can conceive of how to do this, its still not clear *why* you want or need to :)

    Cheers,

    Dave
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    2) If the write addresses match compare the data being written. If all the ports are writing the same data then there is no problem.

    --- Quote End ---

    I don't think it's necessary to check the data being written unless you intended to separately accumulate statistics or otherwise report the collision. The match vs. not has no impact on how you actually process the pending writes (just always write whatever your chosen priority master is writing, and if it happens to match what everybody else wanted to write, fantastic).

    As far as priority goes, static priority based on port is probably simpler to implement and simpler to explain to a 3rd party using your module. This shouldn't be a frequently exercised piece of functionality, so minimizing the resources/time devoted to it is probably a good idea.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Although you can conceive of how to do this, its still not clear *why* you want or need to :)

    Cheers,

    Dave

    --- Quote End ---

    Hello Dave,

    Is your question - Will simultaneous writes to the same location be issued in the first place? I had the question when I asked in one of my earlier posts where the software itself can resolve the issue using synchronization techniques and there would be no need to think of a hardware feature to implement this. If we consider 3 scenarios :

    1) A single NIOS processor [This my present case where I am using a Cyclone iv fpga]

    2) A multi-core processor

    3) A multi-processor.

    Do you mean to say if a single machine has any one of these processors there will not be any write conflict? I understood the case of 2 disparate machines with 2 different OS s access the multi-ported memory.

    One more query I have is - Kindly take a look at the attachment. So that is the 4w8r memory at a particular depth. So now the chip has a 4w8r memory and there are the rest of the M9K block rams available for use. How will the system know when it has to acccess this 4w8r memory and not the other block rams? Are separate instructions needed to specify that the 4w8r memory has to be accessed?

    I am so hazed with all these questions right now!! Any help will help me understand things better.

    Thanks.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    So now the chip has a 4w8r memory and there are the rest of the M9K block rams available for use. How will the system know when it has to acccess this 4w8r memory and not the other block rams? Are separate instructions needed to specify that the 4w8r memory has to be accessed?

    --- Quote End ---

    Your (larger) system would need to instantiate and make explicit connections to your new 4w8r module. It is not possible to, for example, extend Quartus synthesis to infer your new memory the same way you can write HDL to infer single/dual-port M9K.

    Since you have mentioned NIOS a couple times, you may want to go through the exercise of packaging your new module as a Qsys component.