Sign in to follow this  
zygot

Tales from the Trenches ( with apologies to WWI veterans )

Recommended Posts

If, like me, you do any significant FPGA development and in particular designs for a wide variety of devices and more so using devices from most of the programmable logic vendors, you run into "quirks" with the devices and tools that are unexpected and not easily resolved without a bit of luck and determination. A naive view of software development is that if you use a particular language, such as C, then all of the confusion as to what exactly the language syntax implies as regards to behavior and expression of that behavior in all machine code has long been settled. I can assure you that this is not the case. So, as complex as the FPGA tools are it shouldn't be a surprise that you might come upon strange and unexplainable problems. Add to that the occasional bug in any particular toolset and it's not uncommon to run into a wall now or then that should be there.

Since I know of no other venue for having a discussion about this I thought that starting a thread here might be useful. If you are a newbie to FPGA development you might find information posted here useful as well. At least you might develop an appreciation for the complexity of what's behind translating your HDL into working logic.

My hope is that new postings to this thread restrict their scope to presenting out-of-band issues that they've come across and resolved. Mentioning specific devices and toolset versions is important.

I've been thinking about starting this thread about 4 issues ago so if there's any interest I can feed the pipeline for a while.

Share this post


Link to post
Share on other sites

I've been posting quite a few "tales from the trenches" on ZipCPU.com.  Perhaps you've seen some of them?  Here's an article telling of some of the times I've gotten stuck.  Another article discusses reasons why simulation might not match the hardware implementation.  You can read here about one of the uglier bugs I've come across, or here regarding about all the bugs I found, and have since fixed using formal methods, in the ZipCPU.  Another fun one was a student's response to one of the articles I'd written, telling his tale from the trenches.

In general, though, I embed most of my tales from the trenches stories into topical articles.  For example, here's a fun recent one on how to build an SPI controller--including a discussion of how I had to work through a timing issue with the final SB_IO pin controller in an ODDR type of mode.  (That vendor doesn't call it an ODDR, but that's the mode the I/O was placed within.)

Perhaps that'll get the discussion going for you?

Dan

Share this post


Link to post
Share on other sites

Tool: ISIM

ToolSet Version: P.20131013

Target Device: KC7K325T-2GFG200C

 

Sometimes, you find a problem with a tool, figure out a resolution, and many months later step back into the same sinkhole again, wasting a few hours, until you remember....


I'm a big proponent of simulation. Of course simulation is only a tool. You can do good (adequate) simulation, bad simulation, useless simulation and simulation that lies to you. It's a form of art as much as anything else; really. It's also, in my opinion essential not only for verification purposes but in developing and exercising your skills as an engineer.

Lately, I've been working with ISE 14.7 Application Version P.20131013, which as far as I know is the very last version published by Xilinx. The sinkhole in question is a quirk in ISE ISIM. My project targets the KC7K325T-2GFG200C device and the KC705 development board from Xilinx. Why would I want to use ISE for a new project? Because I am also using a third party PCIe core that uses ISE. Why create unnecessary problems when toolset versions present more than I care to handle?

My design uses the Ethernet PHY and is mostly a port of code that I've been using successfully on the Spartan 6 based ATLYS development board. I've had no end of nasty surprises doing what I expected to be a rather routine port. I have a considerable number of designs for both of these boards completed so I generally have a good feel for the expected issues. But this post is about ISE ISIM.

It is important to mention how I use FPGA vendor tools. I use my own text editor. I am aware of issues with tools not recognizing when source code has been updated, or worse yet sometimes recognizing when source code has been updated.

The quirk prompting this post has reveals itself when I change source code and relaunch a current simulation. This always initiates a recompile ( if you are observant you will notice that ISIM complies executables of your simulation; no doubt to speed up the actual simulation). Occasionally, I'll make small changes to the source ( either the design or the testbench ) and not see an expected change in logic behavior. If I'm lucky, this happens when I change the testbench and It's fairly obvious that ISIM is ignoring my change. If I'm unlucky, this happens when I change design sources and I can quickly find my way down the rabbit hole conversing with a strange creature. Mostly, this issue for me involves forgetting past experiences and having a general mindset that if things aren't working, it must be me not the tools. Thankfully, it's usually me.

What I keep forgetting, when I've been away from ISE for a while, is that when ISIM simulations stop conforming to a reasonable sense of reality I need to do the following:

  • stop using the Relaunch button in the simulator
  • exit the simulator
  • in The ISE Processes window right-click the 'Simulate the Behavorial Model' process and select Re-Run All.

 This usually restores my sanity, at least for a while.

Edited by zygot

Share this post


Link to post
Share on other sites
4 minutes ago, D@n said:

Perhaps you've seen some of them?

I should have known that you'd be around as I got this thread started. I'm thrilled to see a reply as I submit the first post.

To answer you question; no I haven't but I promise to check out what you've been up to.

