What's the simplest way to syntax-check my VHDL in Vivado without running through a full synthesis?
Sometimes I code many inter-related modules at once, and would like to quickly find naming errors, missing semi-colons, port omissions, etc. The advice I've read is to run synthesis, but that takes longer than I need for just a syntax check. I've observed that syntax errors will usually cause synthesis to abort within the first minute or so, so my workaround is to run synthesis and abort it manually after about a minute.
In the Vivado Tcl Console window, the check_syntax command performs a fast syntax check, catches typos, missing semi-colons, etc.
Vivado offers an elaboration step before synthesis. This is the lightweight version of y synthesis by just reading all sources and creating a design model based on the language without optimizations and transformations.
A pure syntax check per file is not enough in many cases. You also want to know if certain identifiers exist and if types are matching. Therefore, an elaboration is needed.
(If you never have heard of that step: VHDL compiling has 2 steps: Analysis and Elaboration. Think of elaboration like of linking in ANSI C.)
This is a question inspired by this question and answer pair: call questa sim commands from SystemVerilog test bench
The questions asks how Verilog code could control the executing simulator (QuestaSim). I saw similar questions and approaches for VHDL, too.
So my question is:
Why should a simulation (slave) have power of its simulator (master)?
What are typical use cases?
Further reading:
call questa sim commands from SystemVerilog test bench
VerTcl - A Tcl interpreter implemented in VHDL
Why? Can anyone answer "why"? Well, perhaps the product engineer, or developer at Mentor that drove the creation of such behavior can answer that. But lacking that, we can only guess. And that's what I'm doing here.
I can think of a few possible use cases, but they aren't something that cannot be done in another manner. For example, one could have a generic "testbench controller" that depending on generics/parameters could invoke certain simulator behavior. (Edit: After re-reading one of your links, I see that's the exact use case.)
For example, say I have this "generic" testbench code as:
module testbench;
parameter LOG_SIGNALS = 1'b0;
initial
begin
if LOG_SIGNALS
begin
// Log all signals in the design
mti_fli::mti_Cmd("add wave -r /*")
end
endmodule
Then, one could invoke this as:
vsim -c -gLOG_SIGNALS=1 work.testbench
The biggest use case for this might be if vsim is invoked from some environment. If one were to do a do file, I'm not sure one can pass parameters to the script. Say one had the following do file:
if {$log_signals} {
add wave -r /*
}
How does one set $log_signals from the command line? I suppose one could do that through environment variables, such as:
if { [info exists ::env(LOG_SIGNALS)] } {
add wave -r /*
}
Other uses cases might be to turn on/off the capturing of coverage data, list files, maybe even a quirky case of ending simulation.
But of course, all of these can be handled in other manners. And in manners I think are much more clear and much easier to maintain.
As for VerTCL, I find it fascinating. But incomplete. Or at very least barebones. I find scripted testenches exceedingly useful (we use them where I work). And VerTCL is a great way to do it (if you like TCL). But it does need some framework around it to read signals, drive signals, and otherwise manage a simulation.
Ideally, you wouldn't need a simulator API if the HDL was comprehensive enough to do all the functions that are currently left to the simulator. At its inception, Verilog was implemented as an interpreted language and the command line was the Verilog language instead of some other command line interface we see today based on Tcl.
But as simulators became more complex, they needed commands that interacted with the file system, platform, OS, as well as other features at faster pace than the HDL standard could keep up with. The IEEE HDL standards stop at any implementation specific details.
So simulation tool vendors developed command line interfaces (CLI) to meet user needs for debugging and analysis. These CLIs are robust enough to create stimulus and check behaviors that there can be an overlap in functionality of the CLI code versus what's in your testbench source code. So having an API to your simulators CLI can make it easier to control the flow of commands to the simulator and avoid duplication of procedures.
For example, maybe you want to start logging signals to add to a waveform after the design gets out of reset. From the CLI, you would have to set a watch condition on the reset signal that executes the logging command when reset goes inactive. Using the simulator API, you could just put that command in your bench in the spot in your where release reset.
I have instantiated the BSCANE2 in my tutorial designs in order to do easy controls and commands into the trial designs, and in order to simulate this I will use the BSCAN_SIME2.
However, I do not seem to find any documentation on this SIME2.
My trials so far on simulating has shown that it does set the SHIFT signal when going through the DR Shift states, but I have not yet been able to get a SEL signal from issuing a USER1 JTAG instruction.
Anyone had success using this simulation component?
Up until now I have just used very simple structures in my test bench. I dont want to build a larger design before I know exactly how to stimulate it.
Thanks.
In many of my VHDL designs I create a lot of low level components in HDL (which is fine). However, when I am ready to create multiple instantiations and link them together at the top-level, I find that the file ends up being rather large with tons of internal signals going between tons of component instantiations. It gets a little unwieldy and hard to follow.
Instead, I thought what might be easier to understand and faster to develop with is if there was a graphical tool to do the high level component linking. It would be able to parse my low level HDL files and determine the port inputs/outputs and create a block (or multiple instances of that block). I could then use my mouse to create connections between the blocks and give them a text label. When I am done, it would be able to auto-generate a VHDL file with all appropriate syntax for creating internal signals, component instantiations, port declarations, etc.
I tried experimenting with Xilinx Schematic Editor, but this thing was a beast and I did not have any luck.
Is there any tool out there like this? If it could even get me 90% of the way I'd be happy.
You should take a look at www.sigasi.com
Sigasi has autocompletes to help you with the instantiations and quick-fixes to help you with the wiring. There is also a premium version that gives you a live, graphical block diagram view (demo screencast)
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
Interview question-
Often its pretty easier to debug a program once you have trouble with your code.You can put watches,breakpoints and etc.Life is much easier because of debugger.
But how to debug a program without a debugger?
One possible approach which I know is simply putting print statements in your code wherever you want to check for the problems.
Are there any other approaches other than this?
As its a general question, its not restricted to any specific language.So please share your thoughts on how you would have done it?
EDIT- While submitting your answer, please mention a useful resource (if you have any) about any concept. e.g. Logging
This will be lot helpful for those who don't know about it at all.(This includes me, in some cases :)
UPDATE: Michal Sznajderhas put a real "best" answer and also made it a community wiki.Really deserves lots of up votes.
Actually you have quite a lot of possibilities. Either with recompilation of source code or without.
With recompilation.
Additional logging. Either into program's logs or using system logging (eg. OutputDebugString or Events Log on Windows). Also use following steps:
Always include timestamp at least up to seconds resolution.
Consider adding thread-id in case of multithreaded apps.
Add some nice output of your structures
Do not print out enums with just %d. Use some ToString() or create some EnumToString() function (whatever suits your language)
... and beware: logging changes timings so in case of heavily multithreading you problems might disappear.
More details on this here.
Introduce more asserts
Unit tests
"Audio-visual" monitoring: if something happens do one of
use buzzer
play system sound
flash some LED by enabling hardware GPIO line (only in embedded scenarios)
Without recompilation
If your application uses network of any kind: Packet Sniffer or I will just choose for you: Wireshark
If you use database: monitor queries send to database and database itself.
Use virtual machines to test exactly the same OS/hardware setup as your system is running on.
Use some kind of system calls monitor. This includes
On Unix box strace or dtrace
On Windows tools from former Sysinternals tools like http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx, ProcessExplorer and alike
In case of Windows GUI stuff: check out Spy++ or for WPF Snoop (although second I didn't use)
Consider using some profiling tools for your platform. It will give you overview on thing happening in your app.
[Real hardcore] Hardware monitoring: use oscilloscope (aka O-Scope) to monitor signals on hardware lines
Source code debugging: you sit down with your source code and just pretend with piece of paper and pencil that you are computer. Its so called code analysis or "on-my-eyes" debugging
Source control debugging. Compare diffs of your code from time when "it" works and now. Bug might be somewhere there.
And some general tips in the end:
Do not forget about Text to Columns and Pivot Table in Excel. Together with some text tools (awk, grep or perl) give you incredible analysis pack. If you have more than 32K records consider using Access as data source.
Basics of Data Warehousing might help. With simple cube you may analyse tons of temporal data in just few minutes.
Dumping your application is worth mentioning. Either as a result of crash or just on regular basis
Always generate you debug symbols (even for release builds).
Almost last but not least: most mayor platforms has some sort of command line debugger always built in (even Windows!). With some tricks like conditional debugging and break-print-continue you can get pretty good result with obscure bugs
And really last but not least: use your brain and question everything.
In general debugging is like science: you do not create it you discover it. Quite often its like looking for a murderer in a criminal case. So buy yourself a hat and never give up.
First of all, what does debugging actually do? Advanced debuggers give you machine hooks to suspend execution, examine variables and potentially modify state of a running program. Most programs don't need all that to debug them. There are many approaches:
Tracing: implement some kind of logging mechanism, or use an existing one such as dtrace(). It usually worth it to implement some kind of printf-like function that can output generally formatted output into a system log. Then just throw state from key points in your program to this log. Believe it or not, in complex programs, this can be more useful than raw debugging with a real debugger. Logs help you know how you got into trouble, while a debugger that traps on a crash assumes you can reverse engineer how you got there from whatever state you are already in. For applications that you use other complex libraries that you don't own that crash in the middle of them, logs are often far more useful. But it requires a certain amount of discipline in writing your log messages.
Program/Library self-awareness: To solve very specific crash events, I often have implemented wrappers on system libraries such as malloc/free/realloc which extensions that can do things like walk memory, detect double frees, attempts to free non-allocated pointers, check for obvious buffer over-runs etc. Often you can do this sort of thing for your important internal data types as well -- typically you can make self-integrity checks for things like linked lists (they can't loop, and they can't point into la-la land.) Even for things like OS synchronization objects, often you only need to know which thread, or what file and line number (capturable by __FILE__, __LINE__) the last user of the synch object was to help you work out a race condition.
If you are insane like me, you could, in fact, implement your own mini-debugger inside of your own program. This is really only an option in a self-reflective programming language, or in languages like C with certain OS-hooks. When compiling C/C++ in Windows/DOS you can implement a "crash-hook" callback which is executed when any program fault is triggered. When you compile your program you can build a .map file to figure out what the relative addresses of all your public functions (so you can work out the loader initial offset by subtracting the address of main() from the address given in your .map file). So when a crash happens (even pressing ^C during a run, for example, so you can find your infinite loops) you can take the stack pointer and scan it for offsets within return addresses. You can usually look at your registers, and implement a simple console to let you examine all this. And voila, you have half of a real debugger implemented. Keep this going and you can reproduce the VxWorks' console debugging mechanism.
Another approach, is logical deduction. This is related to #1. Basically any crash or anomalous behavior in a program occurs when it stops behaving as expected. You need to have some feed back method of knowing when the program is behaving normally then abnormally. Your goal then is to find the exact conditions upon which your program goes from behaving correctly to incorrectly. With printf()/logs, or other feedback (such as enabling a device in an embedded system -- the PC has a speaker, but some motherboards also have a digital display for BIOS stage reporting; embedded systems will often have a COM port that you can use) you can deduce at least binary states of good and bad behavior with respect to the run state of your program through the instrumentation of your program.
A related method is logical deduction with respect to code versions. Often a program was working perfectly at one state, but some later version is not longer working. If you use good source control, and you enforce a "top of tree must always be working" philosophy amongst your programming team, then you can use a binary search to find the exact version of the code at which the failure occurs. You can use diffs then to deduce what code change exposes the error. If the diff is too large, then you have the task of trying to redo that code change in smaller steps where you can apply binary searching more effectively.
Just a couple suggestions:
1) Asserts. This should help you work out general expectations at different states of the program. As well familiarize yourself with the code
2) Unit tests. I have used these at times to dig into new code and test out APIs
One word: Logging.
Your program should write descriptive debug lines which include a timestamp to a log file based on a configurable debug level. Reading the resultant log files gives you information on what happened during the execution of the program. There are logging packages in every common programming language that make this a snap:
Java: log4j
.Net: NLog or log4net
Python: Python Logging
PHP: Pear Logging Framework
Ruby: Ruby Logger
C: log4c
I guess you just have to write fine-grain unit tests.
I also like to write a pretty-printer for my data structures.
I think the rest of the interview might go something like this...
Candidate: So you don't buy debuggers for your developers?
Interviewer: No, they have debuggers.
Candidate: So you are looking for programmers who, out of masochism or chest thumping hamartia, make things complicated on themselves even if they would be less productive?
Interviewer: No, I'm just trying to see if you know what you would do in a situation that will never happen.
Candidate: I suppose I'd add logging or print statements. Can I ask you a similar question?
Interviewer: Sure.
Candidate: How would you recruit a team of developers if you didn't have any appreciable interviewing skill to distinguish good prospects based on relevant information?
Peer review. You have been looking at the code for 8 hours and your brain is just showing you what you want to see in the code. A fresh pair of eyes can make all the difference.
Version control. Especially for large teams. If somebody changed something you rely on but did not tell you it is easy to find a specific change set that caused your trouble by rolling the changes back one by one.
On *nix systems, strace and/or dtrace can tell you an awful lot about the execution of your program and the libraries it uses.
Binary search in time is also a method: If you have your source code stored in a version-control repository, and you know that version 100 worked, but version 200 doesn't, try to see if version 150 works. If it does, the error must be between version 150 and 200, so find version 175 and see if it works... etc.
use println/log in code
use DB explorer to look at data in DB/files
write tests and put asserts in suspicious places
More generally, you can monitor side effects and output of the program, and trigger certain events in the program externally.
A Print statement isn't always appropriate. You might use other forms of output such as writing to the Event Log or a log file, writing to a TCP socket (I have a nice utility that can listen for that type of trace from my program), etc.
For programs that don't have a UI, you can trigger behavior you want to debug by using an external flag such as the existence of a file. You might have the program wait for the file to be created, then run through a behavior you're interested in while logging relevant events.
Another file's existence might trigger the program's internal state to be written to your logging mechanism.
like everyone else said:
Logging
Asserts
Extra Output
&
your favorite task manager or process
explorer
links here and here
Another thing I have not seen mentioned here that I have had to use quite a bit on embedded systems is serial terminals.
You can cannot a serial terminal to just about any type of device on the planet (I have even done it to embedded CPUs for hydraulics, generators, etc). Then you can write out to the serial port and see everything on the terminal.
You can get real fancy and even setup a thread that listens to the serial terminal and responds to commands. I have done this as well and implemented simple commands to dump a list, see internal variables, etc all from a simple 9600 baud RS-232 serial port!
Spy++ (and more recently Snoop for WPF) are tremendous for getting an insight into Windows UI bugs.
A nice read would be Delta Debugging from Andreas Zeller. It's like binary search for debugging