























Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Introduction to Verilog, Lexical Tokens, Gate Level Modelling, Data Types, Operators, Operands, Modules, Behavioral Modeling, Timing Controls, Procedures Always and Initial Blocks. As you can see in this file, how descriptive above mentioned points are explained in this lecture of computer programming. VU is one of best university for computer science in our country.
Typology: Study notes
1 / 31
This page cannot be seen from the preview
Don't miss anything!
























9
White Space, Comments, Numbers, Identifiers, Operators, Verilog Keywords
Basic Gates, buf, not Gates, Three-State Gates; bufif1, bufif0, notif1, notif
Value Set, Wire, Reg, Input, Output, Inout Integer, Supply0, Supply Time, Parameter
Arithmetic Operators, Relational Operators, Bit-wise Operators, Logical Operators Reduction Operators, Shift Operators, Concatenation Operator, Conditional Operator: “?” Operator Precedence
Literals, Wires, Regs, and Parameters, Bit-Selects “x[3]” and Part-Selects “x[5:3]” Function Calls
Module Declaration, Continuous Assignment, Module Instantiations, Parameterized Modules
Procedural Assignments, Delay in Assignment, Blocking and Nonblocking Assignments begin ... end, for Loops, while Loops, forever Loops, repeat, disable, if ... else if ... else case, casex, casez
Delay Control, Event Control, @, Wait Statement, Intra-Assignment Delay
Always Block, Initial Block
Function Declaration, Function Return Value, Function Call, Function Rules, Example
Registers, Flip-flops, Counters, Multiplexers, Adders/Subtracters, Tri-State Buffers Other Component Inferences
Counters, Shift Registers
Time Scale, Macro Definitions, Include Directive
$display, $strobe, $monitor $time, $stime, $realtime, $reset, $stop, $finish $deposit, $scope, $showscope, $list
Synchronous Test Bench
Verilog HDL is one of the two most common Hardware Description Languages (HDL) used by integrated circuit (IC) designers. The other one is VHDL. HDL’s allows the design to be simulated earlier in the design cycle in order to correct errors or experiment with different architectures. Designs described in HDL are technology-independent, easy to design and debug, and are usually more readable than schematics, particularly for large circuits.
Verilog can be used to describe designs at four levels of abstraction: (i) Algorithmic level (much like c code with if, case and loop statements). (ii) Register transfer level (RTL uses registers connected by Boolean equations). (iii) Gate level (interconnected AND, NOR etc.). (iv) Switch level (the switches are MOS transistors inside gates). The language also defines constructs that can be used to control the input and output of simulation.
More recently Verilog is used as an input for synthesis programs which will generate a gate-level description (a netlist) for the circuit. Some Verilog constructs are not synthesizable. Also the way the code is written will greatly effect the size and speed of the synthesized circuit. Most readers will want to synthesize their circuits, so nonsynthe- sizable constructs should be used only for test benches. These are program modules used to generate I/O needed to simulate the rest of the design. The words “not synthesizable” will be used for examples and constructs as needed that do not synthesize.
There are two types of code in most HDLs: Structural , which is a verbal wiring diagram without storage. assign a=b & c | d; /* “|” is a OR */ assign d = e & (~c); Here the order of the statements does not matter. Changing e will change a.
Procedural which is used for circuits with storage, or as a convenient way to write conditional logic. always @(posedge clk) // Execute the next statement on every rising clock edge. count <= count+1; Procedural code is written like c code and assumes every assignment is stored in memory until over written. For syn- thesis, with flip-flop storage, this type of thinking generates too much storage. However people prefer procedural code because it is usually much easier to write, for example, if and case statements are only allowed in procedural code. As a result, the synthesizers have been constructed which can recognize certain styles of procedural code as actually combinational. They generate a flip-flop only for left-hand variables which truly need to be stored. However if you stray from this style, beware. Your synthesis will start to fill with superfluous latches.
This manual introduces the basic and most common Verilog behavioral and gate-level modelling constructs, as well as Verilog compiler directives and system functions. Full description of the language can be found in Cadence Verilog-XL Reference Manual and Synopsys HDL Compiler for Verilog Reference Manual. The latter emphasizes only those Verilog constructs that are supported for synthesis by the Synopsys Design Compiler synthesis tool.
In all examples, Verilog keyword are shown in boldface. Comments are shown in italics.
Primitive logic gates are part of the Verilog language. Two properties can be specified, drive_strength and delay.
Drive_strength specifies the strength at the gate outputs. The strongest output is a direct connection to a source, next comes a connection through a conducting transistor, then a resistive pull-up/down. The drive strength is usually not specified, in which case the strengths defaults to strong1 and strong0. Refer to Cadence Verilog-XL Reference Man- ual for more details on strengths.
D elays : If no delay is specified, then the gate has no propagation delay; if two delays are specified, the first represent the rise delay, the second the fall delay; if only one delay is specified, then rise and fall are equal. Delays are ignored in synthesis. This method of specifying delay is a special case of “Parameterized Modules” on page 11. The parame- ters for the primitive gates have been predefined as delays.
These implement the basic logic gates. They have one output and one or more inputs. In the gate instantiation syntax shown below, GATE stands for one of the keywords and, nand, or, nor, xor, xnor.
These implement buffers and inverters, respectively. They have one input and one or more outputs. In the gate instan- tiation syntax shown below, GATE stands for either the keyword buf or not
These implement 3-state buffers and inverters. They propagate z (3-state or high-impedance) if their control signal is deasserted. These can have three delay specifications: a rise time, a fall time, and a time to go into 3-state.
Syntax GATE (drive_strength) # (delays) instance_name1(output, input_1, input_2,..., input_N), instance_name2(outp,in1, in2,..., inN); Delays is
Example 3.
and c1 (o, a, b, c, d); // 4-input AND called c1 and c2 (p, f g); // a 2-input AND called c2. or #(4, 3) ig (o, a, b); /* or gate called ig (instance name); rise time = 4, fall time = 3 */ xor #(5) xor1 (a, b, c); // a = b XOR c after 5 time units xor ( pull1 , strong0 ) #5 (a,b,c); /* Identical gate with pull-up strength pull1 and pull-down strength strong0. */
Syntax
GATE (drive_strength) # (delays) instance_name1(output_1, output_2, ..., output_n, input), instance_name2(out1, out2, ..., outN, in);
Example 3. not #(5) not_1 (a, c); // a = NOT c after 5 time units buf c1 (o, p, q, r, in); // 5-output and 2-output buffers c2 (p, f g);
Example 3. bufif0 #(5) not_1 (BUS, A, CTRL); /* BUS = A 5 time units after CTRL goes low. */ notif1 #(3,4,6) c1 (bus, a, b, cntr); /* bus goes tri-state 6 time units after ctrl goes low. */
BUS = Z En
A
CTRL=
bufif
En
notif
En
notif
En
bufif
Verilog consists of only four basic values. Almost all Verilog data types store all these values: 0 (logic zero, or false condition) 1 (logic one, or true condition) x (unknown logic value) x and z have limited use for synthesis. z (high impedance state)
A wire represents a physical wire in a circuit and is used to connect gates or modules. The value of a wire can be read, but not assigned to, in a function or block. See “Functions” on p. 19, and “Procedures: Always and Initial Blocks” on p. 18. A wire does not store its value but must be driven by a continuous assignment statement or by con- necting it to the output of a gate or module. Other specific types of wires include: wand (wired-AND);:the value of a wand depend on logical AND of all the drivers connected to it. wor (wired-OR);: the value of a wor depend on logical OR of all the drivers connected to it. tri (three-state;): all drivers connected to a tri must be z, except one (which determines the value of the tri).
A reg (register) is a data object that holds its value from one procedural assignment to the next. They are used only in functions and procedural blocks. See “Wire” on p. 4 above. A reg is a Verilog variable type and does not necessarily imply a physical register. In multi-bit registers, data is stored as unsigned numbers and no sign extension is done for what the user might have thought were two’s complement numbers.
These keywords declare input, output and bidirectional ports of a module or task. Input and inout ports are of type wire. An output port can be configured to be of type wire , reg , wand , wor or tri. The default is wire.
Syntax
wire [msb:lsb] wire_variable_list; wand [msb:lsb] wand_variable_list; wor [msb:lsb] wor_variable_list; tri [msb:lsb] tri_variable_list;
Example 4. wire c // simple wire wand d; assign d = a; // value of d is the logical AND of assign d = b; // a and b wire [9:0] A; // a cable (vector) of 10 wires.
Syntax
reg [msb:lsb] reg_variable_list;
Example 4. reg a; // single 1-bit register variable reg [7:0] tom; // an 8-bit vector; a bank of 8 registers. reg [5:0] b, c; // two 6-bit variables
Syntax
input [msb:lsb] input_port_list; output [msb:lsb] output_port_list; inout [msb:lsb] inout_port_list;
Example 4. module sample(b, e, c, a); // See “Module Instantiations” on p. 10 input a; // An input which defaults to wire. output b, e; // Two outputs which default to wire output [1:0] c; /* A two-it output. One must declare its type in a separate statement. */ reg [1:0] c; // The above c port is declared as reg.
These perform arithmetic operations. The + and - can be used as either unary (-z) or binary (x-y) operators.
Relational operators compare two operands and return a single bit 1or 0. These operators synthesize into comparators. Wire and reg variables are positive Thus (-3’b001) = = 3’b111 and (-3d001)>3d110. However for integers -1< 6.
Bit-wise operators do a bit-by-bit comparison between two operands. However see“Reduction Operators” on p. 7.
Logical operators return a single bit 1 or 0. They are the same as bit-wise operators only for single bit operands. They can work on expressions, integers or groups of bits, and treat all values that are nonzero as “1”. Logical operators are typically used in conditional ( if ... else ) statements since they work with expressions.
Operators
Example 5. parameter n = 4; reg [3:0] a, c, f, g, count; f = a + c; g = c - n; count = (count +1)%16; //C an count 0 thru 15.
Operators
< (less than) <= (less than or equal to) > (greater than) >= (greater than or equal to) == (equal to) != (not equal to)
Example 5. if (x = = y) e = 1; else e = 0; // Compare in 2’s compliment; a>b reg [3:0] a,b; if (a[3]= = b[3]) a[2:0] > b[2:0]; else b[3];
Equivalent Statement
e = (x == y);
Operators
~ (bitwise NOT) & (bitwise AND) | (bitwise OR) ^ (bitwise XOR) ~^ or ^~(bitwise XNOR)
Example 5.
module and2 (a, b, c); input [1:0] a, b; output [1:0] c; assign c = a & b; endmodule
b(1)
a(1)
b(0)
a( c(
c(1)
2
2
a
b
Operators
! (logical NOT) && (logical AND) || (logical OR)
Example 5. wire [7:0] x, y, z; // x, y and z are multibit variables. reg a;
... if ((x == y) && (z)) a = 1; // a = 1 if x equals y, and z is nonzero.
5.5. Reduction Operators
Reduction operators operate on all the bits of an operand vector and return a single-bit value. These are the unary (one argument) form of the bit-wise operators above.
5.6. Shift Operators Shift operators shift the first operand by the number of bits specified by the second operand. Vacated positions are filled with zeros for both left and right shifts (There is no sign extension).
5.7. Concatenation Operator The concatenation operator combines two or more operands to form a larger vector.
5.8. Replication Operator
The replication operator makes multiple copies of an item.
For synthesis, Synopsis did not like a zero replication. For example:- parameter n=5, m=5; assign x= {(n-m){a}}
Operators
& (reduction AND) | (reduction OR) ~& (reduction NAND) ~| (reduction NOR) ^ (reduction XOR) ~^ or ^~(reduction XNOR)
Example 5. module chk_zero (a, z); input [2:0] a; output z; assign z = ~| a; // Reduction NOR endmodule
a(0) a(1) a(2)
a z 3
Operators
<< (shift left) >> (shift right)
Example 5. assign c = a << 2; /* c = a shifted left 2 bits; vacant positions are filled with 0’s */
Operators
{ }(concatenation)
Example 5. wire [1:0] a, b; wire [2:0] x; wire [3;0] y, Z; assign x = {1’b0, a}; // x[2]=0, x[1]=a[1], x[0]=a[0] assign y = {a, b}; /* y[3]=a[1], y[2]=a[0], y[1]=b[1], y[0]=b[0] */
assign {cout, y} = x + Z; // Concatenation of a result
Operators
{n{item}} (n fold replication of an item)
Example 5. wire [1:0] a, b; wire [4:0] x; assign x = {2{1’b0}, a}; // Equivalent to x = {0,0,a } assign y = {2{a}, 3{b}}; //Equivalent to y = {a,a,b,b}
Literals are constant-valued operands that can be used in Verilog expressions. The two common Verilog literals are: (a) String: A string literal is a one-dimensional array of characters enclosed in double quotes (“ “). (b) Numeric: constant numbers specified in binary, octal, decimal or hexadecimal.
Wires, regs and parameters can also be used as operands in Verilog expressions. These data objects are described in more detail in Sect. 4..
Bit-selects and part-selects are a selection of a single bit and a group of bits, respectively, from a wire, reg or parame- ter vector using square brackets “[ ]”. Bit-selects and part-selects can be used as operands in expressions in much the same way that their parent data objects are used.
The return value of a function can be used directly in an expression without first assigning it to a register or wire var- iable. Simply place the function call as one of the operands. Make sure you know the bit width of the return value of the function call. Construction of functions is described in “Functions” on page 19
Number Syntax
n’Fddd..., where n - integer representing number of bits F - one of four possible base formats: b (binary), o (octal), d (decimal), h (hexadecimal). Default is d. dddd - legal digits for the base format
Example 6.
“time is”// string literal 267 // 32-bit decimal number 2 ’b 01 // 2-bit binary 20 ’h B36F// 20-bit hexadecimal number ‘o 62 // 32-bit octal number
Syntax
variable_name[index] variable_name[msb:lsb]
Example 6. reg [7:0] a, b; reg [3:0] ls; reg c ; c = a[7] & b[7] ; // bit-selects ls = a[7:4] + b[3:0]; // part-selects
Syntax
function_name (argument_list)
Example 6. assign a = b & c & chk_bc(c, b);// chk_bc is a function
... /* Definition of the function */ function chk_bc;// function definition input c,b;
endfunction
A module is the principal design entity in Verilog. The first line of a module declaration specifies the name and port list (arguments). The next few lines specifies the i/o type ( input , output or inout , see Sect. 4.4. ) and width of each port. The default port width is 1 bit.
Then the port variables must be declared wire , wand ,.. ., reg (See Sect. 4. ). The default is wire. Typically inputs are wire since their data is latched outside the module. Outputs are type reg if their signals were stored inside an always or initial block (See Sect. 10. ).
The continuous assignment is used to assign a value onto a wire in a module. It is the normal assignment outside of always or initial blocks (See Sect. 10. ). Continuous assignment is done with an explicit assign statement or by assigning a value to a wire during its declaration. Note that continuous assignment statements are concurrent and are continuously executed during simulation. The order of assign statements does not matter. Any change in any of the right-hand-side inputs will immediately change a left-hand-side output.
Module declarations are templates from which one creates actual objects (instantiations). Modules are instantiated inside other modules, and each instantiation creates a unique object from the template. The exception is the top-level module which is its own instantiation.
The instantiated module’s ports must be matched to those defined in the template. This is specified:
or(ii) by position, placing the ports in exactly the same positions in the port lists of both the template and the instance.
Syntax
module module_name (port_list); input [msb:lsb] input_port_list; output [msb:lsb] output_port_list; inout [msb:lsb] inout_port_list; ... statements ... endmodule
Example 7.
module add_sub(add, in1, in2, oot); input add; // defaults to wire input [7:0] in1, in2; wire in1, in2; output [7:0] oot; reg oot; ... statements ... endmodule
oot
add
in
in
add_sub
8
8 8
Syntax
wire wire_variable = value ; assign wire_variable = expression ;
Example 7. wire [1:0] a = 2’b01; // assigned on declaration assign b = c & d; // using assign statement assign d = x | y; /* The order of the assign statements does not matter. */
c x (^) d b y
c
Verilog has four levels of modelling:
Procedural assignments are assignment statements used within Verilog procedures ( always and initial blocks). Only reg variables and integers (and their bit/part-selects and concatenations) can be placed left of the “=” in procedures. The right hand side of the assignment is an expression which may use any of the operator types described in Sect. 5.
In a delayed assignment ∆ t time units pass before the statement is executed and the left-hand assignment is made. With intra-assignment delay , the right side is evaluated immediately but there is a delay of ∆t before the result is place in the left hand assignment. If another procedure changes a right-hand side signal during ∆t, it does not effect the output. Delays are not supported by synthesis tools.
Procedural (blocking) assignments (=) are done sequentially in the order the statements are written. A second assignment is not started until the preceding one is complete. See also Sect. 9.4.
Syntax for Procedural Assignment variable = expression Delayed assignment #∆ t variable = expression; Intra-assignment delay variable = #∆ t expression;
Example 8. reg [6:0] sum; reg h, ziltch; sum[7] = b[7] ^ c[7]; // execute now.
after 15 time units. */ #10 hat = b&c; /* 10 units after ziltch changes, b&c is evaluated and hat changes. */
Syntax Blocking variable = expression; variable = #∆ t expression; grab inputs now, deliver ans. later. #∆ t variable = expression; grab inputs later, deliver ans. later
Example 8 .2. For simulation initial begin a=1; b=2; c=3; #5 a = b + c; // wait for 5 units, and execute a= b + c =5. d = a; // Time continues from last line, d=5 = b+c at t=5.
Example 0 .1. For synthesis always @( posedge clk ) begin Z=Y; Y=X; // shift register y=x; z=y; // parallel ff.
1D C
1D C
1D C
x (^) 1D y z C
8.4. Nonblocking (RTL) Assignments (see below for synthesis)
RTL (nonblocking) assignments (<=), which follow each other in the code, are done in parallel. The right hand side of nonblocking assignments is evaluated starting from the completion of the last blocking assignment or if none, the start of the procedure. The transfer to the left hand side is made according to the delays. A delay in a non-blocking statement will not delay the start of any subsequent statement blocking or non-blocking. A good habit is to use “<=” if the same variable appears on both sides of the equal sign (Example 0 .1 on page 13).
The following example shows interactions between blocking and non-blocking for simulation. Do not mix the two types in one procedure for synthesis.
8.5. begin ... end begin ... end block statements are used to group several statements for use where one statement is syntactically allowed. Such places include functions, always and initial blocks, if , case and for statements. Blocks can optionally be named. See “disable” on page 15) and can include register, integer and parameter declarations.
- One must not mix “<=” or “=” in the same procedure. - “<=” best mimics what physical flip-flops do; use it for “always @ (posedge clk ..) type procedures. - “=” best corresponds to what c/c++ code would do; use it for combinational procedures.
Syntax Non-Blocking variable <= expression; variable <= #∆ t expression; #∆ t variable <= expression;
Example 0 .1. For simulation initial begin #3 b <= a; /* grab a at t=0 Deliver b at t=3. #6 x <= b + c; // grab b+c at t=0, wait and assign x at t=6. x is unaffected by b’s change. * /
Example 0 .2. For synthesis always @( posedge clk ) begin Z <= Y; Y <= X; // shift register y <= x; z <= y; // also a shift register.
1D C
1D C
1D C
1D C
x y z
Example 8 .3. Use <= to transform a variable into itself. reg G[7:0] ; always @( posedge clk ) G <= { G[6:0], G[7]}; // End around rotate 8-bit register.
Syntax
Non-Blocking variable <= expression; variable <= #∆ t expression; ?#∆ t variable <=expression; Blocking variable = expression; variable = #∆ t expression; #∆ t variable = expression;
Example 8 .4 for simulation only initial begin a=1; b=2; c=3; x=4; #5 a = b + c; // wait for 5 units, then grab b,c and execute a=2+3. d = a; // Time continues from last line, d=5 = b+c at t=5. x <= #6 b + c;// grab b+c now at t=5 , don’t stop, make x=5 at t=11. b <= #2 a; /* grab a at t=5 (end of last blocking statement). Deliver b=5 at t=7. previous x is unaffected by b change. */ y <= #1 b + c;// grab b+c at t=5 , don’t stop, make x=5 at t=6. #3 z = b + c; // grab b+c at t=8 (#5+#3) , make z=5 at t=8. w <= x // make w=4 at t=8. Starting at last blocking assignm.
8.10. disable Execution of a disable statement terminates a block and passes control to the next statement after the block. It is like the C break statement except it can terminate any loop, not just the one in which it appears. Disable statements can only be used with named blocks.
8.11. if ... else if ... else The if ... else i f ... else statements execute a statement or block of statements depending on the result of the expression following the if. If the conditional expressions in all the if’s evaluate to false, then the statements in the else block, if present, are executed. There can be as many else if statements as required, but only one if block and one else block. If there is one statement in a block, then the begin .. end statements may be omitted. Both the else if and else statements are optional. However if all possibilities are not specifically covered, synthesis will generated extra latches.
Syntax
repeat (number_of_times) begin ... statements ... end
Example 8.
repeat (2) begin // after 50, a = 00, #50 a = 2’ b 00; // after 100, a = 01, #50 a = 2’ b 01; // after 150, a = 00, end // after 200, a = 01
Syntax
disable block_name;
Example 8.
begin : accumulate forever begin @( posedge clk); a = a + 1; if (a == 2’b0111) disable accumulate; end end
Syntax
if (expression) begin ... statements ... end else if (expression) begin ... statements ... end ... more else if blocks ... else begin ... statements ... end
Example 8.
if (alu_func == 2’b00) aluout = a + b; else if (alu_func == 2’b01) aluout = a - b; else if (alu_func == 2’b10) aluout = a & b; else // alu_func == 2’b aluout = a | b;
if (a == b) // This if with no else will generate begin // a latch for x and ot. This is so they x = 1; // will hold there old value if (a != b). ot = 4’b1111; end
8.12. case
The case statement allows a multipath branch based on comparing the expression with a list of case choices. Statements in the default block executes when none of the case choice comparisons are true (similar to the else block in the if ... else if ... else). If no comparisons , including delault, are true, synthesizers will generate unwanted latches. Good practice says to make a habit of puting in a default whether you need it or not. If the defaults are dont cares, define them as ‘x’ and the logic minimizer will treat them as don’t cares. Case choices may be a simple constant or expression, or a comma-separated list of same.
8.13. casex In casex (a) the case choices constant “a” may contain z, x or? which are used as don’t cares for comparison. With case the corresponding simulation variable would have to match a tri-state, unknown, or either signal. In short, case uses x to compare with an unknown signal. Casex uses x as a don’t care which can be used to minimize logic.
8.14. casez
Casez is the same as casex except only? and z (not x) are used in the case choice constants as don’t cares. Casez is favored over casex since in simulation, an inadvertent x signal, will not be matched by a 0 or 1 in the case choice.
Syntax
case (expression) case_choice1: begin ... statements ... end case_choice2: begin ... statements ... end ... more case choices blocks ... default : begin ... statements ... end endcase
Example 0. case (alu_ctr) 2’b00: aluout = a + b; 2’b01: aluout = a - b; 2’b10: aluout = a & b; default : aluout = 1’bx; // Treated as don’t cares for endcase // minimum logic generation.
Example 0. case (x, y, z) 2’b00: aluout = a + b; // case if x or y or z is 2’b00. 2’b01: aluout = a - b; 2’b10: aluout = a & b; default : aluout = a | b; endcase
Syntax
same as for case statement (Section 8.10)
Example 8. casex (a) 2’b1x: msb = 1; // msb = 1 if a = 10 or a = 11 // If this were case(a) then only a=1x would match. default : msb = 0; endcase
Syntax
same as for case statement (Section 8.10)
Example 8.
case z (d) 3’b1??: b = 2’b11; // b = 11 if d = 100 or greater 3’b01?: b = 2’b10; // b = 10 if d = 010 or 011 default : b = 2’b00; endcase
The always block is the primary construct in RTL modeling. Like the continuous assignment, it is a concurrent statement that is continuously executed during simulation. This also means that all always blocks in a module execute simultaneously. This is very unlike conventional programming languages, in which all statements execute sequen- tially. The always block can be used to imply latches, flip-flops or combinational logic. If the statements in the always block are enclosed within begin ... end , the statements are executed sequentially. If enclosed within the fork ... join , they are executed concurrently (simulation only).
The always block is triggered to execute by the level, positive edge or negative edge of one or more signals (sepa- rate signals by the keyword or ). A double-edge trigger is implied if you include a signal in the event list of the always statement. The single edge-triggers are specified by posedge and negedge keywords.
Procedures can be named. In simulation one can disable named blocks. For synthesis it is mainly used as a com- ment.
The initial block is like the always block except that it is executed only once at the beginning of the simulation. It is typically used to initialize variables and specify signal waveforms during simulation. Initial blocks are not supported for synthesis.
Syntax 1
always @(event_1 or event_2 or ...) begin ... statements ... end
Example 10.
always @(a or b) // level-triggered; if a or b changes levels always @( posedge clk); // edge-triggered: on +ve edge of clk
see previous sections for complete examples
Syntax 2
always @(event_1 or event_2 or ...) begin: name_for_block ... statements ... end
Syntax
initial begin ... statements ... end
Example 10.
inital begin clr = 0; // variables initialized at clk = 1; // beginning of the simulation end
inital // specify simulation waveforms begin a = 2’b00; // at time = 0, a = 00 #50 a = 2’b01; // at time = 50, a = 01 #50 a = 2’b10; // at time = 100, a = 10 end
Functions are declared within a module, and can be called from continuous assignments, always blocks or other func- tions. In a continuous assignment, they are evaluated when any of its declared inputs change. In a procedure, they are evaluated when invoked. Functions describe combinational logic, and by do not generate latches. Thus an if without an else will simulate as though it had a latch but synthesize without one. This is a particularly bad case of synthesis not following the simula- tion. It is a good idea to code functions so they would not generate latches if the code were used in a procedure. Functions are a good way to reuse procedural code, since modules cannot be invoked from a procedure.
A function declaration specifies the name of the function, the width of the function return value, the function input arguments, the variables (reg) used within the function, and the function local parameters and integers.
When you declare a function, a variable is also implicitly declared with the same name as the function name, and with the width specified for the function name (The default width is 1-bit). This variable is “my_func” in Example 11 .1 on page 19. At least one statement in the function must assign the function return value to this variable.
As mentioned in Sect. 6.4. , a function call is an operand in an expression. A function call must specify in its terminal list all the input parameters.
The following are some of the general rules for functions:
Syntax, Function Declaration
function [msb:lsb] function_name; input [msb:lsb] input_arguments; reg [msb:lsb] reg_variable_list; parameter [msb:lsb] parameter_list; integer [msb:lsb] integer_list; ... statements ... endfunction
Example 11.
function [7:0] my_func; // function return 8-bit value input [7:0] i; reg [4:0] temp; integer n; temp= i[7:4] | ( i[3:0]);
endfunction