Showing posts with label simulation. Show all posts
Showing posts with label simulation. Show all posts

Friday, August 4, 2017

HDL-FPGA Coding Style Guide

Based on all my years of professional and educational experience I'd like to introduce a document detailing general guidelines for VHDL coding style as well as some related to FPGA architecture. 
Even though I've tried to summarize the most important points, it results in a lengthy documentbut it still is useful when starting a new project, or as a reference for coding in HDL (VHDL or Verilog) / FPGA.

Link to the document is as follows. ..... ;) ......

Suggestions are welcome in case any of you have a 'guide/point' that I've missed in the doc.

Have a GrAt DaY ! 

Saturday, January 31, 2015

"Warning: NUMERIC_STD, "=": metavalue detected, returning FALSE". ISim, Xilinx

Introduction 

Whenever it’s possible I avoid using ISIM (the ISE embedded simulator). Among other things, it has poor support, and also very encrypted Warnings and Errors messages. In the last project I worked, I had no choice but using ISim, and when I was finishing the top level simulation I got the famous warning "Warning: NUMERIC_STD," = "metavalue detected, returning FALSE". And I say famous, because I goggled it in the web and found many entries, but almost none gave me an idea of what happened and even less how to fix it. Well, that is the reason I’m writing this post, to tell you what this means and at least one concrete way to find a clue where or how this Warning is generated.


What is it "Metavalue Detected" ? 

This message means that the simulator encountered as a result of an expression a non-numeric value, which can be for example "UUUU" or "XXXX" or some other value.
Commonly this result is obtained during the initialization of the system under test, and depending on the type of test it can repeat this message periodically or just once. As an example,  in the following figure you can read the messages I got during my simulation.


How to find the source of the warning message? 

As it can be seen from the figure shown above, there is nothing that looks "rare/strange" in the waveform of the various signals shown, so that, the solution is not at simple sight.

One way to find the source of this warning message, at least in this particular case that I’m showing you, it is to try to see the different internal signals of the whole system described in VHDL. To do this, go to the panel called "Instance and Processes" and click on the arrow that is next to the test bench, show in the figure above, click on the arrow next to top_tb. The name of the instance of the component under test in the test bench appears, in this case I called 'uut'. Again click on the arrow that is next to 'uut' and the various sub-components of the system are now listed. The following figure details what it was explained.


The next step is to select each sub-component and adding the different E/S and internal signals to the waveforms window (Wave Window). Select a sub-component by simply click on its name, then in the 'Objects' panel all the E / S and internal signals  of this sub-component appear. Then select all signals (because we do not know which one is malfunctioning), and add then to the Wave Window.
The following figure details the steps explained.




In the figure above, I have added to the Wave Window all the signals of the cont_4bits_1 sub-component. I can also add the signals of the other sub-components, freq_div_1 and bcd_7seg_1, but it happened that just adding the signals of cont_4bits_1, I found part of the problem. How? ... Well, once I added the signals of this sub-component, I run the simulation again, and immediately I visualized something that caught my attention .... what was that? .. well, try to find it out by yourself in the following figure.:



What do you see weird ???? .......

Yes ! ( I guess you found it out J )…  the last two signals, count and i_count, are not defined ('U' = undefined) .... We found something! ....

Possible Solutions

Now I come to this point, the steps to follow are two:
1) review the VHDL / Verilog subcomponent cont_4bits_1, and check especially initializing the count and i_count vectors.
2) review the bench test and verify the value given to the signal that initializes the system, commonly called reset.
In one of the two sides is the origin of Warning, and the solution to work with .....! ... (In my particular case it was a no well defined reset value in the test bench....).

Finally a note for those using ModelSim, you can read in various forums that ModelSim has an option for this type of Warnings (based on 'metavalues') that allow you to ignore them. Of course I DO NOT share that view, because it is always good to know the origin of the Warning. In my particular case if I had used ModelSim and had used the option to ignore these Warning, I had never encountered the problem that I found with the reset signal. . .

Well, I hope you find it useful ... reminded me if so!

See you soon ...


Wednesday, August 21, 2013

Delta Time 'View' in ModelSim

Introduction


For some people learning the language the concept of delta time is one of the most tough to understand. It's not the objective of this article to discuss about delta delay, but to let you to know the tools available in ModelSim to 'see' the delta delays.

How to 'see' the delta delays

