Anda di halaman 1dari 15

Introduction to Verilog This document uses short examples to demonstrate the basic Verilog syntax, time delays, and

concurrent execution features. We have tried to condense all the interesting and hard parts of Verilog into 15 pages and skip all of the boring stuff like the what is the difference between real and integer data types. Studying this document will enable you to model circuits using simple structural and behavioral Verilog code and provide a solid framework for learning all the details of the language. If Verilog is a new language for you we recommend getting a copy of "Verilog HDL" by Samir Plantikar. It is a well organized Verilog textbook that is filled with lots of examples. 1.0 Why Use Verilog? Most Verilog and VHDL books begin with several chapters describing the language's history and advantages. But the arguments boil down to these:

HDL simulators are better then gate level simulators for 2 reasons: portable model development, and the ability to design complicated test benches that react to outputs from the model under test. Finding a model for a unique component for your particular gate level simulator can be a frustrating task, with an HDL language you can always write your own model. Also most gate level simulators are limited to simple waveform based test benches which complicates the testing of bus and microprocessor interface circuits. Verilog is a great low level language. Structural models are easy to design and Behavioral RTL code is pretty good. The syntax is regular and easy to remember. It is the fastest HDL language to learn and use. However Verilog lacks user defined data types and lacks the interface-object separation of the VHDL's entityarchitecture model. VHDL is good for designing behavioral models and incorporates some of the modern object oriented techniques. It's syntax is strange and irregular, and the language is difficult to use. Structural models require a lot of code that interferes with the readability of the model. C++as an hardware modeling language is excellent choice for high-level behavioral analysis of a system (like evaluating different data flow architectures in a microprocessor). However C++ lacks the basic hardware concepts like knowledge of strengths, connections, and concurrent execution which complicates model generation for lower level simulations.

Choosing Verilog, VHDL, or C++ will be based on availability of tools, models, and inhouse expertise. If you are just learning your first HDL language we recommend Verilog because you will be able to quickly become comfortable with the syntax and timing issues of the language:

