ch11.13.htm

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

HTM
485
字号
<HTML>

<HEAD>

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

  

  <TITLE> 11.13&nbsp;&nbsp;&nbsp;Other Verilog Features</TITLE>

</HEAD><!--#include file="top.html"--><!--#include file="header.html"--><br><!--#include file="AmazonAsic.html"-->



<P><A NAME="pgfId=69130"></A><HR ALIGN="LEFT"></P>

<P><A HREF="CH11.htm">Chapter&nbsp;start</A></P>

<P><A HREF="CH11.12.htm">Previous page</A></P>

<P><A HREF="CH11.14.htm">Next page</A></P>

<H1>11.13&nbsp;&nbsp;&nbsp;Other Verilog Features</H1>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=123421"></A>This section covers

some of the more advanced Verilog features. <B>System tasks</B> and functions

are defined as part of the IEEE Verilog standard [Verilog LRM14].</P>

<H2><A NAME="pgfId=125062"></A>11.13.1&nbsp;&nbsp;&nbsp;Display Tasks</H2>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=120626"></A>The following code

illustrates the <B>display system tasks</B> [Verilog LRM 14.1]:</P>

<PRE>

<B>module</B> test_display; // display system tasks:

<B>initial</B> <B>begin</B> $display (&quot;string, variables, or expression&quot;);

/* format specifications work like printf in C:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%d=decimal %b=binary %s=string %h=hex %o=octal

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%c=character %m=hierarchical name %v=strength %t=time format

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%e=scientific %f=decimal %g=shortest

examples: %d uses default width %0d uses minimum width

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%7.3g uses 7 spaces with 3 digits after decimal point */

// $displayb, $displayh, $displayo print in b, h, o formats

// $write, $strobe, $monitor also have b, h, o versions

$write(&quot;write&quot;); // as $display, but without newline at end of line

$strobe(&quot;strobe&quot;); // as $display, values at end of simulation cycle

$monitor(v); // disp. @change of v (except v= $time,$stime,$realtime)

$monitoron; $monitoroff; // toggle monitor mode on/off

<B>end</B> <B>endmodule</B></PRE>

<H2><A NAME="pgfId=120892"></A>11.13.2&nbsp;&nbsp;&nbsp;File I/O Tasks</H2>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=125068"></A>The following example

illustrates the <B>file I/O system tasks</B> [Verilog LRM 14.2]:</P>

<PRE>

<B>module</B> file_1; <B>integer</B> f1, ch; <B>initial</B> <B>begin</B> f1 = $fopen(&quot;f1.out&quot;);

<B>if</B>(f1==0) $stop(2); <B>if</B>(f1==2)$display(&quot;f1 open&quot;); 

ch = f1|1; $fdisplay(ch,&quot;Hello&quot;); $fclose(f1); <B>end</B> <B>endmodule</B>

&gt; vlog file_1.v

&gt; vsim -c file_1

# Loading work.file_1

VSIM 1&gt; run 10

# f1 open

# Hello

VSIM 2&gt; q

&gt; more f1.out

Hello

&gt;</PRE>

<P><P CLASS="Body"><A NAME="pgfId=120018"></A>The <CODE>$fopen</CODE> system

task returns a 32-bit unsigned integer called a <B>multichannel descriptor</B>

(<CODE> f1</CODE> in this example) unique to each file. The multichannel

descriptor contains 32 flags, one for each of 32 possible channels or files

(subject to limitations of the operating system). Channel 0 is the standard

output (normally the screen), which is always open. The first call to <CODE>$fopen</CODE>

opens channel 1 and sets bit 1 of the multichannel descriptor. Subsequent

calls set higher bits. The file I/O system tasks: <CODE>$fdisplay</CODE>

, <CODE>$fwrite</CODE> , <CODE>$fmonitor</CODE> , and <CODE>$fstrobe</CODE>

; correspond to their display counterparts. The first parameter for the

file system tasks is a multichannel descriptor that may have multiple bits

set. Thus, the preceding example writes the string <CODE>&quot;Hello&quot;</CODE>

to the screen and to <CODE>file1.out</CODE> . The task $fclose closes a

file and allows the channel to be reused.</P>

<P><P CLASS="Body"><A NAME="pgfId=125094"></A>The file I/O tasks <CODE>$readmemb</CODE>

and <CODE>$readmemh</CODE> read a text file into a memory. The file may

contain only spaces, new lines, tabs, form feeds, comments, addresses, and

binary (for <CODE>$readmemb</CODE> ) or hex (for <CODE>$readmemh</CODE>

) numbers, as in the following example:</P>

<PRE>

mem.dat

@2 1010_1111 @4 0101_1111 1010_1111 // @address in hex

x1x1_zzzz 1111_0000 /* x or z is OK */

<B>module</B> load; <B>reg</B> [7:0] mem[0:7]; <B>integer</B> i; <B>initial</B> <B>begin</B>

$readmemb(&quot;mem.dat&quot;, mem, 1, 6); // start_address=1, end_address=6

