Sometime over the course of the past few weeks, I decided that it was finally time (actually quite a bit past time) to step out of the physical hardware world for a moment and learn how to work in the virtual world by means of a software simulator.
This means that, as opposed to implementing and running my designs in a physical FPGA, I will instead use a simulator to mimic what will happen when I apply stimulus to the inputs to my designs. There are a number of software simulation options available on the market, but I’m starting with what I’ve got, which is the Xilinx ISE Simulator (ISim). Step one is to make myself a pretty bad-tasting Latte (bad wasn’t my intention, but that’s definitely what I ended up with today).
Xilinx has a VHDL simulation tutorial for their ISE (integrated software environment) version 12.4, which is what I have. Yes, it's true that Xilinx sponsors All Programmable Planet (APP), but that doesn’t mean I’m not genuinely pleasantly surprised once again with their tutorial set -- I am.
In my experience with chip companies, most of them seem to have documentation or a tutorial for an older version of a different language on some other version of the chip I need to use. They tell you: “Sure, it’s exactly the same, only a whole lot different.” Fortunately, I don’t have to worry about that here.
The tutorial uses a Vertex-5 chip, but the only change necessary will be to select the Spartan-6 FPGA I'm currently using in the project settings. To get the tutorial documentation and files, go to: “ISE Simulator (ISim) In-Depth Tutorial” on this web page. You'll find it just a little bit down from the top. Un-zip the design files into your Xilinx code directory and open the PDF. The tutorial covers using the simulator from within ISE (which I am going to do) and from the command-line (which I am not going to do).
As far as I can tell, the steps involved are as follows:
Write your VHDL (or Verilog) code
Write a testbench
Compile everything
Fuse it
Run the simulation executable
The tutorial example uses the Digital Clock Manager (DCM). I’ve fiddled with the DCM before, so that concept isn’t entirely alien to me. The concept of a testbench is, however, somewhat alien. Not totally though. I’ve read enough about testbenches here on APP; if I think in terms of hardware, I would assume that I’m creating hardware that will give my code specific inputs so I can examine the outputs based on those inputs.
So read the tutorial down through Page 13, as I have, and then start up ISE. Create a new project, as instructed. The "Project Settings" dialog box will differ from the tutorial, unless you happen to be using a Virtex-5 chip. For my Spartan-6 LX9, it will be as illustrated below (click here to see a larger, more detailed version of this image):
Otherwise, everything I’m doing matches the tutorial PDF... until we reach Page 22. The first step on Page 22 says: “In the Design Panel, select Behavioral Simulation from the dropdown list.” The problem is that I don’t have a dropdown list as illustrated below:
Quick... did you spot my "deliberate" mistake? I’ll give you a hint; it’s a pretty basic mistake. I don’t know if I missed an instruction, or if the tutorial's creators simply assumed that no one could possibly mess this up, but at the top of the dialog I have the “Implementation” view selected. I need to click the radio button for “Simulation” to get my drop-down list to magically appear. Doing this put me back on track on Page 23 with only about a five minute delay.
The end result of the tutorial on my monitor exactly matches the screen capture in the tutorial document as illustrated below (click here to see a larger, more detailed version of this image):
This is cool, except that it means nothing to me yet. I’ve gone through all of the steps, but thus far I haven’t learned anything (apart from the fact that I need to be in the “Simulation” view, of course). Unfortunately, the “haven’t learned anything” refrain seems to be far too common a theme for me, but I’ll do my best to break out of this pattern soon. The tutorial doesn’t actually end there. It now jumps to Chapter 4 (unless you want to go through the command-line version also).
Between now and next week, I’m going to read the remainder of the tutorial and start dissecting the various parts of this simulation system. Until then; how about a vote? Is ISim the way to go? Or is there something else that's much better out there?
Re: Another Humble Request to the FPGA VHDL Experts
@devel@latke.net: " .... I am still kinda dizzy ...."
Ash I promised, I came back for another simple request from the experts. Happy to learn.(grin)
OK, I made some progress as far as defining a package named SRPackage and compiling it as a library placed at a certainh directory on the hard disk, say D:\ABD\DEF\partsbox
I began creating a test project named ActiveLowJK.vhd module which is expected to use the SRPlackageNow, I need to know how to refer to it along the library declaration and include (use) code lines as follows:
library IEEE, partsbox; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use partsbox.SRPackage.all;
Since I got errors referent to "libraby not defined" and such, I located the ieee directory within %PATH\Xilinx\11.1\ISE\vhdl\xst
For lack of better knowledge, I placed the 'partsbox' in there. Still didn't work.
At this point, after exploring Google the best I know, it remains to wait for the wisdom coming down from the AllProgrammablePlanet experts and gurus! (grin)
Duane Benson 2/25/2013 11:46:36 AM User Rank Blogger
Re: Another Humble Request to the FPGA VHDL Experts
Devel - Thanks for the detailed explanation. I'm nowhere near the point of creating libraries or packages, but this helps me undersdtand what I'm doing when I use something from a library or package.
Re:but thus far I haven't learned anything (apart from the fact that I need to be in the "Simulation" view, of course).
But see, you did learn something! I bet you will never forget that "Simulation" radio button again! Isn't it funny how learning the hard way is always best... (After the frustration is over! :-)
Re:Unfortunately, the "haven't learned anything" refrain seems to be far too common a theme for me
Re: Another Humble Request to the FPGA VHDL Experts
perhaps i wasn't clear.
compile the uart into whatever library you want (like you are recommending and showing examples for). I completely agree here.
but, within the uart hierarchy itself, all uart references and declarations can be to work. however, you are not analyzing into work as we have previously stated.
by using work internally, the tools can resolve those references and declarations into the library the unit is analyzed into. the tools are smart enough to know that say in uart_fsm.vhd the use work.uart_pkg.all will resolve/map to my_uart_lib.uart_pkg.all
at whatever level of hierarchy the uart is instantiated or the pkg is used (outside of the uart hierarchy) is where the unique library name is needed. anything below can just use work, safely.
Re: Another Humble Request to the FPGA VHDL Experts
intseeker: Please, tell me the name of the book on "digital design with VHDL" book you wrote, and I will purchase a copy.
Sorry, I haven't written one. I work for a living, and I can't imagine taking the time off to write such a book. I'm too lazybusy to even work up a simple WordPress blog with this stuff on it.
Re: Another Humble Request to the FPGA VHDL Experts
Thrakkor: otherwise, reusers down the road are stuck with whatever library name you created and it could conflit with existing library names in their design.
I agree -- somewhat.
But as someone on another VHDL thread pointed out, a good reason (perhaps really the only reason) to use VHDL libraries is to avoid namespace collision. Everybody wants to call their UART something simple like "uart."
So rather than trying to analyze the uart entity into the work library and have it collide with another entity called uart (OK, so you're insane and you're using two different uart models for some crazy reason), you put your UART into a library whose name is hopefully "reasonably unique."
You could end up with something like:
library ieee;
use ieee.std_logic_1164.all;
library ExpensiveIP;
use ExpensiveIP.TheirPackages.all;
library MyCompanyLibrary;
use MyCompanyLibrary.OurPackages.all;
and when you instantiate:
theiruart : entity ExpensiveIP.uart port map (...);
myuart : entity MyCompanyLibrary.uart port map (...);
FWIW, this is the reason why Xilinx' EDK uses libraries for all of their IP cores. And note that the library names they use attempt to be unique by adding version numbers and all of that.
Re: Another Humble Request to the FPGA VHDL Experts
the only things I would add to what Devel has described are these:
1) within the uart hierarchy you are compliing into myuart library, use the generic work library name for all references and declarations.
why?
because the library creation based on RTFM creates virtual mappings. and in this way it is truly portable because you can compile the uart hierarchy into any arbitrary library for reference in a larger design. otherwise, reusers down the road are stuck with whatever library name you created and it could conflit with existing library names in their design.
2) you can skip the component declaration of the topmost entity in the package and when instantiating it do this:
myuart_i : entity myuart.uart
which directly invokes the library myuart you have compiled the uart hierarchy into.
It is complicated and I understand most of the steps. However, I must tell you that this is the best step-by-step guide I ever got! Please, tell me the name of the book on "digital design with VHDL" book you wrote, and I will purchase a copy. THIS IS GOOD STUFF!
I am still kinda dizzy after reading it, but hopeful that I will pull this together :0)
UART, ALARM CLOCK, or a simple FF, all come from a seed: "bit".
Re: Another Humble Request to the FPGA VHDL Experts
intseeker: @jezimo: In that case int I would suggest that you put your components in a package rather than creating a library.
Thanks Jezimo for staying with me on this(grin)
So my first question is: why do you want to use a library? I mean, I wouldn't put simple stuff (like a D-flip-flop) into a library. If anything, it would be something more substantial, like perhaps the entire description of a UART or something.
And having said that: anything substantial which is likely to be re-used gets put into the source-code control system and the source checked out (using Subversion's externals property) along with the rest of the FPGA design. But I digress.
Here is what is important to understand about VHDL libraries. They aren't what you think they are. Here is why I say that.
A library is a collection of compiled "stuff." That "stuff" could be anything from entities to type definitions to packages. You are obviously familiar with the ieee library. It contains definitions of some types (std_logic among them) and functions which convert between types.
Note I said "collection of compiled." So right away you need to compile the library for your simulation tool and compile it again for your synthesis tool. (Your vendors provide a pre-compiled ieee library.)
Furthermore, look at the usual library use invocation:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
Before the first dot is the library name. The second thing (std_logic_1164, numeric_std) is the name of a package which has been compiled into that library. The "all" says that "all parts of the package are available for your use."
What does the second part, "a package which has been compiled into that library" mean? Not quite simple, I'm afraid. It means that if you want to put something into a library and then reuse it, you need to put it into a package which gets analyzed into that library.
Stay with me here. There are actually two parts of a package.
There is the package declaration and the package body. You can think of (very roughly) the package declaration in the same way as a C header file. It can contain your type definitions and constants. It can contain function and procedure declarations (but not the "guts" of them). It can contain component declarations (but again not the "guts"). It is the last of these which you'd use for entities such as your reusable UART.
Along with the package declaration, you might have a package body. It is in the package body where you will find the code for the functions and procedures referenced in the package declaration. The package body does not, however, contain the description of a component's logic. More on that in a moment. So now you have a package declaration and possibly a package body. When you compile the package, you can specify the library into which it is compiled. How you do that is entirely tool-dependent, so RTFM. So if you like, you can compile your UART into a library called myuart, and then code which wants to use the UART does:
library myuart;
use myuart.myuart_pkg.all;
and code in the entity which needs to know about your UART can use it. BUT WAIT, THERE'S MORE. You're still asking, "how do I put my UART entity into the library?" Like so:
Code up your UART entity in the usual way (create an entity port list and an architecture and fill in the guts). Call it myuart.
Create a package declaration, call it myuart_pkg. In that package declaration, create a component declaration that matches exactly the entity declaration for myuart.
Tell your synthesis or simulation tool to create a library called myuart. (Tool-dependent, RTFM).
Tell your synthesis or simulation tool to compile both the UART entity itself and the package into that library myuart. (Otherwise, they get compiled into the default work library.)
Now you're asking, "How do I use my library?
Tell your synthesis or simulation tool about this library myuart so when it's elaborating, it can find the guts of your UART entity. (Again, tool-dependent.)
In the library-declare part of the sources that need to know about your UART, add the library lines noted above.
In the entity which instantiates your UART, instantiate the component called myuart. The package (header) includes the component declaration, so the compiler is satisfied.
Duane has decided that the time is ripe to get his ZedBoard bolted onto his robot with a Linux distribution up and running. That was the ultimate plan anyway, so why wait?
To save this item to your list of favorite All Programmable Planet content so you can find it later in your Profile page, click the "Save It" button next to the item.
If you found this interesting or useful, please use the links to the services below to share it with other readers. You will need a free account with each service to share an item via that service.