Verilog Structure This chapter gives a quick overview of the structural and behavioral elements of Verilog and discusses the time flow and time control statements. Verilog differs from regular programming languages (C, Pascal, ...) in 3 main aspects: (1) simulation time concept, (2) multiple threads, and (3) some basic circuit concepts like network connections and primitive gates. If you know how to program in C and you understand basic digital design then learning Verilog will be easy. If you have VeriLogger Pro installed on your computer you can copy and paste the following code segments into a text file and simulate the examples. 2.1 Modules In Verilog, circuit components are designed inside a module. Modules can contain both structural and behavioral statements. Structural statements represent circuit components like logic gates, counters, and microprocessors. Behavioral level statements are programming statements that have no direct mapping to circuit components like loops, ifthen statements, and stimulus vectors which are used to exercise a circuit. Figure 1 shows an example of a circuit and a test bench module. A module starts with the keyword module followed by an optional module name and an optional port list. The key word endmodule ends a module.
`timescale 1ns / 1ps //create a NAND gate out of an AND and an Invertor module some_logic_component (c, a, b); // declare port signals output c; input a, b; // declare internal wire wire d; //instantiate structural logic gates and a1(d, a, b); //d is output, a and b are inputs not n1(c, d); //c is output, d is input endmodule //test the NAND gate module test_bench; //module with no ports reg A, B; wire C; //instantiate your circuit some_logic_component S1(C, A, B); //Behavioral code block generates stimulus to test circuit initial begin A = 1'b0; B = 1'b0; #50 $display("A = %b, B = %b, Nand output C = %b \n", A, B, C); A = 1'b0; B = 1'b1;

#50 A = #50 A = #50 end endmodule

$display("A = %b, B = %b, Nand output C = %b \n", A, B, C); 1'b1; B = 1'b0; $display("A = %b, B = %b, Nand output C = %b \n", A, B, C); 1'b1; B = 1'b1; $display("A = %b, B = %b, Nand output C = %b \n", A, B, C);

Figure 1 shows a simple logic circuit and test bench. 2.2 Structural Design with Gate Primitives and the Delay operator Verilog defines some basic logic gates as part of the language. In Figure 1, module some_logic_component instantiates two gate primitives: the not gate and the and gate. The output of the gate is the first parameter, and the inputs are the rest of the parameters. These primitives are scaleable so you can get multiple input gates just by adding inputs into the parameter list. For example:
nand a1(out1, in1, in2); //2-input NAND gate nand a2(out1, in1, in2, in3, in4, in5); //5-input NAND gate

By default the timing delay for the gate primitives is zero time. You can define the rising delay, falling delay using the #(rise, fall) delay operator. And for tri-state gates you can also define the turn-off delay (transition to high impedance state Z) by using the #(rise, fall, off) delay operator. For example
notif0 #(10,11,27) inv2(c,d,control) //rise=10, fall=11, off=27(not if control=0) nor #(10,11) nor1(c,a,b); //rise=10, fall=11 (nor gate) xnor #(10) xnor1(i,g,h); //rise=10, fall=10 (xnor gate)

Also each of the 3 delays can be defined to have minimum, typical, and a maximum value using the a colon to separate the values like 8:10:12 instead of 10 in the above examples. At run time, the Verilog simulator looks for to see if the +mindelay, +typdelay, or +maxdelay option has been defined so that it will know which of the 3 time values to use. In VeriLogger these options are set using the Project > Project Preferences menu. If none of the options are specified then the typical value is used.
// min:typ:max values defined for the (rise, fall) delays or #(8:10:12, 10:11:13) or1(c,a,b);

The delay operator has one subtle side effect: it swallows narrow input pulses. Normally, the delay operator causes the output response of a gate to be delayed a certain amount of time. However if the input pulse width is shorter then the overall delay of the gate then the change will not be shown on the output. Here is a list of logic primitives defined for Verilog:

Gate

Parameter List

Examples and a1(C,A,B);nand na1(out1,in1,in2,in3,in4);nor #(5) n1(D,A,B);//delay = 5 time unitsxor #(3,4,5) x1(E,A,B);//rise,fall,off delaysnor #(3:4:5) n2(F,A,B);//min:typ:max of delays not inv1(c,a); notif0 inv2(c,a, control);

scalable, requires at nand nor and least 2 inputs(output, or xor xnor input1, input2, , inputx) not buf notif0bufif0 (output, input) control signal active low(output, input, control) control signal active high(output, input, control)

notif1bufif1

not inv1(c,a, control);

2.3 Structural Design with Assignment Statements If you have a lot of random logic, the gate primitives of the previous section are tedious to use because all the internal wires must be declared and hooked up correctly. Sometimes it is easier to just describe a circuit using a single Boolean equation. In Verilog, Boolean equations which have similar timing properties as the gate primitives are defined using a continuous assignment statement. For example, the following code excerpt from Figure 1:
wire d; and a1(d, a, b); not n1(c, d);

can be replaced with one statement:


assign c = !(a && b); //notice that wire d was not used here

Assignments can also be made during the declaration of a wire. In this case the assign keyword is implicitly assumed to be there for example:
wire d; assign d = a || b; //continuous assignment wire d = a || b; //implicit continuous assignment

By default the timing delay for assignment statements is zero time. You can define a propagation delay using the #delay operator just like we did for the gate primitives. The following examples have the exact same timing.
wire c; assign #5 c = a && b; //delay in the continuous assignment

wire #5 c = a && b;

//delay in the implicit assignment

wire #5 c; //delay in the wire declaration assign c = a && b;

To demonstrate the pulse swallowing effect of the delays operator, consider the following senario. In the above examples, if input a changed value at time 10 (and held its value for at least 5 time units), then the output c would change values at time 15. If input a had a value pulse that was shorter then the propagation delay of the assignment then the value on a would not be passed to the output. The delay operator can also use the full rise, fall, and off delays and each delay can have a minimum:typical: maximum value. The following is a valid line of code.
and #(8:10:12, 10:11:13, 26:27:29) a1(c,a,b); //min:typ:max of (rise,fall,off)

Appendix A defines all of the operators that can be used in an assignment statement. 2.4 Structural Design with using Modules Verilog supports hierarchical design by allowing modules to instantiate other modules. For example in Figure1 module test_bench instantiates a component S1 of type some_logic_component. The code is reprinted here for convince:
module test_bench; ... some_logic_component S1(C, A, B); //instantiate a some_logic_component module ... endmodule

By default the timing inside a module is controlled by the module itself. However, modules can be defined to have parameterized delays similar to the #(4,5) delay operator used with gate primitives. In the module definition, use the parameter keyword to create delay variables. Parameters can also be used to change other scalar values in the module. When the module is instantiated then you can choose to override the delay values using the #(parameter) notation. For example:
module some_logic_component (c, a, b); ... //some code parameter andDelay = 2; //default delays parameter invDelay = 2; and #andDelay a1(d, a, b); //using parameter delays not #invDelay n1(c, d); endmodule module test_bench; //module with no ports ... some_logic_component #(5,4) S3(E, A, B); //override andDelay=5, invDelay=4

some_logic_component #(5) invDelay=2 some_logic_component .... endmodule

S2(D, A, B); //override andDelay=5, S1(C, A, B); //uses default delays

Modules also support a special kind of timing called specify blocks which can be used in conjunction with SDF analyzers. Specify blocks also support continuous setup and hold checking. 2.5 Behavioral Design with Initial and Always blocks Behavioral code is used to describe circuits at a more abstract level then the structural level statements we have studied. All Behavioral code occurs within either an initial block or in an always block. A module can contain several initial and always blocks. These behavioral blocks contain statements that control simulation time, data flow statements (like if-then and case statements), and blocking and non-blocking statements. An initial block executes once during a simulation. Initial blocks are usually used to initialize variables and to describe stimulus waveforms which exercise which drive the simulation. An always block continuously repeats its execution during a simulation. Always blocks usually contain behavioral code that models the actual circuit operation. During a simulation each always and each initial block begin to execute at time zero. Each block executes concurrently with each structural statement and all the other behavioral blocks. The following example shows a behavioral SRAM model. The initial block sets the memory cells to zero at startup. The always block executes each time there is a change on the write control line, the chip select line, or the address bus. As an exercise, copy and paste this code into a verilog file and write a test bench to exercise the model. If you are using VeriLogger Pro then you can draw a test bench.
//SRAM Model module sram(CSB,WRB,ABUS,DATABUS); input CSB; // active low chip select input WRB; // active low write control input [11:0] ABUS; // 12-bit address bus inout [7:0] DATABUS; // 8-bit data bus //** internal signals reg [7:0] DATABUS_driver; wire [7:0] DATABUS = DATABUS_driver; reg [7:0] ram[0:4095]; // memory cells integer i; initial //initialize all RAM cells to 0 at startup begin DATABUS_driver = 8'bzzzzzzzz; for (i=0; i < 4095; i = i + 1) ram[i] = 0;

end always @(CSB or WRB or ABUS) begin if (CSB == 1'b0) begin if (WRB == 1'b0) //Start: latch Data on rising edge of CSB or WRB begin DATABUS_driver <= #10 8'bzzzzzzzz; @(posedge CSB or posedge WRB); $display($time," Writing %m ABUS=%b DATA=%b",ABUS,DATABUS); ram[ABUS] = DATABUS; end if (WRB == 1'b1) //Reading from sram (data becomes valid after 10ns) begin #10 DATABUS_driver = ram[ABUS]; $display($time," Reading %m ABUS=%b DATA= %b",ABUS,DATABUS_driver); end end else //sram unselected, stop driving bus after 10ns begin DATABUS_driver <= #10 8'bzzzzzzzz; end end endmodule

Verilog Syntax Details Our goal up to this point has been to teach you how to model some simple circuits before swamping you with all the details about Verilog types, ports, and numbers. But as we do more Behavioral design it becomes easier to make mistakes in this area. Before you begin a big design you might want to get a copy of "Verilog HDL" by Samir Plantikar and memorize Chapters 3, 4, and 7. What follows is just enough information in order to understand the subsequent behavioral code examples. 3.1 Structural Data Types: wire and reg Verilog supports structural data types called nets which model hardware connections between circuit components. The two most common structural data types are wire and reg. The wire nets act like real wires in circuits. The reg type hold their values until another value is put on them, just like a register hardware component. The declarations for wire and reg signals are inside a module but outside any initial or always block. The initial state of a reg is x unknown, and the initial state of a wire is z. Ports:Modules communicate with each other through ports, the signals listed in the parameter list at the top of the module. Ports can be of type in, out, and inout.

Here are 3 simplistic rules for matching the structural data type to the type of port: 1. Use reg as the outputs of Behavioral blocks. If you us a wire then the value will never be seen by other blocks. 2. Use wire for all inputs, inouts, and most outputs of Structural elements. 3. If you need a special strength type operation use special net keyword wand, wor, tir, triand, trior, trireg. 3.2 Behavioral Data Types: integer, real, and time The types in integer and real are convenient data types to use for counting in behavioral code blocks. These data types act like their counter parts in other programming languages. If you eventually plan to synthesize your behavioral code then you would probably want to avoid using these data types because they often synthesize large circuits. The data type time can hold a special simulator value called simulation time which is extracted from the system function $time. The time information can be used to help you debug your simulations. ..... //code fragment from inside a module
integer i, y; real a; real b = 3.5; real c = 4; time simulationTime; initial begin y = 4; i = 5 + y; c = c + 3.5; a = 5.3e4; simulationTime = $time; $display("integer y = %d, i = %f \n", y, i); $display("reals c = %f, a = %e, b= %g \n", c, a, b); $display("time simulationTime = %t \n", simulationTime); end

3.3 Number Syntax Numbers in verilog are in the following format


'

The size is always specified as a decimal number. If no is specified then the default size is at least 32bits and may be larger depending on the machine. Valid base formats are 'b , 'B , 'h , 'H 'd , 'D , 'o , 'O for binary, hexadecimal, decimal, and octal. Numbers consist of strings of digits (0-9, A-F, a-f, x, X, z, Z). The X's mean unknown, and the Z's mean

high impedance If no base format is specified the number is assumed to be a decimal number. Some examples of valid numbers are:
2'b10 'b10 3 8'hAf -16'd47 // // // // // 2 bit binary number at least a 32-bit binary number at least a 32-bit decimal number 8-bit hexadecimal negative decimal number

3.4 Behavioral Design with blocking and non-blocking statements There are 2 kinds of assignment statements: blocking using the = operator, and nonblocking using the <= operator. Blocking assignments act like sequential code statements and execute when they are called. Non-blocking schedule events to happen at some time in the future. This can be confusing because lines that appear after a non-blocking statement execute at the same time as the non-blocking statement. Here are some examples:
#5 x = 1'b0; // blocks for 5 time units, applies value to x, then next line goes y = 1'b1; // blocks, sets y to 1 now, then next statement goes y <= #3 1'b0; // evaluates now, schedules apply y=0 in 3 time units, and next line goes #5 x <= y; // waits for 5 time units, evaluates, // schedules apply at end of current time, and next line goes

The following two code blocks are not equivalent:


// Section 1: Blocking statements execute sequentially #5 a = b; // waits 5 time units, evaluates and applies value to a c = d; // evaluates and applies value to c // Section 2: #5 a <= b; // current time c <= d; // // Non-Blocking statements execute concurrently waits 5 time units, evaluates, schedules apply for end of evaluate, schedules apply for end of current time At end of current time both a and c receive their values

3.6 Arrays, Vectors, and Memories Verilog supports three similar data structures called Arrays, Vectors, and Memories. Arrays are used to hold several objects of the same type. Vectors are used to represent multi-bit busses. And Memories are arrays of vectors which are accessed similar to hardware memories. Read the following examples to determine how to reference and use the different data structures.
//*** Arrays for integer i[3:0]; time x[20:1]; reg r[7:0]; integer, time, reg, and vectors of reg *************** //integer array with a length of 4 //time array with length of 19 //scalar reg array with length of 8

c = r[3]; //the 3rd reg value in array r is assigned to c //*** Vectors are multi-bit words of type reg or net (wire)************ reg [7:0] MultiBitWord1; // 8-bit reg vector with MSB=7 LSB=0 wire [0:7] MultiBitWord2; // 8-bit wire vector with MSB=0 LSB=7 reg [3:0] bitslice; reg a; // single bit vector often referred to as a scalar .... //referencing vectors a = MultiBitWord1[3]; //applies the 3rd bit of MultiBitWord1 to a bitslice = MultiBitWord1[3:0]; //applies the 3-0 bits of MultiBitWord1 to bitslice //*** Memories are arrays of vector reg ******************************** reg [7:0] ram[0:4095]; // 4096 memory cells that are 8 bits wide //code excerpt from Chapter 2 SRAM model input [11:0] ABUS; // 12-bit address bus to access all 4096 memory cells inout [7:0] DATABUS; // 8-bit data bus to wite into and out of a memory cell reg [7:0] DATABUS_driver; wire [7:0] DATABUS = DATABUS_driver; //inout must be driven by a wire .... for (i=0; i < 4095; i = i + 1) // Setting individual memory cells to 0 ram[i] = 0; end .... ram[ABUS] = DATABUS; //writing to a memory cell .... DATABUS_driver = ram[ABUS]; //reading from a memory cell

3.7 Operators Here is a small selection of the Verilog Operators which look similar but have different effects. Logical Operators evaluate to TRUE or FALSE. Bitwise operators act on each bit of the operands to produce a multi-bit result. Unary Reduction operators perform the operation on all bits of the operand to produce a single bit result. Operator Name ! ~ && & & ~& logical negation bitwise negation logical and bitwise and reduction and reduction nand abus = bbus&cbus; abit = &bbus; Examples

|| | | ~| ^ ^ ~^ ^~ ~^ ^~ == === != !== > >> >= < << <= <= =

logical or bitwise or reduction or reduction nor bitwise xor reduction xor bitwise xnor reduction xnor logical equality, result may be unknown if x or z in the input logical equality including x and z logical inequality, result may be unknown if x or z in the input logical inequality including x and z relational greater than shift right by a number of positions relational greater than or equal relational less than shift left by a number of positions relational less than or equal if (a <= b) non blocking assignment statement, schedules assignment for #5 b <= b + 2; future and allows next statement to execute blocking assignment statement, waits until assignment time before allowing next statement to execute #5 a = a + 2; a = shiftvalue >> 2; if (a == b)

Verilog also supports arithmetic, replication, and concatenation operators

Verilog Design Flow


In a typical design flow, the design team will first create an RTL level model of their design and write behavioral test benches that model the other systems that surround their design. They will then perform a series of simulations, fixing problems found during simulation, until they decide that the RTL design has been sufficiently tested. The RTL is then synthesized into a gate-level Verilog netlist which can fed into a place-and-route tool to produce a final chip layout or to generate an FPGA programming file.

Lets use a real-world example to see how this works in practice. Assume youre tasked with building a PCI-based board that performs optical-character-recognition on data from a scanner and communicates with software running on a PC. If its a low-volume application, most of the logic for the board will probably be implemented in an FPGA. Youll probably also need a little glue logic to buffer the input/output (IO) signals that communicate with the PC and the scanner.

Step 1: Create RTL Design Models and Behavioral Test Bench Code
To program the FPGA, youll need to write RTL-level modules that describe the logic for processing image data from the scanner and model the ports that can be read and written to by the PC via the PCI bus. At the end of this process, lets assume you have generated 3 Verilog files that model your FPGA design: pci_interface.v (models ports and communication across PCI bus) ocr_processor.v (communicates with scanner and performs character recognition) fpga.v (top-level module of fpga design that instantiates modules defined in pci_interface.v and ocr_processor.v) To test your design code, youll need to write a behavioral model that generates data in the format provided by the scanner (e.g. models IO from scanner). And youll need to write a bus-functional model (behavioral model that models the bus level IO) of the PC that to test the PCI interface of your board. Lets assume you create the following testbench files: pci_stimulator.v (bus-functional IO model of the PC that reads/writes FPGA ports) scanner.v (generates scanner input to feed the FPGA) testbench.v (top level test bench that instantiates the pci_stimulator, the scanner, and the FPGA top level module, plus any glue logic weve included in the design)

Step 2: Functionally Simulate your Register-Transfer-Level Design


Now that youve got something to test and some basic tests written, its time to simulate the system. During this phase of the design, youll be constantly running simulations, examining the results, and then making changes to your Verilog code to fix bugs you find. This phase is called functional simulation, because its only testing whether the logical (functional) design of the system is correct, but it doesnt test whether the system meets speed requirements. If youre using a command line simulator, you would compile these files with a command line such as the one below. For the purposes of this tutorial, were assuming youre using SynaptiCADs Verilog simulator, simx, but the syntax would be very similar for most verilog simulators. To compile the code and run the simulation from the command line, type:

simx testbench.v scanner.v pci_stimulator.v pci_interface.v ocr_processor.v fpga.v If youre using a graphical debugger with your simulator, all these files should be placed into the source file folder of your Verilog simulators project file, then you would press the Build button to compile the files, followed by the Run button to simulate the design. After the design has finished simulating (or when you encounter a breakpoint), you can look at the simulation log file and waveforms captured during the simulation run to see if there were any problems. Most simulators provide various ways to examine the internal signals of your design to trace down the cause of any errors, so that you make appropriate corrections to your Verilog source files and re-simulate the design. During debug of your design, a graphical debugger is highly recommended, as its much easier to locate and fix bugs using these tools. Steps 1 and 2 are essentially an iterative process and typically most of the design is spent in these two phases. These two steps are fairly high level and are somewhat independent of the target FPGA or ASIC youve decided to use. The exact syntax of commands for the next couple of steps will generally depend more on your choice of FPGA vendor, however.

Step 3: Convert RTL-level files to a Gate-level model with a Synthesizer


After youve successfully fixed all the bugs you can find during functional testing, its time to synthesize your RTL design. You do not need to synthesize your testbench code, only your RTL design code (in fact, most test bench code uses Verilog features that synthesis tools cannot handle). Synthesis is a mostly automated process using a synthesizer tool that converts your RTL-level design source code (pci_interface.v, ocr_processor.v, and fpga.v) into a single gate-level Verilog file (this file is often called timingsim.v) that can be fed into a place-and-route (P&R) tool to create a programming file for your FPGA. The generated gate-level Verilog file will consist of one big module filled with gates connected by wires. This is often referred to as a flattened design, because all the individual modules from your original RTL design has been flattened out into one big module and all hierarchical information is gone.

Step 4: Perform Gate Level simulations with FPGA or ASIC libraries


Now that weve synthesized the design, its time to simulate the gate-level code generated by the synthesizer to check if the synthesizer misunderstood anything we told it to do (generally this occurs if we write some form of improper code that simulates properly at RTL level, but violates a synthesis coding convention). These errors are relatively rare nowadays as there are many good books that cover proper coding techniques for writing synthesizable code and synthesizers have also gotten very good at their job. Gate-level simulations take longer to run than RTL level simulations (especially when SDF timing is included), but fortunately you dont typically need to run many gate-level

simulations since most bugs are logic errors that should have already been caught during the functional simulation phase. You should be able to reuse the same test benches during your gate level simulation that you created for testing the RTL design, with some minor modifications to handle things like expansion of buses into individual bits and possibly some changes to the stimulus to check stressful timing conditions. You will need to add some additional command line options to your simulator to compile a gate-level design. Instead of true Verilog gate level primitives, the gates in the synthesized design file will be vendor gates. These vendor gates are defined in a Verilog library file or directory provided by the FPGA vendor. These gates are mostly just wrappers around the Verilog gate primitives that also include specify blocks where standard delay file (SDF) data can be incorporated to model the timing of the gates. So, to compile the synthesized design file, you will need to tell your simulator where to find the vendor library gate models. FPGA vendor libraries typically come in one of two forms: a single big file that contains all the gate models or a directory with one file per gate model, where the filename matches the name of the gate model. If its a single big file, you can just include this file into the compile options for your simulator with a -v option to specify the vendor library file. For example, assume the vendors library file is called fpga_models.v, you would perform a gate level simulation using a command like: simx testbench.v scanner.v pci_stimulator. timingsim.v v c:\fpga\fpga_models.v (Note were using timingsim.v, the flattened gate-level model, rather than the three RTL level source files now, but were still using the original test bench files to test the design) On the other hand, if your FPGA vendor ships its library models as individual files in a directory called fpga_models_dir, then you would use the -y to specify the vendor library directory. In this case, you would use a simulation command like: simx testbench.v scanner.v pci_stimulator. timingsim.v y c:\fpga\fpga_models_dir

Optional Step: Gate-level simulation with SDF timing information


Gate level simulations can optionally be performed with timing information from an SDF file. The FPGA vendors Place-and-Route tool will generate a separate SDF file that contains estimates of the delay times for the gates in your design based on the way the FPGA was routed (most of the delays in FPGAs are interconnect routing delays rather than delays through the logic gates themselves). The SDF file generated by the Place-and-Route tool can be used along with the synthesized gate-level model file to perform time-based simulations with your Verilog simulator. An $sdf_annotate command can be placed into the gate-level verilog file to

incorporate the timing from the SDF file. These timing simulations are used to detect bugs such as flip flop setup and hold violations. You generally dont need to do exhaustive timing simulations, as your design will probably also be getting checked by a timing analyzer tool. A timing analyzer scans for timing paths in your Verilog gate-level netlist that would cause a timing error in your design. A timing analyzer performs a min-max analysis, so it checks more thoroughly for timing problems than a timing simulation does. In theory, you could even skip gate-level simulations and just use the timing analyzer results to verify your design meets timing requirements, but in practice its a very good idea to perform a timing simulation as an extra check.

Anda mungkin juga menyukai