<B>for</B> (i= 0; i&lt;8; i=i+1) $display(&quot;mem[%0d] %b&quot;, i, mem[i]);

<B>end</B> <B>endmodule</B>

&gt; vsim -c load

# Loading work.load

VSIM 1&gt; run 10

# ** Warning: $readmem (memory mem) file mem.dat line 2:

#    More patterns than index range (hex 1:6)

#    Time: 0 ns  Iteration: 0  Instance:/

# mem[0] xxxxxxxx

# mem[1] xxxxxxxx

# mem[2] 10101111

# mem[3] xxxxxxxx

# mem[4] 01011111

# mem[5] 10101111

# mem[6] x1x1zzzz

# mem[7] xxxxxxxx

VSIM 2&gt; q

&gt;</PRE>

<H2><A NAME="pgfId=121180"></A>11.13.3&nbsp;&nbsp;&nbsp;Timescale, Simulation,

and Timing-Check Tasks</H2>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=125069"></A>There are two <B>timescale

tasks</B>, <CODE>$printtimescale</CODE> and <CODE>$timeformat</CODE> [Verilog

LRM 14.3]. The <CODE>$timeformat</CODE> specifies the <CODE>%t</CODE> format

specification for the display and file I/O system tasks as well as the time

unit for delays entered interactively and from files. Here are examples

of the timescale tasks:</P>

<PRE>

// timescale tasks:

<B>module</B> a; <B>initial</B> $printtimescale(b.c1); <B>endmodule</B>

<B>module</B> b; c c1 (); <B>endmodule</B>

`timescale 10 ns / 1 fs

<B>module</B> c_dat; <B>endmodule</B>

`timescale 1 ms / 1 ns

<B>module</B> Ttime; <B>initial</B> $timeformat(-9, 5, &quot; ns&quot;, 10); <B>endmodule</B>

/* $timeformat [ ( n, p, suffix , min_field_width ) ] ;

units = 1 second ** (-n), n = 0-&gt;15, e.g. for n = 9, units = ns

p = digits after decimal point for %t e.g. p = 5 gives 0.00000

suffix for %t (despite timescale directive)

min_field_width is number of character positions for %t */</PRE>

<P><P CLASS="Body"><A NAME="pgfId=120964"></A>The <B>simulation control

tasks</B> are $stop and $finis<CODE> h </CODE>[Verilog LRM 14.4]:</P>

<PRE>

<B>module</B> test_simulation_control; // simulation control system tasks:

<B>initial</B> <B>begin</B> $stop; // enter interactive mode (default parameter 1)

$finish(2); // graceful exit with optional parameter as follows:

// 0 = nothing 1 = time and location 2 = time, location, and statistics 

<B>end</B> <B>endmodule</B></PRE>

<P><P CLASS="Body"><A NAME="pgfId=140760"></A>The <B>timing-check tasks</B>

[Verilog LRM 14.5] are used in specify blocks. The following code and comments

illustrate the definitions and use of timing-check system tasks. The arguments

to the tasks are defined and explained in Table&nbsp;11.11.</P>

<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">

<TR>

<TH COLSPAN="3"><P CLASS="TableTitle"><A NAME="pgfId=140769"></A>TABLE&nbsp;11.11&nbsp;&nbsp;&nbsp;&nbsp;Timing-check

system task parameters.</TH></TR>

<TR>

<TH><P CLASS="TableFirst"><A NAME="pgfId=140775"></A>Timing task argument</TH>

<TH><P CLASS="TableFirst"><A NAME="pgfId=140777"></A>&nbsp;&nbsp;Description

of argument</TH>

<TH><P CLASS="TableFirst"><A NAME="pgfId=140779"></A>Type of argument</TH></TR>

<TR>

<TD><PRE>

reference_event</PRE>

</TD>

<TD><P CLASS="TableLeft"><A NAME="pgfId=140783"></A>to establish reference time</TD>

<TD><P><P CLASS="TableLeft"><A NAME="pgfId=140785"></A>module input or inout</P>

<P><P CLASS="TableLeft"><A NAME="pgfId=140786"></A>(scalar or vector net)</TD></TR>

<TR>

<TD><PRE>

data_event</PRE>

</TD>

<TD><P CLASS="TableLeft"><A NAME="pgfId=140790"></A>signal to check against

reference_event</TD>

<TD><P><P CLASS="TableLeft"><A NAME="pgfId=140792"></A>module input or inout</P>

<P><P CLASS="TableLeft"><A NAME="pgfId=140793"></A>(scalar or vector net)</TD></TR>

<TR>

<TD><PRE>

limit</PRE>

</TD>

<TD><P CLASS="TableLeft"><A NAME="pgfId=140797"></A>time limit to detect timing

violation on data_event</TD>

<TD><P><P CLASS="TableLeft"><A NAME="pgfId=140799"></A>constant expression</P>

<P><P CLASS="TableLeft"><A NAME="pgfId=140800"></A>or specparam</TD></TR>

<TR>

<TD><PRE>

threshold</PRE>

</TD>

