Perform functional simulation before design implementation to verify that the schematic you designed is logically correct. All components in the Calc design, even the non-schematic LogiBLOX module, have built-in simulation models, reducing the amount of pre-processing.
The CONCEPT2XIL program both translates the design for implementation and creates a simulatable Verilog netlist. The latter only occurs after running CONCEPT2XIL if the design contains schematic components only. If the design contains any black boxes with no underlying schematics, such as VHDL code synthesized and compiled down to an NGO file, functional simulation can only occur after execution of the program NGDBuild. In any case, NGDBuild executes during implementation. The Calc schematic does not contain any non-schematic blocks, so proceed directly to simulation.
At the UNIX prompt in the main design directory, enter the following command.
concept2xil -sim_only -rundir -family \
xilinx.func_sim xce4000e calc
If compiling this for another family, substitute the appropriate family name for xce4000e (such as xce9000, xce5200, xce3000, or xce4000x for the 9500,5200,3000A,or 4000EX, respectively).
The -sim_only option causes CONCEPT2XIL not to create an EDIF file, which it normally does so the Xilinx Design Implementation Tools can implement the design.
After CONCEPT2XIL completes, it creates a xilinx.func_sim directory by default, which contains all the output files (except concept2xil.log). The generated output files are a V file (Verilog file that declares the global GSR and GTS signals for a 4000E(X) part), and a VF file (list of paths to all the Verilog files that comprise the design).
Either HDL Direct creates the Verilog files that the VF file points to, or those files are part of the Xilinx-supplied Verilog library of components for all the Xilinx primitives and macros (located in $XILINX/cadence/data/family. A few entries from a sample VF file follow.
/home/jeremy/m1/cadence_m1tut/calc/logic/verilog.v
/home/jeremy/m1/cadence_m1tut/alu1/logic/verilog.v
/xilinxM1/cadence/data/xce4000e/adsu4/logic/verilog.v
/home/jeremy/m1/cadence_m1tut/andblk2/logic/verilog.v
/xilinxM1/cadence/data/xce4000e/fd4re/logic/verilog.v
Later, when Verilog-XL executes, the -f option causes Verilog-XL to read in all the verilog.v files referenced by calc.vf.
Now that CONCEPT2XIL has created the necessary files, you must create a Verilog test fixture to properly force the inputs for the simulation. The tutorial (calcf.stim) directory includes a sample test fixture, which you modify for the functional simulation. The next subsections provide an analysis of the various parts of the test fixture.
Include a `timescale directive near the top of the file. The `timescale directive declares the time unit used, followed by the precision. Smaller precisions result in longer run times, but can provide more accurate results. The following shows a typical `timescale directive.
`timescale 1 ns/100 ps
You do not have to use a smaller precision than 1 ps in a timing simulation because the delay numbers given in the .sdf file are not more precise than that. In functional simulation, it is essentially irrelevant (except for longer simulation run times) so long as it is more precise than the time unit (1 ns).
Use the following test fixture module declaration with Calc.
module test;
// Design inputs
reg notgblreset;
reg [7:0] switch
// Design outputs
wire ofl;
wire a, b, c, d, e, f, g;
wire [3:0] guage;
wire [3:0] stackled;
// Instantiated design with an instance name of "uut"
calc uut (.ofl (ofl), .notgblreset (notgblreset), .g (g),
.f (f), .e (e), .d (d), .c (c), .b (b), .a (a),
.guage (guage), .stackled (stackled),
.switch (switch));
The test fixture itself is considered the top-level module (module test;), and the design is considered a component to instantiate (calc uut (...)). All the inputs and outputs of the Calc module connect to signals in the test fixture with the same name (although the name can differ). The inputs of the Calc module (switch and notgblreset) connect to signals in the test fixture of type reg because the test fixture stimuli drives the signals. The signals hold their values until driven differently. Outputs go to signals of type wire.
The calc uut line is the instantiation of the Calc design. The string uut is an instance name (any name will do, so long as it conforms to Verilog naming conventions). Generalize the string .ofl (OFL) to mean .port_name (signal_name), where port_name is the name of the I/O port in the Calc module, and signal_name is the name of the signal in the test fixture to which it connects.
The output signal values of the Verilog-XL simulator can display in the UNIX xterm window where you invoked Verilog-XL, or you can save the signals in a waveform database for display in SimWave later on.
If you want to display the signal values in the xterm window, use a $monitor statement to define a list of signals to display, as shown in the following example.
$monitor("%t",$realtime,, "| %b", notgblreset,, "%b", switch[7],, "%b", switch[6:0],, "%b", uut.clk,, "| %b", uut.exec,, "| %h", uut.aluval[3:0],, "%h", stackled[3:0]);
The $monitor statement outputs the signal values whenever an event occurs on one of the listed signals (one of the signals toggles). The $realtime function returns the system time as a real number; system time displays via the $timeformat function. A typical $timeformat statement follows.
$timeformat(-9,3,"ns",12);
This $timeformat statement display the system time in units of 1E-9, to 3 decimal digits precision, to end with the string ns, and to display at least 12 digits.
The sample Calc test fixture file also uses several $display statements to serve as a header for your output.
If you use SimWaves to display the output waveforms, make the test fixture write out a waveform database (.shm file), which SimWave can read in later on. Use the $shm_open statement with the following syntax.
$shm_open(calc.shm);
You can use any directory and file name as a target. You must include the quotation marks.
In addition, you need a $shm_probe statement indicating which signals to write to the database. An example $shm_probe statement follows.
$shm_probe("AS")
The AS argument includes all signals in the test fixture and all instantiations below it (including Calc) in the database, except for the internal signals of library cells.
Because most designs have an external clock signal coming in, include a block in the test fixture that generates the pulses without having to manually toggle the clock signal back and forth.
Theoretically, you do not have to create a clock for the Calc schematic because it already has the OSC4 component (inside CLOCKGEN) generating a 15Hz signal. However, the OSC4 component also has a 8MHz pin, and therefore the OSC4 Verilog model has to simulate the toggling of the 8MHz pin (even though the Calc schematic does not use it). Verilog-XL takes an extraordinary amount of time to simulate a 15Hz clock signal. The osc4.v module, located in $XILINX/cadence/data/verilogxce4000e, has a `timescale precision of 100ps, so to make it to the first edge of the 15Hz clock, set at 3.33E10 ps (.0333 seconds), requires 3.33E10 / 100 = 333 million simulation events.
Therefore, define a clock in the test fixture that clocks much slower, and forces its values onto the CLK net, overriding the OSC4 clock. Typically, you define a clock with an always block.
always
begin
#10 clock = ~clock;
end
Do not use this example in the Calc test fixture; it is only an general example. This previous statement assigns clock the value of itself negated, but only after waiting 10 time units (assuming `timescale 1ns, this would mean 10 ns). So if clock is initially 0, then after assigning ~clock to 10ns clock, the value resets as 1. Because this is in an always block, it continuously loops around until simulation halts.
Notice, however, the previous analysis assumed an initial value of 0. You must include a statement inside an initial block that defines the value at time 0ns.
initial
begin
clock = 0;
The above assumes a port clock on the design, but that is not the case in the Calc design (because OSC4 generates the clock internal to the device). Because of this, you need the following in the test fixture.
// Create a clock for the Oscillator
always
begin
force uut.clk = 0;
#50 force uut.clk = 1
#50;
end
The always block immediately forces uut.clk to 0, and then forces uut.clk to 1 after 50ns. The block then pauses for 50ns before looping around to force uut.clk back to 0, creating a clock of period 100ns that begins with 0 at 0ns and has its first rising edge at 50ns.
In the statement #50 force uut.clk = value you need the keyword force because force always overrides the current value on a signal. Because OSC4 still drives the signal, the force command prevents contention on the signal. Additionally, you must use the syntax uut.clk.If the referenced signal does not exist in the test fixture (or the module where the assignment occurs), then you must specify the hierarchy of the signal by referencing the instance name contained it, followed by a period and the signal name.
In a netlist for a 4000E(X) or a Spartan design that uses STARTUP, the Global Set and Reset (GSR) net that leads to every flip-flop connects to the STARTUP block implicitly. Toggle the signal that controls the GSR pin to begin simulation and to simulate resetting the device. Even if your design does not utilize the STARTUP block, pulse the GSR line once at the beginning of simulation to simulate the initial behavior of the device.
In the Unified Library functional simulation, you must connect the logic that controls the GSR pin to the underlying global GSR net by using a `define directive.
`define GSR_SIGNAL testfixture.design.signal_on_GSR_pin
Here testfixture is the name of the test fixture module, design is the instance name of the instantiated design, and signal_on_GSR_pin is the net name that sources the STARTUP GSR pin.
The following connects the GSR pin to the GSR net in the Calc design.
`define GSR_SIGNAL test.uut.gblreset
Using notgblreset; is not necessary. Instead, you must use the signal that actually hooks up to the STARTUP GSR pin, not the signal that comes in from the IPAD. If you use the signal that comes in from the IPAD, the polarity of GSR in simulation reverses because an inverter exists between the signal NOTGBLRESET and the GSR pin.
However, if you do not use the STARTUP block, you must directly drive the GSR. You can again use the `define directive to define a GSR signal, even though it does not explicitly exist in the schematic or HDL code. To do this, you define a dummy "reg test.GSR" (assuming the test fixture module name is "test," recommended if you want to reuse the test fixture with post-NGDBuild simulation). You then need to use the `define to hook it up to the verilog models, and drive "test.GSR" in your stimulus.
`define GSR_SIGNAL test.GSR
reg GSR
.....
.....
initial
begin
test.GSR=1; // Begin Global Reset
#300 test.GSR=0; // End Global Reset
//assign inputs now
For the 5200 family (which has a STARTUP symbol available), use the following.
`define GR_SIGNAL testfixture.design.signal_on_GR_pin
If you use this statement for the Calc design, and you use STARTUP as discussed in previous sections, then make signal_on_GR_pin gblreset. If you do not use STARTUP, then you must define a dummy signal, as discussed before.
For the 9500 family, use the following.
`define PRLD_SIGNAL test.PRLD
reg PRLD; //no 9K STARTUP, so use this dummy
.....
.....
initial
begin
test.PRLD=1; // Begin Global Reset
#300 test.PRLD=0; // End Global Reset
//assign inputs now
For the 3000A family, use the following.
`define GR_SIGNAL test.GR
reg test.GR;
Use a similar procedure as described previously for the 9500. GR on a 3000A is active-low.
In the test fixture, you must add a series of stimuli to all the inputs. Typically, you place this series in an initial block, and you place timing controls to specify when the inputs change. If one or more of the inputs is periodic (for example, the clock), then you can instead put that signal in an always block, as described previously for the clock signal.
The following shows a series of assignments that work with the Calc design (comments appear after //).
initial
begin
//Initialize Input Signals
//time=0
switch[7] = 1'b1;
switch[6:0] = 1'h0;
notgblreset = 1'b0 ; //Apply Global Reset
#200 //time=200
notgblreset = 1 ; //End Reset
switch[6:0] = 7'b1100001;
#500 //time=700
switch[7] = 0;
switch[6:0] = 7'b0001101;
#200 //time=900
switch[7] = 1;
#300 //time=1200
switch[7] = 0;
switch[6:0] = 7'b1111011;
#200 //time=1400
switch[7] = 1;
#400 //time=1800
switch[7] = 0;
switch[6:0] = 7'b0111111;
#200 //time=2000
switch[7] = 1;
#300 //time=2300
switch[7] = 0;
switch[6:0] = 7'b1111011;
#200 //time=2500
switch[7] = 1;
#300 //time=2800
switch[7] = 0;
switch[6:0] = 7'b1010000;
#200 //time=3000
switch[7] = 1;
#200 $stop; //time=3200
end
Begin by forcing the notgblreset signal low, then assert it high after 200ns. In the Calc design the notgblreset net goes through an inverter, which makes the GSR active low, but in the 4000E(X) family GSR is normally active high.
The switch signal, the main input (it inputs the opcode and the data), gets assigned various values to test its various functions. See the Hardware Debugger Guide for a complete description of the Calc design, and to understand how the switch settings function. Specify the signal switch[7] independently only for clarity; it has a separate function (execute).
Time is cumulative when you use the (#xxx) notation (the sequence #20 statement1; #30 statement2; means execute statement1 at 20ns, execute statement2 at 50ns).
At the end of the block, you can put a $finish or a $stop. A $finish causes Verilog-XL to terminate. A $stop causes Verilog-XL to terminate simulation from the test fixture, but go into interactive mode. See your Cadence documentation for information about using interactive mode.
After creating the test fixture and running CONCEPT2XIL, you can go into the Verilog-XL simulator. From the xilinx.run directory, invoke the UNIX command line.
verilog +gui calcf.stim calc.v -f calc.vf
The +gui switch invokes the Verilog-XL GUI. If you do not have this feature, omit using this switch.
CONCEPT2XIL created the files calc.v and calc.vf. The calcf.stim file is user-generated (a copy exists in the tutorial design directory; copy it to the xilinx.func.sim directory to use it).
After entering the previous command line, the following displays (only the first portion of simulation appears here).
Highest level modules:
test
alias_vector
alias_bit
Inputs Internal Outputs
(Binary) Signals (HEX)
==========|===============|=======|==========
| n s sssssss c | e s p | a s
Time | o w wwwwwww l | x t u | l t
| t i iiiiiii o | e a s | u a
in | g t ttttttt c | c c h | v c
| b c ccccccc K | k | a k
ns | l h hhhhhhh | e | l l
| r | n | e
| e 6543210 | | d
| s | |
| e | |
| t | |
==========|===============|=======|==========
0.000ns | 0 1 0000000 0 | x x x | x x
0.100ns | 0 1 0000000 0 | x x x | 0 x
0.200ns | 0 1 0000000 0 | 0 x x | 0 x
0.300ns | 0 1 0000000 0 | 0 0 0 | 0 x
0.400ns | 0 1 0000000 0 | 0 0 0 | 0 f
50.000ns | 0 1 0000000 1 | 0 0 0 | 0 f
100.000ns | 0 1 0000000 0 | 0 0 0 | 0 f
150.000ns | 0 1 0000000 1 | 0 0 0 | 0 f
200.000ns | 1 1 1100001 0 | 0 0 0 | 0 f
250.000ns | 1 1 1100001 1 | 0 0 0 | 0 f
250.000ns | 1 1 1100001 1 | 1 0 0 | 0 f
250.000ns | 1 1 1100001 1 | 0 0 0 | 0 f
300.000ns | 1 1 1100001 0 | 0 0 0 | 0 f
350.000ns | 1 1 1100001 1 | 0 0 0 | 0 f
400.000ns | 1 1 1100001 0 | 0 0 0 | 0 f
450.000ns | 1 1 1100001 1 | 0 0 0 | 0 f
500.000ns | 1 1 1100001 0 | 0 0 0 | 0 f
$display statements specified the header (time, clock, notgblreset, and the rest.) in the test fixture. The clock corresponds to uut.clk, now overridden with force statements in the test fixture. The simulation outputs are aluval[3:0] and stackled[3:0]. The following intermediate nodes display: exec, stacken, and push. Undefined states are marked with an x.
Cadence shipped the cWaves waveform viewer up to and including its 9604 release. Starting with the 97A release, it replaced cWaves with SimWave. This tutorial uses SimWave to display the waveforms.
To invoke SimWave, follow these steps.
Figure 9.41 SimWave Browser/Display Tool |
The Calc design uses switch[6:0] as an opcode and data, but also uses switch[7] as a toggled execute switch. For convenience, display switch[6:0] separately from switch[7].
Figure 9.42 Splitting up the Switch[7:0] Bus in SimWave |
I
Figure 9.43 Final SimWave Display of Waveforms |
Select File Database
Save to save your setup. This does not save the waveforms themselves; they still exist in the .shm file.
Because the end of the testbench has a $stop function placing Verilog-XL into an interactive mode, exit using one of the following methods.
If you cannot easily read the waveforms shown in the display, zoom out to see the entire waveform. Also, the timescale shown at the bottom of the display appears now in picoseconds, compressing their appearance. Arrange the waverforms differently to improve their readability.
Figure 9.44 Changing the Displayed Time Scale in SimWave |
Order the waveforms in the following sequence, from top to bottom: notgblreset, switch[7], switch[6:0], clk, exec, stacken, push, aluval, and stackled.