Functional simulation of HDL designs includes support for FPGA and CPLD architecture features, such as global set/reset, global tristate enable, on-chip oscillators, RAMs, and ROMs.
You can perform functional simulation at the following points in the design flow.
The first simulation point is the RTL-level simulation that allows you to verify or simulate a description at the system or chip level. At this level, the system or chip is described with high-level RTL language constructs. VHDL and Verilog simulators exercise the design to check its functionality before it is implemented in gates. A test bench is created to model the environment of the system or chip. At this level, the Unified Simulation Library (UniSim) is used to instantiate cells. You can also instantiate LogiBLOX components if you do not want to rely on the module generation capabilities of your synthesis tool, or if your design requires larger memory structures.
After the RTL simulation is error-free, the system or chip is synthesized to gates. The test bench is used again to simulate the synthesized result and check its consistency with the original design description.
Gate-level simulation in the Xilinx design flow includes any simulation performed after any of the synthesis, map, or place and route stages. The post-synthesis pre-NGDBuild gate-level simulation is a functional simulation with unit delay timing. The gates are expressed in terms of UniSim components.
This gate-level functional simulation allows you to directly verify your design after it has been generated by the synthesis tool. If there are differences in the behavior of the original RTL description and the synthesized design, this may indicate a problem with the synthesis tool. Although RTL-level and gate-level simulation may differ even when the synthesis is correct. This is due to the change in the level of abstraction. In general, overall functionality should be the same, but timing differences may occur.
Post-synthesis simulation is synthesis vendor-dependent, and the synthesis tool must write VHDL or Verilog netlists in terms of UniSim library components. Check with your synthesis vendor for this feature. The library usage guidelines for RTL simulation also apply to post-synthesis pre-NGDBuild gate-level functional simulation. LogiBLOX models remain as behavioral blocks and can be simulated in the same design as structural UniSim components. You may have to insert library statements into the HDL code.
The post-NGDBuild (pre-map) gate-level functional simulation is used when it is not possible to simulate the direct output of the synthesis tool. This occurs when the tool cannot write UniSim-compatible VHDL or Verilog netlists. In this case, NGDBuild translates the EDIF or XNF output of synthesis to SimPrim library components. Like post-synthesis, pre-NGDBuild simulation, this simulation allows you to verify that your design has been synthesized correctly, and you can begin to identify any differences due to the lower level of abstraction. Unlike the post-synthesis pre-NGDBuild simulation, there are GSR, GR (global reset), PRLD (preload), and GTS nets that must be initialized, just as for post-map partial timing simulation.
Different simulation libraries are used to support simulation before and after running NGDBuild. Prior to NGDBuild, your design is expressed as a UniSim netlist containing Unified Library components. After NGDBuild, your design is a netlist containing SimPrims. Although these library changes are fairly transparent, two important considerations are specifying different simulation libraries for pre- and post-implementation simulation, and the different gate-level cells in pre- and post-implementation netlists.
You can pause the implementation tools after reading in your source files; select either a VHDL or Verilog netlist as an output file; and write the file.
The third type of post-synthesis functional simulation is post-map partial timing simulation. This gate-level description is also expressed in terms of SimPrim components.
The SDF file that is created contains timing numbers for the CLB and IOB mapped blocks. At this point, your design is not routed and does not contain net delays, except for pre-laid out macros, such as cores. Like the post-NGDBuild and full-timing simulation, there are GSR, GR, PRLD, and GTS nets that must be initialized. If you want partial timing delays, you can use the SDF file (this is optional).
You can pause the implementation tools after the Map program stops, and write one of the HDL formats.
When you create a test bench for functional simulation, refer to the following table for coding style examples. You should refer to your synthesis vendor's documentation before using these styles because many of the styles cannot be synthesized.
Description | Verilog | VHDL |
---|---|---|
Delay or wait 20 ns | `timescale 1 ns/ 100 ps #20 | wait for 20 ns; |
Creation of a free running clock | Initial begin clock = 0; #25 forever #25 clock = ~clock; end | Loop wait for 25 ns; clock <=not (clock); end loop; |
Print Text. to screen | $display(Text); | report Text. |
Print value of signal to screen whenever the value changes | $monitor(%r,$real time,%b, clock,%bmy_signal); | |
Apply a binary value 1010 to an input bus X. | X = 4'b1010; | X <=1010; |
Creation of a for loop 0 to 10 | for(x=0; x < 10; x=x+1) begin actions end | for x in 0 to 9 loop actions end loop; |
Write X = value to an output file | $dumpfile (file name.dmp); $dumpvars (X); | variable TEMP; write (TEMP, X =); write (TEMP, X); writeline (filename, TEMP); |
Wait until X is logic one | wait (X == 1'b1); | wait (X == '1'); |
Wait until X transitions to a logic one | @(posedge X); | wait on X; |
If-Else construct | always @ (X) begin if (X = 1) Y = 1'b0; else Y = 1'b0; end | process (X) if (X = `1') then Y = `0'; else Y = `1'; end if; end process; |
Case construct | always @(X or A) case (X) 2'b00 : Y = 1'b0; 2'b01 : Y = 1'b1; default : Y = A; endcase | process (X,A) begin case X is when 00 => Y ='0'; when 01 => Y = `1'; when others => Y = A; end case; end process; |
Example instantiation of an OFD | OFD U1 (.Q(D_OUT),.D(D_IN), .C(CLOCK)); | U1: OFD port map (Q => D_OUT), D => D_IN, C => CLOCK); |