<TD><P CLASS="TableLeft"><A NAME="pgfId=140804"></A>largest pulse width ignored

by timing check $width</TD>

<TD><P><P CLASS="TableLeft"><A NAME="pgfId=140806"></A>constant expression</P>

<P><P CLASS="TableLeft"><A NAME="pgfId=140807"></A>or specparam</TD></TR>

<TR>

<TD><PRE>

notifier</PRE>

</TD>

<TD><P><P CLASS="TableLeft"><A NAME="pgfId=140811"></A>flags a timing violation

(before -&gt; after):</P>

<PRE>

x-&gt;0, 0-&gt;1, 1-&gt;0, z-&gt;z</PRE>

</TD>

<TD><P CLASS="TableLeft"><A NAME="pgfId=140814"></A>register</TD></TR>

</TABLE>

</P>

<PRE>

<B>module</B> timing_checks (data, clock, clock_1,clock_2); 

<B>input </B>data,clock,clock_1,clock_2; <B>reg</B> tSU,tH,tHIGH,tP,tSK,tR;

<B>specify</B> // timing check system tasks:

/* $setup (data_event, reference_event, limit [, notifier]);

violation = (T_reference_event)-(T_data_event) &lt; limit */

$setup(data, <B>posedge</B> clock, tSU);

/* $hold (reference_event, data_event, limit [, notifier]);

violation = 

&nbsp;&nbsp;(time_of_data_event)-(time_of_reference_event) &lt; limit */

$hold(<B>posedge</B> clock, data, tH);

/* $setuphold (reference_event, data_event, setup_limit,

&nbsp;&nbsp;&nbsp;&nbsp;hold_limit [, notifier]);

parameter_restriction = setup_limit + hold_limit &gt; 0 */

$setuphold(<B>posedge</B> clock, data, tSU, tH);

/* $width (reference_event, limit, threshold [, notifier]);

violation = 

&nbsp;&nbsp;threshold &lt; (T_data_event) - (T_reference_event) &lt; limit

reference_event = edge

data_event = opposite_edge_of_reference_event */

$width(<B>posedge</B> clock, tHIGH);

/* $period (reference_event, limit [, notifier]);

violation = (T_data_event) - (T_reference_event) &lt; limit

reference_event = edge

data_event = same_edge_of_reference event */

$period(<B>posedge</B> clock, tP);

/* $skew (reference_event, data_event, limit [, notifier]);

violation = (T_data_event) - (T_reference_event) &gt; limit */

$skew(<B>posedge</B> clock_1, <B>posedge</B> clock_2, tSK);

/* $recovery (reference_event, data_event, limit, [, notifier]);

violation = (T_data_event) - (T_reference_event) &lt; limit */

$recovery(<B>posedge</B> clock, <B>posedge</B> clock_2, tR);

/* $nochange (reference_event, data_event, start_edge_offset,

&nbsp;&nbsp;end_edge_offset [, notifier]);

reference_event = posedge | negedge

violation = change while reference high (posedge)/low (negedge)

+ve start_edge_offset moves start of window later

+ve end_edge_offset moves end of window later */

$nochange (<B>posedge</B> clock, data, 0, 0);

<B>endspecify</B> <B>endmodule </B></PRE>

<P><P CLASS="Body"><A NAME="pgfId=201105"></A>You can use <B>edge specifiers</B>

as parameters for the timing-check events (except for the reference event

in $nochange):</P>

<PRE>

edge_control_specifier ::= edge [edge_descriptor {, edge_descriptor}]

edge_descriptor ::= 01 | 0x | 10 | 1x | x0 | x1</PRE>

<P><P CLASS="BodyAfterHead"><A NAME="pgfId=121867"></A>For example, <CODE>'edge

[01, 0x, x1] clock'</CODE> is equivalent to <CODE>'posedge clock'</CODE>

. Edge transitions with <CODE>'z'</CODE> are treated the same as transitions

with <CODE>'x'</CODE> .</P>

<P><P CLASS="Body"><A NAME="pgfId=122441"></A>Here is a D flip-flop model

that uses timing checks and a <B>notifier register</B>. The register, notifier,

is changed when a timing-check task detects a violation and the last entry

in the table then sets the flip-flop output to unknown.</P>

<PRE>

<B>primitive</B> dff_udp(q, clock, data, notifier);

<B>output</B> q; <B>reg</B> q; <B>input</B> clock, data, notifier;

<B>table</B> //&nbsp;&nbsp;&nbsp;clock&nbsp;data&nbsp;&nbsp;notifier:state:&nbsp;&nbsp;q

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;?&nbsp;&nbsp;:&nbsp;&nbsp;0 ;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;?&nbsp;&nbsp;:&nbsp;&nbsp;1 ;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;?&nbsp;&nbsp;:&nbsp;&nbsp;- ;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;?&nbsp;&nbsp;:&nbsp;&nbsp;- ;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;?&nbsp;&nbsp;:&nbsp;&nbsp;x ; <B>endtable</B> // notifier

<B>endprimitive</B> 

⌨️ 快捷键说明

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