UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer ofdouglas
Observer
7,502 Views
Registered: ‎05-25-2015

Design Passes Simulation, Fails on FPGA

Hello,

 

My design passes behavioral, post-synthesis, post-functional simulation, and static timing analysis, but it consistently fails on the FPGA.

 

The design is a classic 5-stage MIPS processor. Using the ILA core I can easily see the problem: the "Boot Exception Vectors" and "Kernel Mode" bits in the Status register go to '0'. This leads to an Address Error Exception being serviced at a non-boot exception vector which does not exist in the memory map yet, resulting in an endless cycle of instruction bus faults. The exception mechanism is correct. The question is: why are my Status register bits changing? This does not happen in simulation!

 

cpu_fail.png

 

I do not get any critical warnings in synthesis or implementation. Also, note that my test program is about a dozen assembly instructions, with no dependence on external input - it's simply a loop that tries to toggle an LED.

 

Since it all works fine in simulation (even after extensive testing on different synthesis and implementation strategies, and different versions of the code), I have to suspect that there is a problem with either the clocks or reset mechanism. 

 

I am using a synchronous reset that initializes the program counter and status register, sets the PC to the boot vector, and floods the pipeline with NOPs. This reset is not connected to any external pin; it's simply meant as a guarantee that the CPU is in a well-known state when the Global Set-Reset finishes. My reset is held for 16 cycles of the CPU clock:

 

signal reset_sync : std_logic_vector(15 downto 0) := (others => '1');

...

reset_proc:
  process (clk)
  begin
    if rising_edge(clk) then
      reset_sync <= '0' & reset_sync(15 downto 1);
    end if;
  end process;

...

 mips_cpu: entity work.r3000_cpu
    port map (clk => clk,
              reset => reset_sync(0),

...

The CPU clock 'clk' is a 50 MHz clock generated by a Clock Wizard instance, which is using the 100 MHz external clock provided on the board (a Nexys4 DDR). I have used this board successfully many times before. I also encountered this problem when using the 100 MHz clock directly, without the Clock Wizard. In both cases, I have tripple-checked my XDC file to verify the clock constraint:

 

set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports sys_clk]
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports sys_clk]

At this point I really do not know what else to investigate. I am hoping someone here has some wisdom to share about how to track down this kind of bug, or some ideas about what might be causing it. Thanks for reading!

 

 

0 Kudos
1 Reply
Highlighted
Observer ofdouglas
Observer
7,453 Views
Registered: ‎05-25-2015

Re: Design Passes Simulation, Fails on FPGA

Update: I think the error might be with my clocks. I was trying to read my BRAMs on negative edges and run the rest of the design (including writing the BRAMs) on the positive edge because that seemed closer to the model of asynchronous reads during the IF and MEM stages. I'm not sure that the single clock constraint I used above covers this, though.

 

Changing the BRAMs to Distributed RAM and using an asynchronous read, I now get a warning that 2665 nets (basically the entire design) have multiple clocks. That is clearly not good, but I don't know why it happened, or why it's only being reported now... Every register in the design uses the output from the MMCM (from the clock wizard); the only other clock in the design is the input to the MMCM. I tried resetting and regenerating the Clock Wizard but the results are the same.

 

This is new territory for me, so I'm not sure what I'm looking for, but I noticed that the 'sys_clk' (defined in the XDC file, the port of the top module, and used as input to the MMCM) seems to have an alias named 'sys_clk_pin'.

 

clocks.png

 

What is going on here?

0 Kudos