I'll explain in few steps the procedures to follow to find out how many delta delays happens until a signal has an stable value.
First, here is the simple code I'll use

 1 library ieee;
 2 use eee.std_logic_1164.all;
 3
 4 entity aoi is
 5 port(A, B, C, D: in std_logic;
 6      E         : out std_logic);
 7 end aoi;
 8
 9 architecture beha4 of aoi is
10 signal O1, O2, O3:std_logic;
11
12 begin
13 b4: process(A, B, C, D, O1, O2, O3)
14  begin
15   E  <= not O3;
16   O1 <= A and B;  
17   O2 <= C and D;  
18   O3 <= O1 or O2;
19 end process b4;
20 end dflow1;


and this is the simple test bench used

 1 library ieee;
 2 use eee.std_logic_1164.all;
 3
 4 entity aoi_tb is
 5 end aoi_tb;
 6
 7 architecture test of aoi_tb is
 8 signal O1, O2, O3   : std_logic;
 9 signal a, b, c, d, e: std_logic;
10 component  aoi is
11   port(A, B, C, D: in std_logic; E: out std_logic);
12 end component;
13
14 begin
15    a <= '0', '1' after 6 ns;
16    b <= '0', '1' after 5 ns, '0' after 8 ns;
17    c <= '0', '1' after 7 ns;
18    d <= '0';
19
20 uut: aoi  port map(
21   E => e, a => a ,b => b ,c => c, d => d
22   );
23 end test;
24


Once you have executed the test bench, the Wave window will show the respective waveform, as you can see in this figure (a point to keep in mind is that you will likely have to add the internal signals, in this case O1, O2, O3, to the Wave window):


So, if you want to know the delta delays that happened at the simulation time 8 ns, you have to: 
1- Place a cursor on the 8 ns simulation time.
2- Click on the 'Expanded Time Delta Mode" button


3- Click on the "Expand Time at Active Cursor" button

4- Click on the "Zoom In At Active Cursor"

5- ReAdY !

The following figure details the above steps and the expected result.


Other way

ModelSim offers another way of seeing the delta delay. In the 'View->List' option, the signals and their respective events and delay are detailed in a table. 
The following figure is the respective 'list' of the above case. 



FINALLY

So, if you ever had doubt on how the delta delays works, here is an easy way of find it out !. 

See you soon.... 

Thursday, July 18, 2013

Quartus-ModelSim: How to customize the waveforms to facilitate the debug

In a previous blog I described how to customize the waveforms in ModelSim in the Xilinx ISE environment. Due to the request of many of you, I now describe the waveform customization for the Altera Quartus users.  
As you'll read in the application note that I present; when invoking any simulation (functional or gate level) from the Quartus environment, ModelSim is automatically started up, displaying the waveforms resulting from the test bench in the panel called Wave View. Due to the ModelSim's settings (detailed in a script file) by default, only the entity signals are displayed in the waveform viewer, no other signal ... So, once opened this Wave View window if you wish to display internal signals of the design under test, or change the position and / or color of the signals, or add dividers, and many other features offered by ModelSim, you can do it (following certain steps explained later), but once you close ModelSim all modifications are lost!. Hence, when you run the same simulation again, you must start again with the modifications. The problem sound familiar?????

In the 'Application Note' that I present here, I detail the steps to follow, so that when you invoke ModelSim from Quartusthe Wave View will contain all the information you set and saved for proper verification and easy debug.

Here is the link to download the 'Application Note'AN-08 C7T

Until next time!

Saturday, August 4, 2012

ISE-ModelSim: How to Customize the Wave View Window

In case your simulation is executed using ModelSim, when you invoke any kind of simulation within the ISE environment, ModelSim is automatically opened. By default one of the window that comes up is the Wave View window. In this window only the top entity signals are shown, and ... no any other signal ... So if you want to see internal signals of your design, or maybe you want to change the position and/or color of a signal, maybe you want to add dividers,or utilize many other features offered by ModelSim, you can do that in the window that is automatically opened, but. . . any change in the Wave View window will be kept until ModelSim is closed. When running the same simulation again, you should start with the changes that you want once again from scratch.

I've written a kind of application note that describes the necessary steps to follow, so when you invoke ModelSim from ISE, the Wave View will open (keep) any change you have done to the initial (default) window, containing all the information you want/need for proper verification and easy debug:

C7T AN-05

Happy design!

Saturday, July 7, 2012

Combinational Loop

Introduction

Combinational loops are logical structures that contain no synchronous feedback element. This kind of loops cause stability and reliability problemas,  as we will see in this article, violating the synchronous principles by making feedback with no register in the loop.

