- •Contents
- •Instantiating a Module
- •Specifying Time Units
- •Resetting Compiler Directives
- •Declaring Nets
- •Declaring Registers
- •Example: Declaring registers
- •Declaring and Using Integers
- •Declaring and Using Reals
- •Declaring and Using Strings
- •Declaring Vectors
- •Declaring Arrays
- •Declaring and Loading Memories
- •Using Operators
- •Modeling Your Hardware (Gate-Level)
- •Instantiating Gates
- •Specifying Drive Strengths
- •Specifying Gate Delays
- •Assigning Values to Registers (Procedural Assignments)
- •Specifying Intra-Assignment Timing Controls
- •Disabling Named Blocks and Tasks
- •Controlling Timing with Delays
- •Controlling Timing with Event Controls
- •Declaring and Triggering Named Events
- •Overriding Procedural Assignments on Registers
Verilog-XL Modeling Style Guide
Modeling Your Hardware
The following example shows a module that includes input and output port declarations. This module is called flop and has five ports: data, clock, clear, q, and qb.
Example: Defining a module that has ports
module flop (data, clock, clear, q, qb); input data, clock, clear;
output q, qb;
wire data, clock, clear, q, qb;
nand #10 nd1 (a, data, clock, clear), nd2 (b, ndata, clock),
nd4 (d, c, b, clear), nd5 (e, c, nclock), nd6 (f, d, nclock), nd8 (qb, q, f, clear);
nand #9 nd3 (c, a, d), nd7 (q, e, qb);
not #10 iv1 (ndata, data), iv2 (nclock, clock);
endmodule // flop
Declare the ports immediately following the module definition. Verilog HDL supports three types of ports: input, output, and inout (bidirectional). Note that ports can be either scalars or vectors.
This module has three scalar input ports (data, clock, clear) and two scalar output ports (q, qb). Specify the data types for the ports. Verilog HDL’s default data type is wire (unless modified with ‘default_nettype), so if a port is a wire, no data type declaration is needed. Verilog HDL has the following rules for the data types of ports:
■Input and bidirectional ports must be nets.
■Output ports can be either nets or registers.
■Ports can be scalars or vectors.
All ports for module flop are wires, so this declaration is optional.
Instantiating a Module
You can incorporate a copy of one module into another module with a module instantiation statement. You ensure proper connections beween ports of a module instantiation and the module definition by either port ordering or the use of explicit port names. For information on describing module paths, see the Verilog-XL Reference.
The following example shows three modules. The first is instantiated into the second using port ordering, and the second is instantiated into the third using explicit named ports. “See
Step n” comments in the example correspond to descriptive steps that follow the example.
January 2001 |
7 |
Product Version 3.2 |
Verilog-XL Modeling Style Guide
Modeling Your Hardware
Example: Instantiating a module
// The lower-level module |
// See Step 1 |
||
module flop |
(data, clock, clear, q, qb); |
||
input data, clock, clear; |
|
||
output q, qb |
|
|
|
wire data, clock, clear, q, qb; |
|
||
nand #10 |
nd1 |
(a, data, clock, clear), |
|
|
nd2 |
(b, ndata, clock), |
|
|
nd4 |
(d, c, b, clear), |
|
|
nd5 |
(e, c, nclock), |
|
|
nd6 |
(f, d, nclock), |
|
|
nd8 |
(qb, q, f, clear); |
|
nand #9 |
nd3 |
(c, a, d), |
|
|
nd7 |
(q, e, qb); |
|
not #10 |
iv1 |
(ndata, data), |
|
|
iv2 |
(nclock, clock); |
|
endmodule // |
flop |
|
|
// The middle-level module |
|
||
module hardreg (d, clk, clrb, q); |
// See Step 2 |
||
input clk, clrb; |
|
||
input [3:0] d; |
|
||
output [3:0] |
q; |
// See Step 3 |
|
|
flop f1 (d[0],clk,clrb,q[0],); |
||
|
flop f2 (d[1],clk,clrb,q[1],), |
// See Step 4 |
|
|
f3 (d[2],clk,clrb,q[2],), |
|
|
|
f4 (d[3],clk,clrb,q[3],); |
|
|
endmodule // |
hardreg |
|
|
// The higher-level module |
|
||
module harddrive; |
// See Step 5 |
||
|
reg |
clk, clr; |
|
|
reg |
[3:0] data; |
|
|
wire [3:0] q; |
// See Step 6 |
|
|
hardreg h1 (.d(data), .clk(clk), |
||
|
clrb(clr), .q(q), .qb()); |
|
|
initial |
|
|
|
begin |
|
|
|
clr = 1; |
clk = 0; |
|
|
|
.. |
|
|
1.Defines lower-level flop module, a D-type master-slave flip-flop. Note that Verilog HDL’s primitives, such as nand and not, are themselves modules that you instantiate into your modules.
2.Define the middle-level hardreg module (the one that will instantiate the lower-level module). This module defines a 4-bit register by instantiating four flop modules.
3.The first part of the statement is the name of the module as it was defined in the lowerlevel module (flop). The second part is the unique name of the instantiated module as used in the middle-level module (f1). The third part is a list of signals that correspond to the ports for the instantiated module, enclosed in parentheses.
The order of the ports in the module instantiation must agree with the order of ports in the module definition unless you use explicit port names (used later in this example).
January 2001 |
8 |
Product Version 3.2 |
Verilog-XL Modeling Style Guide
Modeling Your Hardware
Represent unconnected ports with null arguments in the port list and include all commas as placeholders.
This statement instantiates a flop—the first of four flop instantiations that together make up a 4-bit register. Note that the qb output port as declared in the definition of the flop module is not used in the instantiations and so it is represented by a comma placeholder in the module-instantiation statement.
4.You can instantiate multiple modules with one statement by separating each instantiation with a comma. This statement instantiates three flops, completing the 4-bit register.
5.Specify the data types for the ports of the modules you plan to instantiate. Verilog HDL’s default data type is wire, so if a port is a wire, you do not need a data type declaration. Verilog HDL has the following rules for the data types of ports of instantiated modules:
You must declare input and bidirectional ports either as registers or nets in the higher-level modules’ definition.
You must declare output and bidirectional ports as nets in the higher-level modules’ definition.
The size of the port declarations in the higher-level module must agree with the size as defined in the lower-level module definition.
The clk, clr, and data ports are all input ports of the middle-level hardreg module, so they must be declared as registers or nets in the higher-level harddrive module. You must declare the instantiated module’s output port q as a net in the higher-level module.
6.If you do not want to depend on ordering the ports properly, you can explicitly provide port names for your module instantiation. Explicit port mapping requires you to specify a period, followed by the name of the port as declared in the lower-level module definition, followed by the port expression for the higher-level module enclosed in parentheses.
The d, clk, clrb, and q ports in the lower-level module are mapped to the data, clk, clr, and q ports in the higher-level module.
Specifying Time Units
To specify time units and precision, use the ‘timescale compiler directive. You can use modules with different time scales together in the same simulation.
The following example shows how you can use modules with different time scales in the same simulation. “See Step n” comments in the example correspond to descriptive steps that follow the example.
January 2001 |
9 |
Product Version 3.2 |
|
Verilog-XL Modeling Style Guide |
|
||
|
|
Modeling Your Hardware |
|
|
|
|
|
|
|
Example: Specifying time units |
|
|
|
|
‘timescale 1 ms / 1 ns |
|
// See Step 1 |
||
module ts_1ms_1ns; |
|
|
|
|
parameter p = 123.456789; |
|
|
|
|
initial |
|
|
|
|
begin |
|
// See Step 2 |
|
|
|
$printtimescale; |
|
|
|
|
$display(“p = %15.9f”,p); |
// See Step 3 |
|
|
|
$printtimescale(ts_1us_1ns); |
|
||
|
$display(“p = %15.9f”,ts_1us_1ns.p); |
// See Step 4 |
||
end |
$display(“p = %15.9f”,$scale(ts_1us_1ns.p)); |
|||
|
|
|
|
|
endmodule // ts_1ms_1ns |
|
// See Step 5 |
|
|
‘timescale 1us / 1ns |
|
|
||
module ts_1us_1ns; |
|
|
|
|
|
parameter p = 123.456789; |
|
|
|
endmodule // ts_1ms_1ns |
|
|
|
|
% verilog timescales.v |
|
|
|
|
Compiling source file “timescales.v” |
|
|
||
Highest level modules: |
|
|
|
|
ts_1ms_1ns |
|
|
|
|
ts_1us_1ns |
|
|
|
|
Time scale of (ts_1ms_1ns) is |
1ms / |
1ns |
|
|
p = |
123.456789000 |
|
|
|
Time scale of (ts_1us_1ns) is |
1us / |
1ns |
|
|
p = |
123.456789000 |
|
|
|
p = |
0.123456789 |
|
|
|
0 simulation events
CPU time: 1.3 secs to compile + 0.2 secs to link + 0.0 secs in simulation
1.Specify the time scale for subsequent modules with the ‘timescale compiler directive. This module has a time unit of 1 millisecond and a precision of 1 nanosecond.
2.Verify the time units and precision for the current scope with $printtimescale.
3.Display the time units and precision for another module with $printtimescale, specifying the name of the module as an argument to the system task. This $printtimescale system task displays the time scale for the ts_1us_1ns module.
4.To scale a time value from a module with a time unit different from that of the current module, specify the $scale system task.
5.Override previous time scales by specifying another ‘timescale directive. The second module has a time unit of 1 microsecond and precision of 1 nanosecond.
Defining Text Substitution Macros
You can define macros with the ‘define compiler directive to make changes to your design more easily. When you compile and simulate your design, Verilog-XL substitutes the macro text for the macro name everywhere in your design. You can override ‘define macro
January 2001 |
10 |
Product Version 3.2 |
Verilog-XL Modeling Style Guide
Modeling Your Hardware
definitions with the +define+ command-line option. Parameters are similar to macros, except that parameters are local to a module.
The following example shows how you can define macros with the ‘define compiler directive. “See Step n” comments in the example correspond to descriptive steps that follow the example. The define construct is illustrated in this example:
Example: Specifying time units
module harddrive; |
|
reg clk, clr; |
|
reg [3:0] data; |
|
wire [3:0] q; |
// See Step 1 |
‘define period 100 |
|
‘define stim #‘period data = 4’b |
// See Step 2 |
event end_first_pass; |
|
hardreg h1 (data, clk, clr, q); |
|
initial |
|
begin |
|
clr = 1; clk = 0; |
|
end |
|
always #(‘period/2) clk = ~clk; |
// See Step 3 |
always @(end_first_pass) clr = ~clr;
initial begin
repeat (2) begin
data = 4’b0000; ‘stim 0001; ‘stim 0010; ‘stim 0011; ‘stim 0100; ‘stim 0101; ‘stim 0110; ‘stim 0111; ‘stim 1000; ‘stim 1001; ‘stim 1010; ‘stim 1011; ‘stim 1100; ‘stim 1101; ‘stim 1110; ‘stim 1111;
#200 ->end_first_pass;
end $finish;
end
endmodule // harddrive
1.Define macros with ‘define when you might want to change a value that appears frequently in your design.
The clock period is used throughout the design, but can be changed in one place because of the period macro.
January 2001 |
11 |
Product Version 3.2 |