I have written a verilog code and RTL simulation is working fine. After this I synthesized the design using XST tool in Xilinx ISE 13.2. The post-synthesis simulation is showing some unexpected results. I don't know what went wrong as there were no warnings during simulation. What should I do now? Is there any way to debug post synthesis level netlist? How can I know what my synthesis tool (XST) is doing with my design? I have included part of my source code. It is for control FSM of my design.
always @ (posedge clock)
begin
case (state) // s0, s1, s2, s3, s_reset are parameters
s_reset:
begin
if(start_proc)
state <= s0;
else
state <= s_reset;
end
s0: begin
pixel_value <= dataOut_bigimage;
pixel_ref <= dataOut_smallimage;
j <= j+1;
if(j==1'b1)
i <= i+1;
if ({i,j} == 2'b11)
if(base_col == 3'b101)
begin
base_row_prev <= base_row;
base_col_prev <= base_col;
base_col <= 3'b000;
base_row <= base_row+1;
end
else
begin
base_col <= base_col+1;
base_col_prev <= base_col;
base_row_prev <= base_row;
end
state <= s1;
end
s1: begin
if (pixel_value <= pixel_ref)
accumulator <= accumulator+1;
else
accumulator <= accumulator;
if({i,j} == 2'b00)
state <= s2;
else state <= s0;
end
s2: begin
if (accumulator > 2'b01)
begin
matchcount <= matchcount+1;
rowmatch[matchcount] <= base_row_prev;
colmatch[matchcount] <= base_col_prev;
end
accumulator <= 2'b00;
if (base_row == 2'b11)
state <= s3;
else
state <= s0;
end
s3: begin
task_done <= 1'b1;
state <= s3;
end
Every thing inside the always block is of reg data type and is properly initialized in a separate initial block
Thanks in advance
-
\$\begingroup\$ What's your definition of a 'random result'? \$\endgroup\$Tim– Tim2013年03月29日 18:45:32 +00:00Commented Mar 29, 2013 at 18:45
-
\$\begingroup\$ @Tim, it's not same as the one I got in behavioral simulation. My problem is I can monitor only top level ports of my design after synthesis. So all I can tell is, my design is not working after synthesis :( \$\endgroup\$Akash Singh– Akash Singh2013年03月29日 18:51:31 +00:00Commented Mar 29, 2013 at 18:51
-
\$\begingroup\$ I'm not aware of any 'standard way' to debug a post synthesis netlist other than to put on your engineer hat and start trying to work backward through the design to see where it's going wrong. Don't know about the specifics of your tool, but perhaps theres a way you can add keep nets to key signals in your design and see if they are behaving properly. You say that you can only see the top level ports, is there a reason why you cannot run the simulation against your synthesis netlist and dump the full waveform? \$\endgroup\$Tim– Tim2013年03月29日 18:55:01 +00:00Commented Mar 29, 2013 at 18:55
-
\$\begingroup\$ Also I don't know if this is a 50 gate or 500,000 gate synthesis, but if your project is small perhaps you can add the source and someone can look for obvious problems like latches or possibly x-prop issues. \$\endgroup\$Tim– Tim2013年03月29日 18:55:56 +00:00Commented Mar 29, 2013 at 18:55
-
\$\begingroup\$ @Tim, the netlist is in terms of FPGA primitives. So I cannot understand its meaning. Moreover, I don't think there are issues likes latches because XST shows warnings for such problems. I am adding the source here. Let's see if someone can help. \$\endgroup\$Akash Singh– Akash Singh2013年03月29日 19:05:04 +00:00Commented Mar 29, 2013 at 19:05
5 Answers 5
Add (and use) a reset signal.
Xilinx FPGAs have a global set/reset (GSR) signal that puts all registers in the their default state or as specified in the register declaration (this is documented in the XST User's Guide at the beginning of chapter 5). AFAIK, the @initial block is ignored.
However, things are chaotic when the FPGA starts up, because:
- The GSR is asynchronous.
- PLLs are not locked
- Not all PLLs lock at the same time
- There are race conditions everywhere
So the initial Flip-Flop values after the GSR are not enough.
Create a module that generates a reset signal for each clock domain. You can create it by by AND'ing relevant asynchronous reset signals, such as an external reset pin, PLL/DCM locked signals, and using it with a synchronizer, as follows:
Reset Circuit
(Source: How do I reset my FPGA?)
Here's one bit of your code that might trip up someone new to Verilog:
j <= j+1;
if(j==1'b1)
i <= i+1;
if ({i,j} == 2'b11)
...
In this code, the j
used for the comparison (if(j==1'b1)
) is the old value of j
, not the newly incremented value. But I suspect you already knew this, and at any rate if this was your problem, you would have seen it in the behavioral simulation (unless you were using blocking assignment like j = j+1
when you did the behavioral simulation).
Another odd thing about your code is that once you get to state 3, you're stuck. You didn't provide any mechanism to return to the reset state or to state 0, which is an unusual design, but also doesn't sound like the problem you're asking about.
-
\$\begingroup\$ Actually, it is the old value of j that I am intending to compare in if statement. So, that's not a problem. Also, my design enters state 3 when my task is complete. So it is supposed to be stuck there \$\endgroup\$Akash Singh– Akash Singh2013年03月30日 05:26:58 +00:00Commented Mar 30, 2013 at 5:26
Apparently, there is a tool-specific feature allowing initial blocks to be synthesized in your case. I wasn't aware of that when I wrote this. I wonder why they would add that feature, because it would just encourage bad coding style. A Power-on-reset mega-function would make more sense. So take this answer as general advice.
Every thing inside the always block is of reg data type and is properly initialized in a separate initial block
Initial blocks are usually not synthesizable. Although some tools may correctly implement the initial block, it is not advisable to rely on this behavior for portability reasons. For example, if you switch tools, it may break your design. You should not use them in blocks you intend to synthesize in general, as the pre-synthesis and post-synthesis behavior might not match.
Your block has no reset signal, and usually this means there is no initialization in hardware. To fix this problem, add a reset signal and a reset condition to your code. Then, place the contents of the initial block into the new reset condition block.
-
2\$\begingroup\$ While I agree with your advice about synthesizing initial blocks, I've found that they can be used with Xilinx tools and FPGAs. Xilinx FPGAs go through an internal reset and programming sequence, and it's possible to initialize registers as part of that process. \$\endgroup\$Joe Hass– Joe Hass2013年07月12日 11:03:49 +00:00Commented Jul 12, 2013 at 11:03
-
\$\begingroup\$ @Joe Where did you find that initial blocks are used during synthesis? From what I understand, only the value specified in their declaration is used. \$\endgroup\$apalopohapa– apalopohapa2013年10月02日 20:49:48 +00:00Commented Oct 2, 2013 at 20:49
-
\$\begingroup\$ @JoeHass, using reset is still the preferred route, because relying on tool-specific behavior like that causes portability problems. \$\endgroup\$travisbartley– travisbartley2013年10月03日 08:23:40 +00:00Commented Oct 3, 2013 at 8:23
-
\$\begingroup\$ @apalopohapa I couldn't cite a reference for you, but I teach digital design using Xilinx tools and some students use initial blocks in synthesized code, despite my warnings not to do it. To my suprise, it worked. I think it is because the Xilinx chips inherently generate a global power-up reset. \$\endgroup\$Joe Hass– Joe Hass2013年10月03日 10:56:18 +00:00Commented Oct 3, 2013 at 10:56
-
\$\begingroup\$ @trav1s As I said originally, I agree with your advice. However, saying that they are unsynthesizable is not strictly correct. \$\endgroup\$Joe Hass– Joe Hass2013年10月03日 10:57:30 +00:00Commented Oct 3, 2013 at 10:57
I would advise you to have a combinational block and move all the control logic there and only keep the data transfer logic in the sequential block. I haven't run your code, but I feel that in the case of the state being s0, your two if conditions (if j==1'b1) and (if {i,j} == 2'b11) might be colliding with each other. In a normal behavioral simulation, the tool simulates the design without no delays. However, after synthesis, the delays get added to the design and may cause the "random result" problem that you are seeing.
-
\$\begingroup\$ Might agree with your assessment to split up the logic a little more cleanly, but I can't think of any problem that could be caused by the two
if
statements that you pointed out. They wouldn't be 'colliding' in any way that I can see. \$\endgroup\$Tim– Tim2013年03月29日 21:10:40 +00:00Commented Mar 29, 2013 at 21:10 -
\$\begingroup\$ I have included many registers in the top level block just by defining reg's and assigning them values in the always block shown in the code. Is that the problem?? Should I define these reg's in separate modules and then instantiate them in the top level block? \$\endgroup\$Akash Singh– Akash Singh2013年03月30日 05:30:20 +00:00Commented Mar 30, 2013 at 5:30
-
\$\begingroup\$ I agree with this advice. Your coding style is very dangerous. Separate the combinational logic into its own procedural block with blocking assignments. The clocked procedure should do nothing more than state <= nextstate; \$\endgroup\$Joe Hass– Joe Hass2013年03月30日 19:36:52 +00:00Commented Mar 30, 2013 at 19:36
-
\$\begingroup\$ @JoeHass This procedural block is mainly sequential. I am assigning values to reg data types depending upon some input signal. Splitting it would mean defining some register modules with Load Enable inputs and controlling these Load Enable signals from this block. But then won't it be like designing from schematics. \$\endgroup\$Akash Singh– Akash Singh2013年04月01日 10:06:40 +00:00Commented Apr 1, 2013 at 10:06
-
\$\begingroup\$ @Tim, my bad. I missed out on the fact that OP is incrementing j nonetheless. \$\endgroup\$Spartan_Xtreme– Spartan_Xtreme2013年04月08日 21:07:25 +00:00Commented Apr 8, 2013 at 21:07
I did not find any mention about initial
blocks being the proper way of initializing registers value in XTS User's Guide.
On the other hand, I found the following statement on page 109: "Since initial blocks are ignored during synthesis, only always blocks are discussed".
Well, it seems that your synthesis tool does not support registers' initialization in initial
blocks. You have two options:
- Define a proper reset signal and use it to initialize your design (see other answers for more elaborate explanations)
- Use the supported syntax for initialization with internal reset (page 104):
reg [3:0] arb_priority = 4'b1011;
In general, I strongly advice you not to use initial
statements for initializations of values (except for initialization of SRAM contents and initialization of testbench signals).
Explore related questions
See similar questions with these tags.