ch11.02.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 490 行 · 第 1/2 页
HTM
490 行
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">
<TITLE> 11.2 Basics of the Verilog Language</TITLE>
</HEAD><!--#include file="top.html"--><!--#include file="header.html"--><br><!--#include file="AmazonAsic.html"-->
<P><A NAME="pgfId=12099"></A><HR ALIGN="LEFT"></P>
<P><A HREF="CH11.htm">Chapter start</A></P>
<P><A HREF="CH11.01.htm">Previous page</A></P>
<P><A HREF="CH11.03.htm">Next page</A></P>
<H1>11.2 Basics of the Verilog Language</H1>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=618"></A>A Verilog <B>identifier</B>
[<A HREF="../../Verilog/LRM/HTML/02/ch02.7.htm">Verilog LRM2.7</A>], including the
names of variables, may contain any sequence of letters, digits, a dollar
sign <CODE>'$'</CODE> , and the underscore <CODE>'_'</CODE> symbol. The
first character of an identifier must be a letter or underscore; it cannot
be a dollar sign <CODE>'$'</CODE> , for example. We cannot use characters
such as <CODE>'-'</CODE> (hyphen), brackets, or <CODE>'#'</CODE> (for active-low
signals) in Verilog names (<A HREF="../../Verilog/LRM/HTML/02/ch02.7.htm#pgfId=271">escaped
identifiers</A> are an exception). The following is a shorthand way of saying
the same thing:</P>
<PRE>
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</PRE>
<P><P CLASS="Body"><A NAME="pgfId=137495"></A>If we think of <CODE>'::='</CODE>
as an equal sign, then the preceding "equation" defines the syntax
of an identifier. Usually we use the Backus-Naur form (BNF) to write these
equations. We also use the BNF to describe the syntax of VHDL. There is
an explanation of the BNF in Appendix A. Verilog syntax definitions
are given in Appendix B. In Verilog all names, including keywords and
identifiers, are case-sensitive. Special commands for the simulator (a system
task or a system function) begin with a dollar sign <CODE>'$'</CODE> [<A HREF="../../Verilog/LRM/HTML/02/ch02.7.htm">Verilog LRM 2.7</A>]. Here are some
examples of Verilog identifiers:</P>
<PRE><A HREF="../../Code/cd11b.htm#anchor26548895"><IMG SRC="../../Images/HDL.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"></A>
<B>module</B> identifiers;
/* Multiline comments in Verilog
look like C comments and // is OK in here. */
// Single-line comment in Verilog.
<B>reg</B> legal_identifier,two__underscores;
<B>reg</B> _OK,OK_,OK_$,OK_123,CASE_SENSITIVE, case_sensitive;
<B>reg</B> \/clock ,\a*b ; // Add white_space after escaped identifier.
//reg $_BAD,123_BAD; // Bad names even if we declare them!
<B>initial</B> <B>begin</B>
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!
$display("Variable CASE_SENSITIVE= %d",CASE_SENSITIVE);
$display("Variable case_sensitive= %d",case_sensitive);
$display("Variable \/clock = %d",\/clock );
$display("Variable \\a*b = %d",\a*b );
<B>end endmodule</B></PRE>
<P><P CLASS="Body"><A NAME="pgfId=71348"></A>The following is the output
from this model (future examples in this chapter list the simulator output
directly after the Verilog code).</P>
<PRE>
Variable CASE_SENSITIVE= 0
Variable case_sensitive= 1
Variable /clock = 0
Variable \a*b = 0</PRE>
<H2><A NAME="pgfId=12532"></A>11.2.1 Verilog Logic Values</H2>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=29639"></A>Verilog has a predefined
<B>logic-value system or value set </B>[<A HREF="../../Verilog/LRM/HTML/03/ch03.1.htm">Verilog
LRM 3.1</A>] that uses four logic values: <CODE>'0'</CODE> , <CODE>'1'</CODE>
, <CODE>'x'</CODE> , and <CODE>'z'</CODE> (lowercase <CODE>'x'</CODE> and
lowercase <CODE>'z'</CODE> ). The value <CODE>'x'</CODE> represents an uninitialized
or an unknown logic value--an unknown value is either <CODE>'1'</CODE> ,
<CODE>'0'</CODE> , <CODE>'z'</CODE> , or a value that is in a state of change.
The logic value <CODE>'z'</CODE> represents a high-impedance value, which
is usually treated as an <CODE>'x'</CODE> value. Verilog uses a more complicated
internal logic-value system in order to resolve conflicts between different
drivers on the same node. This hidden logic-value system is useful for switch-level
simulation, but for most ASIC simulation and synthesis purposes we do not
need to worry about the internal logic-value system.</P>
<H2><A NAME="pgfId=644"></A>11.2.2 Verilog Data Types</H2>
<P><P CLASS="BodyAfterHead"><A NAME="pgfId=172683"></A>There are several
<B>data types</B> in Verilog--all except one need to be declared before
we can use them. The two main data types are <B>nets</B> and <B>registers</B>
[<A HREF="../../Verilog/LRM/HTML/03/ch03.2.htm">Verilog LRM 3.2</A>]. Nets are
further divided into several net types. The most common and important net
types are: <B>wire</B> and <B>tri</B> (which are identical); <B>supply1</B>
and <B>supply0</B> (which are equivalent to the positive and negative power
supplies respectively). The <CODE>wire</CODE> data type (which we shall
refer to as just <CODE>wire</CODE> from now on) is analogous to a wire in
an ASIC. A <CODE>wire</CODE> cannot store or hold a value. A <CODE>wire</CODE>
must be continuously driven by an assignment statement (see <A HREF="CH11.05.htm">Section 11.5</A>).
The default initial value for a <CODE>wire</CODE> is <CODE>'z'</CODE> [<A HREF="../../Verilog/LRM/HTML/03/ch03.6.htm">Verilog LRM3.6]</A>. There are also <B>integer</B>,
<B>time</B>, <B>event</B>, and <B>real</B> data types.</P>
<PRE><A HREF="../../Code/cd11b.htm#anchor26554241"><IMG SRC="../../Images/HDL.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"></A>
<B>module</B> declarations_1;
<B>wire</B> pwr_good, pwr_on, pwr_stable; // Explicitly declare wires.
<B>integer</B> i; // 32-bit, signed (2's complement).
<B>time</B> t; // 64-bit, unsigned, behaves like a 64-bit reg.
<B>event</B> e; // Declare an event data type.
<B>real</B> r; // Real data type of implementation defined size.
// An assign statement continuously drives a wire:
<B>assign</B> pwr_stable = 1'b1; <B>assign</B> pwr_on = 1; // 1 or 1'b1
<B>assign</B> pwr_good = pwr_on & pwr_stable;
<B>initial</B> <B>begin</B>
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.
$display("i=%0g",i," t=%6.2f",t," r=%f",r);
#2 $display("TIME=%0d",$time," ON=",pwr_on,
" STABLE=",pwr_stable," GOOD=",pwr_good);
$finish; <B>end</B>
<B>endmodule</B>
i=123 t=123.00 r=123.456000
TIME=2 ON=1 STABLE=1 GOOD=1</PRE>
<P><P CLASS="Body"><A NAME="pgfId=115420"></A>A register data type is declared
using the keyword <CODE>reg</CODE> and is comparable to a variable in a
programming language. On the LHS of an assignment a register data type (which
we shall refer to as just <CODE>reg</CODE> from now on) is updated immediately
and holds its value until changed again. The default initial value for a
<CODE>reg</CODE> is <CODE>'x'</CODE> . We can transfer information directly
from a <CODE>wire</CODE> to a <CODE>reg</CODE> as shown in the following
code:</P>
<PRE><A HREF="../../Code/cd11b.htm#anchor26558941"><IMG SRC="../../Images/HDL.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"></A>
<B>module</B> declarations_2;
<B>reg</B> Q, Clk; <B>wire</B> D;
// Drive the wire (D):
<B>assign</B> D = 1;
// At a +ve clock edge assign the value of wire D to the reg Q:
<B>always</B> @(<B>posedge</B> Clk) Q = D;
<B>initial</B> Clk = 0; <B>always</B> #10 Clk = ~ Clk;
<B>initial</B> <B>begin</B> #50; $finish; <B>end</B>
<B>always</B> <B>begin</B>
$display("T=%2g", $time," D=",D," Clk=",Clk," Q=",Q); #10; <B>end</B>
<B>endmodule</B>
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</PRE>
<P><P CLASS="Body"><A NAME="pgfId=57797"></A>We shall discuss assignment
statements in <A HREF="CH11.05.htm">Section 11.5</A>. For now, it is
important to recognize that a <CODE>reg</CODE> is not always equivalent
to a hardware register, flip-flop, or latch. For example, the following
code describes purely combinational logic:</P>
<PRE>
<A HREF="../../Code/cd11b.htm#anchor26560842"><IMG SRC="../../Images/HDL.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"></A>
<B>module</B> declarations_3;
<B>reg</B> a,b,c,d,e;
<B>initial begin</B>
#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; $stop;
<B>end</B>
<B>always begin</B>
@(a <B>or</B> b <B>or</B> c <B>or</B> d) e = (a|b)&(c|d);
$display("T=%0g",$time," e=",e);
<B>end</B>
<B>endmodule</B>
T=10 e=0
T=20 e=1
T=30 e=0</PRE>
<P><P CLASS="Body"><A NAME="pgfId=57856"></A>A single-bit <CODE>wire</CODE>
or <CODE>reg</CODE> is a <B>scalar</B> (the default). We may also declare
a <CODE>wire </CODE>or <CODE>reg</CODE> as a <B>vector </B>with a <B>range</B>
of bits [<A HREF="../../Verilog/LRM/HTML/03/ch03.3.htm">Verilog LRM 3.3</A>].
In some situations we may use implicit declaration for a scalar <CODE>wire</CODE>
; it is the only data type we do not always need to declare. We must use
explicit declaration for a vector <CODE>wire</CODE> or any <CODE>reg</CODE>
. We may access (or <B>expand</B>) the range of bits in a vector one at
a time, using a <B>bit-select</B>, or as a contiguous subgroup of bits (a
continuous sequence of numbers--like a straight in poker) using a <B>part-select</B>
[<A HREF="../../Verilog/LRM/HTML/04/ch04.2.htm">Verilog LRM 4.2</A>]. The following
code shows some examples:</P>
<PRE><A HREF="../../Code/cd11b.htm#anchor26562563"><IMG SRC="../../Images/HDL.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"></A>
<B>module</B> declarations_4;
<B>wire</B> Data; // A scalar net of type wire.
<B>wire</B> [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.
<B>reg</B> [3:0] vector; // A 4-bit vector register.
<B>reg</B> [4:7] nibble; // msb index < lsb index is OK.
<B>integer</B> i;
<B>initial</B> <B>begin</B>
i = 1;
vector = 'b1010; // Vector without an index.
nibble = vector; // This is OK too.
#1; $display("T=%0g",$time," vector=", vector," nibble=", nibble);
#2; $display("T=%0g",$time," Bus=%b",DBus[15:0]);
<B>end</B>
<B>assign</B> DBus [1] = 1; // This is a bit-select.
<B>assign</B> DBus [3:0] = 'b1111; // This is a part-select.
// assign DBus [0:3] = 'b1111; // Illegal : wrong direction.
<B>endmodule</B>
T=1 vector=10 nibble=10
T=3 Bus=zzzzzzzzzzzz1111</PRE>
<P><P CLASS="Body"><A NAME="pgfId=744"></A>There are no multidimensional
arrays in Verilog, but we may declare a <B>memory</B> data type as an <B>array</B>
of registers [<A HREF="../../Verilog/LRM/HTML/03/ch03.8.htm">Verilog LRM 3.8</A>]:</P>
<PRE><A HREF="../../Code/cd11b.htm#anchor26564048"><IMG SRC="../../Images/HDL.gif" WIDTH="32" HEIGHT="32" ALIGN="BOTTOM" NATURALSIZEFLAG="3"></A>
<B>module</B> declarations_5;
<B>reg</B> [31:0] VideoRam [7:0]; // An 8-word by 32-bit wide memory.
<B>initial</B> <B>begin</B>
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:
$display("VideoRam[0] is %b",VideoRam[0]);
$display("VideoRam[1] is %b",VideoRam[1]);
$display("VideoRam[2] is %b",VideoRam[2]);
$display("VideoRam[7] is %b",VideoRam[7]);
<B>end</B>
<B>endmodule</B>
VideoRam[0] is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
VideoRam[1] is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?