If this venue fails to show interest I'd be happy to conspire with you to create one that does.

Share this post


Link to post
Share on other sites

Quartus 15.0.0 Build 145 04/22/2015 SJ Web Edition
Device: Cyclone V 5CGTFD9E5F35C7

Here's the code snippet:

entity AN_ENTITY is
generic (
  num_crtl_regs    : integer := 1 -- the number of 64-bit read/write control registers

------------------
  signal  ctrl_offset         : integer; -- Quartus can't figure out what to do with this
--  signal  ctrl_offset         : integer range 0 to (num_crtl_regs*64)-1; --  to make Quartus happy
  signal  icontrol            : std_logic_vector((num_crtl_regs*64)-1 downto 0);

------------------

  CTRL_DATA_OFFSET_PROC : process(clk, hard_reset)
  begin
    if hard_reset = '1' then
      ctrl_offset   <= 8;
    elsif rising_edge(clk) then
      if current_state = IDLE then
        ctrl_offset   <= 8;
      elsif current_state = RDATA and ctrl_offset < max_offset then
        ctrl_offset <= ctrl_offset + 8;
      else
        ctrl_offset   <= ctrl_offset;
      end if;  
    end if;
  end process CTRL_DATA_OFFSET_PROC;

------------------
340  CONTROL_REG_PROC : process (clk, hard_reset)
341  begin  
342    if hard_reset)= '1' then         
343      icontrol  <= (others => '0');
344    elsif rising_edge(clk) then
345      if current_state = RDATA and ctrl_write_mask(7) = '1' then
346        icontrol(ctrl_offset-1 downto ctrl_offset-8)  <= phy_data_in;
347      end if;  
348    end if;
349  end process CONTROL_REG_PROC;

------------------  

The error as reported by Quartus:
Quartus Error: Error (10386): VHDL error at NODE_N_SINK_INF.vhd(346): non-constant index is always outside the range (63 downto 0) of object "icontrol"
------------------  

The discussion:     
I love to parameterize my IP because it can make instantiating custom version of it for different requirements of new projects easy. Of course with the flexibility of using GENERICS often comes added complexity. I also love to reuse HDL sources that have been reliable for past projects. You'd think that the same HDL code that works flawlessly** for one device would work for other devices, especially newer devices with better resources. This has not been my experience as a general rule. This has not been my experience especially when it involves devices and tools from different FPGA vendors.

This post is about basic VHDL constructs and how the synthesis tools from different vendors evaluate and implement the same constructs differently. If it's not obvious what the code snippets above are trying to accomplish, here's the idea.

I have an 8-bit input data stream. I have a variable sized output std_logic_vector that uses a variable number of bytes form that data stream to set it's value. Really, it's a variable width shift register that is loaded from an input, which in this case is 8 bits wide. The width of the output is in increments of 64. It should be obvious that this shift register is controlled by a state machine that understands the width of the signal icontrol.  The shift register is a fundamental logic construct that's been around since well before programmable logic. Most synthesis tools will automatically identify this construct in your code, if you allow it to, and synthesize the optimum implementation for the resources of a particular device.

The behavior of the synthesis tools often forms our coding style, for better or worse. A synthesis tool that overlooks our tendency to be lazy and type as few words as possible can also encourage poor HDL coding styles. Really, we don't care if our source is pristine, just that in the end our logic does what we think that it should ( in the limited scope that we bother to care or verify how it does indeed work ). Let's face it most of the time we are behind schedule for a number of things that need to get done..now.

I've used this code for many many Xilinx devices and target boards without issue. The Xilinx synthesis tools evaluate the code and know what it is that I want to do. When I recently tried using the same source for an Intel (aka ALTERA) device I was not pleased to see the error reported above. Curiously, I have previously used the same source for a different device (Cyclone V GX) and didn't get this error.
 
If I explicitly constrain the declaration of the signal ctrl_offset with a range specifier as shown in the commented out line that follows Quartus is happy to synthesize and create a working bitstream for me. 

It took me a while to post this because the error that I remember is one of an unconstrained integer ( well actually I remember my reaction rather than the actual error). Anyway, I wasn't able to find my notes about the details so I just recreated the one above.

Some companies believe that the Xilinx synthesis tools promote bad VHDL coding styles and insist that all designs be "compiled" using Synplicity ( the expensive version ) as part of the verification process. If you want to see Synplicity in action ( a cheaper version ) you can look into ACTEL ( aka Microsemi, aka NXP as of late ???) which has traditionally chosen to use third party synthesis tools.

SIDE NOTE:

works flawlessly**

One definition, the one that I favour, of 'working software' is 'software which hasn't been subjected to the particular testing that exposes a particular flaw. Don't trust anyone who tells you that a piece of software works. At best it works good enough under certain conditions as far as anyone has noticed when concentrating on a limited number of metrics. For FPGA development this premiss is even more true.

Edited by zygot

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this