• Tidak ada hasil yang ditemukan

2.2 4-bit Ripple Carry Counter

Chapter 3. Basic Concepts

3.2 Data Types

45

46

If two signals of unequal strengths are driven on a wire, the stronger signal prevails. For example, if two signals of strength strong1 and weak0 contend, the result is resolved as a strong1. If two signals of equal strengths are driven on a wire, the result is unknown. If two signals of strength strong1 and strong0 conflict, the result is an x. Strength levels are particularly useful for accurate modeling of signal contention, MOS devices, dynamic MOS, and other low-level devices. Only trireg nets can have storage strengths large, medium, and small. Detailed information about strength modeling is provided in Appendix A, Strength Modeling and Advanced Net Definitions.

3.2.2 Nets

Nets represent connections between hardware elements. Just as in real circuits, nets have values continuously driven on them by the outputs of devices that they are connected to.

In Figure 3-1 net a is connected to the output of and gate g1. Net a will continuously assume the value computed at the output of gate g1, which is b & c.

Figure 3-1. Example of Nets

Nets are declared primarily with the keyword wire. Nets are one-bit values by default unless they are declared explicitly as vectors. The terms wire and net are often used interchangeably. The default value of a net is z (except the trireg net, which defaults to x ). Nets get the output value of their drivers. If a net has no driver, it gets the value z.

wire a; // Declare net a for the above circuit

wire b,c; // Declare two wires b,c for the above circuit

wire d = 1'b0; // Net d is fixed to logic value 0 at declaration.

Note that net is not a keyword but represents a class of data types such as wire, wand, wor, tri, triand, trior, trireg, etc. The wire declaration is used most frequently. Other net declarations are discussed in Appendix A, Strength Modeling and Advanced Net Definitions.

3.2.3 Registers

Registers represent data storage elements. Registers retain value until another value is placed onto them. Do not confuse the term registers in Verilog with hardware registers built from edge-triggered flipflops in real circuits. In Verilog, the term register merely

47

means a variable that can hold a value. Unlike a net, a register does not need a driver.

Verilog registers do not need a clock as hardware registers do. Values of registers can be changed anytime in a simulation by assigning a new value to the register.

Register data types are commonly declared by the keyword reg. The default value for a reg data type is x. An example of how registers are used is shown Example 3-1.

Example 3-1 Example of Register

reg reset; // declare a variable reset that can hold its value initial // this construct will be discussed later

begin

reset = 1'b1; //initialize reset to 1 to reset the digital circuit.

#100 reset = 1'b0; // after 100 time units reset is deasserted.

end

Registers can also be declared as signed variables. Such registers can be used for signed arithmetic. Example 3-2 shows the declaration of a signed register.

Example 3-2 Signed Register Declaration

reg signed [63:0] m; // 64 bit signed value integer i; // 32 bit signed value

3.2.4 Vectors

Nets or reg data types can be declared as vectors (multiple bit widths). If bit width is not specified, the default is scalar (1-bit).

wire a; // scalar net variable, default wire [7:0] bus; // 8-bit bus

wire [31:0] busA,busB,busC; // 3 buses of 32-bit width.

reg clock; // scalar register, default

reg [0:40] virtual_addr; // Vector register, virtual address 41 bits wide

