Forum Discussion

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

How to identify if your design has a race condition.

I am currently working on a CPU and I managed to make it run an sequence of instructions (All it does is add 1 to a register and then store it into a memory mapped device which controls LEDs on my FPGA board and repeat) properly in modelsim however when I put it into a qsys system I have issues. I connect the CPU to an Onchip RAM component (through QSYS) which is preloaded with the same instructions.

When I loaded the design onto the FPGA I noticed that the LEDs increment for a VERY short time (Several microseconds or so) and then freeze. If I reset the System it will do the same thing but it will freeze at a different time. I tried using a ROM megafunction instead and I placed it inside of the CPU and it works perfectly fine. This led me to believe that there is an issue with the communication between the CPU and the Memory unit more specifically a race condition Is there any way to check if there is a race condition going on?

EDIT: In some compilations the LEDs will always be in the reset state which makes me believe that it is a race condition and the duration can be affected from the fitting stage.

17 Replies

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

    I am using a Altera on-chip rom for my instructions. I am having proof of the CPU executes the instructions as it does write to my memory mapped device (when loading to FPGA), however it stops before it is supposed to finish all of the instructions. In modelsim my CPU has the waitrequest signal on for my entire gatelevel simulation (100 microseconds). I am not sure if it is the fault of modelsim or of the CPU.

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

    Could you show a capture of your memory signals in Modelsim? 100μs is very long. Is it the wait request from the ROM of the other memory? Are you sure the CPU is trying to access a valid address?

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

    --- Quote Start ---

    Could you show a capture of your memory signals in Modelsim? 100μs is very long. Is it the wait request from the ROM of the other memory? Are you sure the CPU is trying to access a valid address?

    --- Quote End ---

    It is the wait request from my On-chip rom. It is accessing the proper address. Here is the output: https://www.alteraforum.com/forum/attachment.php?attachmentid=6709

    Test_write is the wait request signal.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I would connect your cpu directly to a dual ported internal memory block (use the other port for everything else) then you don't need to worry about wait states (generated by the memory block).

    The memory will do a read every clock - the 'data out' is valid in the cycle following the address.

    For writes the address, data and write enable are valid in the same clock (a read happens as well).

    If you are pipelining reads (as the nios does) then you end up having to add a wait state when a write follows a read.

    There is also a clock enable/address hold signal, the nios uses this to keep the correct address valid when the cpu stalls because the previous cycle stalls on the avalon bus - since the address gets updated by the following instruction.

    If you use signaltap to watch a nios cpu accessing tightly coupled data memory, you see that it does the read cycle regardless of the opcode value.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I would connect your cpu directly to a dual ported internal memory block (use the other port for everything else) then you don't need to worry about wait states (generated by the memory block).

    The memory will do a read every clock - the 'data out' is valid in the cycle following the address.

    For writes the address, data and write enable are valid in the same clock (a read happens as well).

    If you are pipelining reads (as the nios does) then you end up having to add a wait state when a write follows a read.

    There is also a clock enable/address hold signal, the nios uses this to keep the correct address valid when the cpu stalls because the previous cycle stalls on the avalon bus - since the address gets updated by the following instruction.

    If you use signaltap to watch a nios cpu accessing tightly coupled data memory, you see that it does the read cycle regardless of the opcode value.

    --- Quote End ---

    I will look into it. I should change my CPU, since it expects the memory to be there on the same clock cycle that it is needed. I don't have caches so I guess I need to stall my CPU every time the access is needed.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    This is really strange. Are you sure the ROM isn't shared with any other master? Do you keep the read signal up all the time wait request is asserted? I don't see any reason why an on-chip ROM would maintain the wait request signal asserted for so long.

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

    --- Quote Start ---

    This is really strange. Are you sure the ROM isn't shared with any other master? Do you keep the read signal up all the time wait request is asserted? I don't see any reason why an on-chip ROM would maintain the wait request signal asserted for so long.

    --- Quote End ---

    I keep the read signal asserted all of the time. It may be caused by some issue related to compiling the QSYS system.