3
\$\begingroup\$

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

travisbartley
4,9133 gold badges27 silver badges41 bronze badges
asked Mar 29, 2013 at 18:32
\$\endgroup\$
6
  • \$\begingroup\$ What's your definition of a 'random result'? \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Mar 29, 2013 at 19:05

5 Answers 5

2
\$\begingroup\$

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?)

answered Oct 2, 2013 at 19:03
\$\endgroup\$
1
\$\begingroup\$

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.

answered Mar 30, 2013 at 4:26
\$\endgroup\$
1
  • \$\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\$ Commented Mar 30, 2013 at 5:26
1
\$\begingroup\$

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.

answered Jun 12, 2013 at 9:28
\$\endgroup\$
7
  • 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Oct 3, 2013 at 10:57
0
\$\begingroup\$

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.

answered Mar 29, 2013 at 21:00
\$\endgroup\$
5
  • \$\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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Apr 1, 2013 at 10:06
  • \$\begingroup\$ @Tim, my bad. I missed out on the fact that OP is incrementing j nonetheless. \$\endgroup\$ Commented Apr 8, 2013 at 21:07
0
\$\begingroup\$

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:

  1. Define a proper reset signal and use it to initialize your design (see other answers for more elaborate explanations)
  2. 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).

answered Oct 2, 2013 at 19:42
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.