Vectors can be declared at [high# : low#] or [low# : high#], but the left number in the squared brackets is always the most significant bit of the vector. In the example shown above, bit 0 is the most significant bit of vector virtual_addr.

48 Vector Part Select

For the vector declarations shown above, it is possible to address bits or parts of vectors.

busA[7] // bit # 7 of vector busA

bus[2:0] // Three least significant bits of vector bus,

// using bus[0:2] is illegal because the significant bit should // always be on the left of a range specification

virtual_addr[0:1] // Two most significant bits of vector virtual_addr

Variable Vector Part Select

Another ability provided in Verilog HDl is to have variable part selects of a vector. This allows part selects to be put in for loops to select various parts of the vector. There are two special part-select operators:

[<starting_bit>+:width] - part-select increments from starting bit

[<starting_bit>-:width] - part-select decrements from starting bit

The starting bit of the part select can be varied, but the width has to be constant. The following example shows the use of variable vector part select:

reg [255:0] data1; //Little endian notation reg [0:255] data2; //Big endian notation reg [7:0] byte;

//Using a variable part select, one can choose parts

byte = data1[31-:8]; //starting bit = 31, width =8 => data[31:24]

byte = data1[24+:8]; //starting bit = 24, width =8 => data[31:24]

byte = data2[31-:8]; //starting bit = 31, width =8 => data[24:31]

byte = data2[24+:8]; //starting bit = 24, width =8 => data[24:31]

//The starting bit can also be a variable. The width has

//to be constant. Therefore, one can use the variable part select //in a loop to select all bytes of the vector.

for (j=0; j<=31; j=j+1)

byte = data1[(j*8)+:8]; //Sequence is [7:0], [15:8]... [255:248]

//Can initialize a part of the vector

data1[(byteNum*8)+:8] = 8'b0; //If byteNum = 1, clear 8 bits [15:8]

49

3.2.5 Integer , Real, and Time Register Data Types

Integer, real, and time register data types are supported in Verilog.

Integer

An integer is a general purpose register data type used for manipulating quantities.

Integers are declared by the keyword integer. Although it is possible to use reg as a general-purpose variable, it is more convenient to declare an integer variable for purposes such as counting. The default width for an integer is the host-machine word size, which is implementation-specific but is at least 32 bits. Registers declared as data type reg store values as unsigned quantities, whereas integers store values as signed quantities.

integer counter; // general purpose variable used as a counter.

initial

counter = -1; // A negative one is stored in the counter

Real

Real number constants and real register data types are declared with the keyword real.

They can be specified in decimal notation (e.g., 3.14) or in scientific notation (e.g., 3e6, which is 3 x 106 ). Real numbers cannot have a range declaration, and their default value is 0. When a real value is assigned to an integer, the real number is rounded off to the nearest integer.

real delta; // Define a real variable called delta initial

begin

delta = 4e10; // delta is assigned in scientific notation delta = 2.13; // delta is assigned a value 2.13

end

integer i; // Define an integer i initial

i = delta; // i gets the value 2 (rounded value of 2.13)

Time

Verilog simulation is done with respect to simulation time. A special time register data type is used in Verilog to store simulation time. A time variable is declared with the keyword time. The width for time register data types is implementation-specific but is at least 64 bits.The system function $time is invoked to get the current simulation time.

time save_sim_time; // Define a time variable save_sim_time initial

save_sim_time = $time; // Save the current simulation time

50

Simulation time is measured in terms of simulation seconds. The unit is denoted by s, the same as real time. However, the relationship between real time in the digital circuit and simulation time is left to the user. This is discussed in detail in Section 9.4, Time Scales.

3.2.6 Arrays

Arrays are allowed in Verilog for reg, integer, time, real, realtime and vector register data types. Multi-dimensional arrays can also be declared with any number of dimensions.

Arrays of nets can also be used to connect ports of generated instances. Each element of the array can be used in the same fashion as a scalar or vector net. Arrays are accessed by

<array_name>[<subscript>]. For multi-dimensional arrays, indexes need to be provided for each dimension.

integer count[0:7]; // An array of 8 count variables

reg bool[31:0]; // Array of 32 one-bit boolean register variables

time chk_point[1:100]; // Array of 100 time checkpoint variables

reg [4:0] port_id[0:7]; // Array of 8 port_ids; each port_id is 5 bits wide

integer matrix[4:0][0:255]; // Two dimensional array of integers

reg [63:0] array_4d [15:0][7:0][7:0][255:0]; //Four dimensional array

wire [7:0] w_array2 [5:0]; // Declare an array of 8 bit vector wire

wire w_array1[7:0][5:0]; // Declare an array of single bit wires

It is important not to confuse arrays with net or register vectors. A vector is a single element that is n-bits wide. On the other hand, arrays are multiple elements that are 1-bit or n-bits wide.

Examples of assignments to elements of arrays discussed above are shown below:

count[5] = 0; // Reset 5th element of array of count variables chk_point[100] = 0; // Reset 100th time check point value

port_id[3] = 0; // Reset 3rd element (a 5-bit value) of port_id array.

matrix[1][0] = 33559; // Set value of element indexed by [1][0] to 33559

array_4d[0][0][0][0][15:0] = 0; //Clear bits 15:0 of the register //accessed by indices [0][0][0][0]

port_id = 0; // Illegal syntax - Attempt to write the entire array

51

matrix [1] = 0; // Illegal syntax - Attempt to write [1][0]..[1][255]

3.2.7 Memories

In digital simulation, one often needs to model register files, RAMs, and ROMs.

Memories are modeled in Verilog simply as a one-dimensional array of registers. Each element of the array is known as an element or word and is addressed by a single array index. Each word can be one or more bits. It is important to differentiate between n 1-bit registers and one n-bit register. A particular word in memory is obtained by using the address as a memory array subscript.

reg mem1bit[0:1023]; // Memory mem1bit with 1K 1-bit words

reg [7:0] membyte[0:1023]; // Memory membyte with 1K 8-bit words(bytes) membyte[511] // Fetches 1 byte word whose address is 511.

3.2.8 Parameters

Verilog allows constants to be defined in a module by the keyword parameter. Parameters cannot be used as variables. Parameter values for each module instance can be overridden individually at compile time. This allows the module instances to be customized. This aspect is discussed later. Parameter types and sizes can also be defined.

parameter port_id = 5; // Defines a constant port_id

parameter cache_line_width = 256; // Constant defines width of cache line

parameter signed [15:0] WIDTH; // Fixed sign and range for parameter // WIDTH

Module definitions may be written in terms of parameters. Hardcoded numbers should be avoided. Parameters values can be changed at module instantiation or by using the defparam statement, which is discussed in detail in Chapter 9, Useful Modeling

Techniques. Thus, the use of parameters makes the module definition flexible. Module behavior can be altered simply by changing the value of a parameter.

Verilog HDL local parameters (defined using keyword localparam -) are identical to parameters except that they cannot be directly modified with the defparam statement or by the ordered or named parameter value assignment. The localparam keyword is used to define parameters when their values should not be changed. For example, the state encoding for a state machine can be defined using localparam. The state encoding cannot be changed. This provides protection against inadvertent parameter redefinition.

localparam state1 = 4'b0001, state2 = 4'b0010, state3 = 4'b0100, state4 = 4'b1000;

52

3.2.9 Strings

Strings can be stored in reg. The width of the register variables must be large enough to hold the string. Each character in the string takes up 8 bits (1 byte). If the width of the register is greater than the size of the string, Verilog fills bits to the left of the string with zeros. If the register width is smaller than the string width, Verilog truncates the leftmost bits of the string. It is always safe to declare a string that is slightly wider than necessary.

reg [8*18:1] string_value; // Declare a variable that is 18 bytes wide initial

string_value = "Hello Verilog World"; // String can be stored // in variable

Special characters serve a special purpose in displaying strings, such as newline, tabs, and displaying argument values. Special characters can be displayed in strings only when they are preceded by escape characters, as shown in Table 3-3.

Table 3-3. Special Characters

Escaped Characters Character Displayed

\n newline

\t tab

%% %

\\ \

\" "

\ooo Character written in 1?3 octal digits

53

Dokumen terkait