11.2 Basics of the Verilog LanguageA Verilog identifier
[Verilog LRM2.7], including the
names of variables, may contain any sequence of letters, digits, a dollar
sign identifier ::= simple_identifier | escaped_identifier simple_identifier ::= [a-zA-Z][a-zA-Z_$] escaped_identifier ::= \ {Any_ASCII_character_except_white_space} white_space white_space ::= space | tab | newline If we think of module identifiers; /* Multiline comments in Verilog look like C comments and // is OK in here. */ // Single-line comment in Verilog. reg legal_identifier,two__underscores; reg _OK,OK_,OK_$,OK_123,CASE_SENSITIVE, case_sensitive; reg \/clock ,\a*b ; // Add white_space after escaped identifier. //reg ,123_BAD; // Bad names even if we declare them! initial begin legal_identifier = 0; // Embedded underscores are OK, two__underscores = 0; // even two underscores in a row. _OK = 0; // Identifiers can start with underscore OK_ = 0; // and end with underscore. OK$ = 0; // $ sign is OK, but beware foreign keyboards. OK_123 =0; // Embedded digits are OK. CASE_SENSITIVE = 0; // Verilog is case-sensitive (unlike VHDL). case_sensitive = 1; \/clock = 0; // An escaped identifier with \ breaks rules, \a*b = 0; // but be careful to watch the spaces! ("Variable CASE_SENSITIVE= %d",CASE_SENSITIVE); ("Variable case_sensitive= %d",case_sensitive); ("Variable \/clock = %d",\/clock ); ("Variable \a*b = %d",\a*b ); end endmodule The following is the output from this model (future examples in this chapter list the simulator output directly after the Verilog code). Variable CASE_SENSITIVE= 0 Variable case_sensitive= 1 Variable /clock = 0 Variable \a*b = 0 11.2.1 Verilog Logic ValuesVerilog has a predefined
logic-value system or value set [Verilog
LRM 3.1] that uses four logic values: 11.2.2 Verilog Data TypesThere are several
data types in Verilog--all except one need to be declared before
we can use them. The two main data types are nets and registers
[Verilog LRM 3.2]. Nets are
further divided into several net types. The most common and important net
types are: wire and tri (which are identical); supply1
and supply0 (which are equivalent to the positive and negative power
supplies respectively). The module declarations_1; wire pwr_good, pwr_on, pwr_stable; // Explicitly declare wires. integer i; // 32-bit, signed (2's complement). time t; // 64-bit, unsigned, behaves like a 64-bit reg. event e; // Declare an event data type. real r; // Real data type of implementation defined size. // An assign statement continuously drives a wire: assign pwr_stable = 1'b1; assign pwr_on = 1; // 1 or 1'b1 assign pwr_good = pwr_on & pwr_stable; initial begin i = 123.456; // There must be a digit on either side r = 123456e-3; // of the decimal point if it is present. t = 123456e-3; // Time is rounded to 1 second by default. ("i=%0g",i," t=%6.2f",t," r=%f",r); #2 ("TIME=%0d",," ON=",pwr_on, " STABLE=",pwr_stable," GOOD=",pwr_good); ; end endmodule i=123 t=123.00 r=123.456000 TIME=2 ON=1 STABLE=1 GOOD=1 A register data type is declared
using the keyword module declarations_2; reg Q, Clk; wire D; // Drive the wire (D): assign D = 1; // At a +ve clock edge assign the value of wire D to the reg Q: always @(posedge Clk) Q = D; initial Clk = 0; always #10 Clk = ~ Clk; initial begin #50; ; end always begin ("T=%2g", ," D=",D," Clk=",Clk," Q=",Q); #10; end endmodule T= 0 D=z Clk=0 Q=x T=10 D=1 Clk=1 Q=x T=20 D=1 Clk=0 Q=1 T=30 D=1 Clk=1 Q=1 T=40 D=1 Clk=0 Q=1 We shall discuss assignment
statements in Section 11.5. For now, it is
important to recognize that a module declarations_3; reg a,b,c,d,e; initial begin #10; a = 0;b = 0;c = 0;d = 0; #10; a = 0;b = 1;c = 1;d = 0; #10; a = 0;b = 0;c = 1;d = 1; #10; ; end always begin @(a or b or c or d) e = (a|b)&(c|d); ("T=%0g",," e=",e); end endmodule T=10 e=0 T=20 e=1 T=30 e=0 A single-bit module declarations_4; wire Data; // A scalar net of type wire. wire [31:0] ABus, DBus; // Two 32-bit-wide vector wires: // DBus[31] = leftmost = most-significant bit = msb // DBus[0] = rightmost = least-significant bit = lsb // Notice the size declaration precedes the names. // wire [31:0] TheBus, [15:0] BigBus; // This is illegal. reg [3:0] vector; // A 4-bit vector register. reg [4:7] nibble; // msb index < lsb index is OK. integer i; initial begin i = 1; vector = 'b1010; // Vector without an index. nibble = vector; // This is OK too. #1; ("T=%0g",," vector=", vector," nibble=", nibble); #2; ("T=%0g",," Bus=%b",DBus[15:0]); end assign DBus [1] = 1; // This is a bit-select. assign DBus [3:0] = 'b1111; // This is a part-select. // assign DBus [0:3] = 'b1111; // Illegal : wrong direction. endmodule T=1 vector=10 nibble=10 T=3 Bus=zzzzzzzzzzzz1111 There are no multidimensional arrays in Verilog, but we may declare a memory data type as an array of registers [Verilog LRM 3.8]: module declarations_5; reg [31:0] VideoRam [7:0]; // An 8-word by 32-bit wide memory. initial begin VideoRam[1] = 'bxz; // We must specify an index for a memory. VideoRam[2] = 1; VideoRam[7] = VideoRam[VideoRam[2]]; // Need 2 clock cycles for this. VideoRam[8] = 1; // Careful! the compiler won't complain about this! // Verify what we entered: ("VideoRam[0] is %b",VideoRam[0]); ("VideoRam[1] is %b",VideoRam[1]); ("VideoRam[2] is %b",VideoRam[2]); ("VideoRam[7] is %b",VideoRam[7]); end endmodule VideoRam[0] is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx VideoRam[1] is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz VideoRam[2] is 00000000000000000000000000000001 VideoRam[7] is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz We may also declare an integer
array or time array in the same way as an array of module declarations_6; integer Number [1:100]; // Notice that size follows name time Time_Log [1:1000]; // - as in an array of reg. // real Illegal [1:10]; // Illegal. There are no real arrays. endmodule 11.2.3 Other Wire TypesThere are the following other Verilog wire types (rarely used in ASIC design) [Verilog LRM 3.7]:
There are also other keywords that may appear in declarations:
11.2.4 NumbersConstant numbers are integer or real constants [Verilog LRM 2.5]. Integer constants are written as where module constants; parameter H12_UNSIZED = 'h 12; // Unsized hex 12 = decimal 18. parameter H12_SIZED = 6'h 12; // Sized hex 12 = decimal 18. // Note: a space between base and value is OK. // Note: `' (single apostrophes) are not the same as the ' character. parameter D42 = 8'B0010_1010; // bin 101010 = dec 42 // OK to use underscores to increase readability. parameter D123 = 123; // Unsized decimal (the default). parameter D63 = 8'o 77; // Sized octal, decimal 63. // parameter ILLEGAL = 1'o9; // No 9's in octal numbers! // A = 'hx and B = 'ox assume a 32 bit width. parameter A = 'h x, B = 'o x, C = 8'b x, D = 'h z, E = 16'h ????; // Note the use of ? instead of z, 16'h ???? is the same as 16'h zzzz. // Also note the automatic extension to a width of 16 bits. reg [3:0] B0011,Bxxx1,Bzzz1; real R1,R2,R3; integer I1,I3,I_3; parameter BXZ = 8'b1x0x1z0z; initial begin B0011 = 4'b11; Bxxx1 = 4'bx1; Bzzz1 = 4'bz1; // Left padded. R1 = 0.1e1; R2 = 2.0; R3 = 30E-01; // Real numbers. I1 = 1.1; I3 = 2.5; I_3 = -2.5; // IEEE rounds away from 0. end initial begin #1; ("H12_UNSIZED, H12_SIZED (hex) = %h, %h",H12_UNSIZED, H12_SIZED); ("D42 (bin) = %b",D42," (dec) = %d",D42); ("D123 (hex) = %h",D123," (dec) = %d",D123); ("D63 (oct) = %o",D63); ("A (hex) = %h",A," B (hex) = %h",B); ("C (hex) = %h",C," D (hex) = %h",D," E (hex) = %h",E); ("BXZ (bin) = %b",BXZ," (hex) = %h",BXZ); ("B0011, Bxxx1, Bzzz1 (bin) = %b, %b, %b",B0011,Bxxx1,Bzzz1); ("R1, R2, R3 (e, f, g) = %e, %f, %g", R1, R2, R3); ("I1, I3, I_3 (d) = %d, %d, %d", I1, I3, I_3); end endmodule H12_UNSIZED, H12_SIZED (hex) = 00000012, 12 D42 (bin) = 00101010 (dec) = 42 D123 (hex) = 0000007b (dec) = 123 D63 (oct) = 077 A (hex) = xxxxxxxx B (hex) = xxxxxxxx C (hex) = xx D (hex) = zzzzzzzz E (hex) = zzzz BXZ (bin) = 1x0x1z0z (hex) = XZ B0011, Bxxx1, Bzzz1 (bin) = 0011, xxx1, zzz1 R1, R2, R3 (e, f, g) = 1.000000e+00, 2.000000, 3 I1, I3, I_3 (d) = 1, 3, -2 11.2.5 Negative NumbersInteger numbers are signed (two's complement) or unsigned. The following example illustrates the handling of negative constants [Verilog LRM 3.2 , 4.1]: module negative_numbers; parameter PA = -12, PB = -'d12, PC = -32'd12, PD = -4'd12; integer IA , IB , IC , ID ; reg [31:0] RA , RB , RC , RD ; initial begin #1; IA = -12; IB = -'d12; IC = -32'd12; ID = -4'd12; RA = -12; RB = -'d12; RC = -32'd12; RD = -4'd12; #1; (" parameter integer reg[31:0]"); ("-12 =",PA,IA,,,RA); (" ",,,,PA,,,,IA,,,,,RA); ("-'d12 =",,PB,IB,,,RB); (" ",,,,PB,,,,IB,,,,,RB); ("-32'd12 =",,PC,IC,,,RC); (" ",,,,PC,,,,IC,,,,,RC); ("-4'd12 =",,,,,,,,,,PD,ID,,,RD); (" ",,,,,,,,,,,PD,,,,ID,,,,,RD); end endmodule parameter integer reg[31:0] -12 = -12 -12 4294967284 fffffff4 fffffff4 fffffff4 -'d12 = 4294967284 -12 4294967284 fffffff4 fffffff4 fffffff4 -32'd12 = 4294967284 -12 4294967284 fffffff4 fffffff4 fffffff4 -4'd12 = 4 -12 4294967284 4 fffffff4 fffffff4 Verilog only "keeps track"
of the sign of a negative constant if it is (1) assigned to an 11.2.6 StringsThe code listings
in this book use module characters; /* " is ASCII 34 (hex 22), double quote. ' is ASCII 39 (hex 27), tick or apostrophe. / is ASCII 47 (hex 2F), forward slash. \ is ASCII 92 (hex 5C), back slash. ` is ASCII 96 (hex 60), accent grave. | is ASCII 124 (hex 7C), vertical bar. There are no standards for the graphic symbols for codes above 128. ´ is 171 (hex AB), accent acute in almost all fonts. " is 210 (hex D2), open double quote, like 66 (in some fonts). " is 211 (hex D3), close double quote, like 99 (in some fonts). ` is 212 (hex D4), open single quote, like 6 (in some fonts). ' is 213 (hex D5), close single quote, like 9 (in some fonts). */ endmodule Here is an example showing the use of string constants [Verilog LRM 2.6]: module text; parameter A_String = "abc"; // string constant, must be on one line parameter Say = "Say \"Hey!\""; // use escape quote \" for an embedded quote parameter Tab = " "; // tab character parameter NewLine = " "; // newline character parameter BackSlash = "\"; // back slash parameter Tick = "'"; // ASCII code for tick in octal // parameter Illegal = "@"; // illegal - no such ASCII code initial begin("A_String(str) = %s ",A_String," (hex) = %h ",A_String); ("Say = %s ",Say," Say \"Hey!\""); ("NewLine(str) = %s ",NewLine," (hex) = %h ",NewLine); ("\(str) = %s ",BackSlash," (hex) = %h ",BackSlash); ("Tab(str) = %s ",Tab," (hex) = %h ",Tab,"1 newline..."); (" "); ("Tick(str) = %s ",Tick," (hex) = %h ",Tick); #1.23; ("Time is %t", ); end endmodule A_String(str) = abc (hex) = 616263 Say = Say \"Hey!\" Say "Hey!" NewLine(str) = (hex) = 0a \(str) = \ (hex) = 5c Tab(str) = (hex) = 09 1 newline... Tick(str) = ' (hex) = 27 Time is 1 Instead of parameters you may
use a define directive that is a compiler directive, and not
a statement [Verilog LRM 16]. The module define; define G_BUSWIDTH 32 // Bus width parameter (G_ for global). /* Note: there is no semicolon at end of a compiler directive. The character ` is ASCII 96 (hex 60), accent grave, it slopes down from left to right. It is not the tick or apostrophe character ' (ASCII 39 or hex 27)*/ wire [`G_BUSWIDTH:0]MyBus; // A 32-bit bus. endmodule |
|||||
|
|||||
|