VHDL coding tips and tricks: xilinx errors
Showing posts with label xilinx errors. Show all posts
Showing posts with label xilinx errors. Show all posts

Saturday, December 4, 2010

Tips for running a successful simulation in Xilinx ISim.

Though I have given enough examples for learning VHDL I didn't write much about using the software till now. In this article I will cover some basics about running your simulation in Xilinx ISim. This article will point out some basic mistakes people do when simulating their code in ISim.
For explaining, I have just used one of my earlier example in the post : Explaining testbench code using a counter design. Lets go step by step, see the images for easier understanding of the steps. Open the images in a new tab in your browser if they are not clear enough.

1)Once the coding is done( I mean both the testbench and the design to be tested) make sure you select the top entity(testbench code) in the Xilinx window as shown below. Many people just select any other file and click the compilation button.
Note down the red markings in the image below. Points to be noted are:



  • Choose View  as simulation.
  • Select the top entity i.e. the testbench. If the wrong file is selected for simulation then the waveform in ISim will be blank and you will see no waveform.
  • Double click on the Behavioral check syntax for compiling the design or for finding out any syntax errors.
  • If the above step is successful then double click on Simulate Behavioral Model. If there are syntax errors in step 3 then you may have to check your code.


2)Now ISim will open in a new window with waveforms. Note down the toolbar at the bottom. Check the below image for knowing what each button does. You can also hover your mouse over the button and they will display the function of that button.

3)Mostly the signals in the wavforms will be displayed as binary numbers or integers. But you can change this basic setting. See the image below. 


Click on the signal which you want to change the display format. Go to radix and then select the format. Some options available are Binary, Hexadecimal, octal etc. Note that depending on your code , you have to change the display format. My code was a counter, so unsigned decimal was the best format in this case.

4)Another interesting thing you can do is adding the internal signals to the waveform which is not displayed by default. By default ISim displays only the signals which are declared in the testbench code. But if there are many sub entities then you may need to see them for debugging purpose. See the image below for how to do it.


  • Go to the Instance and process names on the left side of the ISim window. 
  • Select the Instance name whose internal signals you want to observe. 
  • All the signals declared in that particular instance will be displayed on the immediate right tab now, under simulation objects.
  • Now select the signals you want to display. You can use keyboard short cuts like shift  and Ctrl for selecting multiple signal names.
  • Now drag and drop these select signals into the immediate right tab under signal Name in waveform window.
  • For updating these signal values you have to restart the simulation and run it again. 


5)You may have noticed that in ISim, all the additional signals you added in step (4) are reset when you close the ISim window. This is little bit annoying since you have to add all the internal signals again. But you need not worry about it. Follow the steps:

  • Add the required signals into the waveform as described in step 4.
  • Save the waveform file by clicking, Ctrl + . Give an appropriate name to the wave file.
  •  Now close ISim and go back to the Xilinx ISE window.
  • Right click on simulate behavioral model. 
  • Choose the option Process properties.
  • A new window will open as shown below in the image.
  • Select the check box, Use custom waveform configuration file. 
  • Choose the waveform file you just saved in the  custom waveform configuration file.







Thats it for now. Hope these explain the things better. Thanks.

Friday, March 5, 2010

VHDL: Can you change a signal at both positive and negative edges of the clock?

Consider the following code:

signal c : std_logic_vector(3 downto 0):="0000";

process(clk)
begin
    c <= c +'1';
end process;

This code is supposed to work as a simple 4 bit counter, counting at both negative and positive edge of the clock. The design works perfectly at the simulation level. But when you synthesize this code you will get the following warnings :
WARNING:Xst:647 - Input clk is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c4.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c6.
WARNING:Xst:2170 - Unit test : the following signal(s) form a combinatorial loop: Madd_c_cy<0>.
Normally most of the warnings can be neglected during synthesis without posing any critical problems. But in this case, the warning "the input clk is never used" cannot be ignored. The synthesis tool was unable to find the right resource in the fpga for the logic we wanted to implement. So it simply ignores the clock signal and surrounded logic and synthesizes a combinatorial circuit.

Lets modify the first version of the code above and see if we can make it work. 

process(clk)
begin
    if(rising_edge(clk)) then   -- for posedge
        c <= c +'1';
    end if;
    if(falling_edge(clk)) then  --for negedge
        c <= c +'1';
    end if;
end process;

It seems no! We still get a synthesis error.
Signal c cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.
The second version clearly shows that it is not possible to change a signal at both negative and positive edges of the clock. Xilinx ISE either synthesizes it in a different way or it gives an error.

One reader asked in the comment section, why does the following code synthesis correctly?

PROCESS(A, B)
BEGIN
    if A = '1' then
        C <= B;
    else
        C <= (others => 'Z');
    end if;
END PROCESS;

The answer is that in the above code, we are not trying to implement a sequential circuit, but a combinatorial circuit. On the simulation level, any change in A or B will trigger the PROCESS. And on synthesis level, the circuit is implemented using a LUT(look up table) rather than flipflops. 

Sequential circuits are edge triggered while combinatorial circuits are level triggered. And most of the fpga doesnt have flipflops which can be triggered on both edges of a clock.