Why? How? is generated a combinational loop? 

Basically, a combinational loop es implemented in hardware (gates) when in the written VHDL code describing combinational logic a signal that is in the left side of an assignment statement (that is, to the left of the <= symbol) it also is on the expression at the right side of the signal assignment statement (right of <=). For example the following lines of code generate a combinational loop, as long as they are written in a combinational process or in a concurrent signal assignment statement.

1 acc <= acc + data;
2
3 Z <= Z nand B;
4
5 cnt <= cnt + 1;


However, it's important to point out that if these same statements are written in a clocked process, each of them will generate the respective sequential logic. This is due to the fact that the signal assignment statement in clocked process will generate a register for the assigned signal, therefore the loop will be registered in this case, therefore no combinational loop is generated.

Hardware

The following figure shows a diagram of a combinational loop. 



As it is shown in the figure, the combinational logic output is fedbacked to the same combinational logic without any register in the loop. The logic between the first input an the last output can be made up of one or several levels of combinational logic. It can also have different signals coming in and coming out of that piece of logic, but at least one of the signal is going back (feedback) to the first logic level, as it can be seen in the following figure.


This kind of logic circuit usually is not desired, no wanted to be implemented. Hence, when the synthesis tool finds out about this combinational loop generates a warning message. 
Here is an example of VHDL code that generate a combinational loop when is implemented.

 1 library ieee;
 2 use ieee.std_logic_1164.all;
 3
 4 entity lazo_comb is
 5   port(
 6     a: in  std_logic;
 7     z: out std_logic);
 8 end lazo_comb;
 9
10 architecture beh of lazo_comb is
11
12  signal y: std_logic;

 
13
14 begin
15     z <= y;
16
17 process(a,y)
18  begin
19     y <= y nand a;
20 end process;
21
22 end beh;


The synthesis tool, Synplify in this case, generates the following warning regarding the combinational loop. 



The warning message "found combinational loop at 'y'" means that the signal 'y' is feed-backed to the input of the combinational logic without any register in the loop. This loop can be easily found when seeing the RTL view of the synthesized system, as it can be seen in the following figure. 


Simulation

The simulation of the system (very simple system) is shown in the following figure. 



The ModelSim windows details a lot of information that deserve a detailed analysis. First of all, the top window plots the waveforms of the signals from the described system, whose main expression is in the line 24 of the middle window. The bottom window, Transcript window, generates an error message, saying that the limit of iterations has been reached at 50ns and no stable value has been gotten. In other words, this mean that the system has began to oscillated and remained oscillating. The maximum number of iterations is configurable in ModelSim (Simulate->Runtime Options); as it's in most simulators. By default this value is set to 5000. Another important piece of information can be found in the bottom of the waveform window. There you can read that the number of Delta reached 5000, which is exactly the number maximum of iterations set in the runtime options, and even after that amount of deltas the system is not stable.
Why this simple logic is oscillating? Well, analyzing the true table of the nand gate, while one of the input is stuck at '0', the output will be always '1'. That is happening in the simulation shown above. Whereas, when the input (signal a in the simulation) tries to change to '1', due to the fact the other input is still at '1' the output change to '0', then since the feedback input is '0', the output should go to '1', then that '1' is going back with the other input at '1', the output will go to '0' again, and so on...This is what is called an "unstable combinational loop". This kind of loop should NEVER be used in a real design.
Other point to bring out on this example is the importance of simulating a system. Assuming that we configured the FPGA without any simulation, based on the fact that the synthesis tool just gave us a 'warning'), we'd see an no stable output, spending some time (maybe a lot of time) trying to find out why the output is not stable. Conversely, by doing the simulation the problem would appear at first shot. 

 Code Style

In designs with a large, very large, amount of code lines it is very easy to make mistakes and generate a combinational loop with no intention (as it can be seen in the example above). So, follow certain order when writting the code, trying to maintain a certain flow of data. Also, take a close look at the warnings generated by the synthesis tool. 
In case you deliberately want to implement a combinational loop, write a detailed description of the reason for doing that, and also write a comment in the constraint file. The reason for this last point is due to the fact that the Static Timing Analysis tool (STA) usually increase the minimum period of the system when it founds a combinational loop. Therefore, in this case you should tell to the STA tool to 'ignore' that particular path. The syntax for ignoring a path is 'set_false_path' for the Quartus (Altera) software, and for the ISE (Xilinx) you should use TIG with its resepctivs syntax in both cases.