ch11.02.htm

来自「介绍asci设计的一本书」· HTM 代码 · 共 490 行 · 第 1/2 页

HTM
490
字号
<HTML>

<HEAD>

  <META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">

  

  <TITLE> 11.2&nbsp;&nbsp;&nbsp;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&nbsp;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&nbsp;&nbsp;&nbsp;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 ::=

&nbsp;&nbsp;\ {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 &quot;equation&quot; 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&nbsp;A. Verilog syntax definitions

are given in Appendix&nbsp;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&nbsp;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

&nbsp;&nbsp;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(&quot;Variable CASE_SENSITIVE= %d&quot;,CASE_SENSITIVE);

$display(&quot;Variable case_sensitive= %d&quot;,case_sensitive);

$display(&quot;Variable \/clock = %d&quot;,\/clock );

$display(&quot;Variable \\a*b = %d&quot;,\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&nbsp;&nbsp;&nbsp;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&nbsp;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&nbsp;&nbsp;&nbsp;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&nbsp;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&nbsp;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 &amp; 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(&quot;i=%0g&quot;,i,&quot; t=%6.2f&quot;,t,&quot; r=%f&quot;,r); 

#2 $display(&quot;TIME=%0d&quot;,$time,&quot; ON=&quot;,pwr_on,

&nbsp;&nbsp;&quot; STABLE=&quot;,pwr_stable,&quot; GOOD=&quot;,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(&quot;T=%2g&quot;, $time,&quot; D=&quot;,D,&quot; Clk=&quot;,Clk,&quot; Q=&quot;,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&nbsp;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> 

&nbsp;&nbsp;#10; a = 0;b = 0;c = 0;d = 0; #10; a = 0;b = 1;c = 1;d = 0;

&nbsp;&nbsp;#10; a = 0;b = 0;c = 1;d = 1; #10; $stop;

<B>end</B> 

<B>always begin</B> 

&nbsp;&nbsp;@(a <B>or</B> b <B>or</B> c <B>or</B> d) e = (a|b)&amp;(c|d);

&nbsp;&nbsp;$display(&quot;T=%0g&quot;,$time,&quot; e=&quot;,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&nbsp;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&nbsp;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 &nbsp;= 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 &lt; 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(&quot;T=%0g&quot;,$time,&quot; vector=&quot;, vector,&quot; nibble=&quot;, nibble);

#2; $display(&quot;T=%0g&quot;,$time,&quot; Bus=%b&quot;,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&nbsp;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(&quot;VideoRam[0] is %b&quot;,VideoRam[0]);

$display(&quot;VideoRam[1] is %b&quot;,VideoRam[1]);

$display(&quot;VideoRam[2] is %b&quot;,VideoRam[2]);

$display(&quot;VideoRam[7] is %b&quot;,VideoRam[7]);

<B>end</B> 

<B>endmodule</B> 

VideoRam[0] is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

VideoRam[1] is xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxz

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?