ch11.13.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 485 行 · 第 1/2 页
HTM
485 行
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">
<TITLE> 11.13 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 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 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 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 ("string, variables, or expression");
/* format specifications work like printf in C:
%d=decimal %b=binary %s=string %h=hex %o=octal
%c=character %m=hierarchical name %v=strength %t=time format
%e=scientific %f=decimal %g=shortest
examples: %d uses default width %0d uses minimum width
%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("write"); // as $display, but without newline at end of line
$strobe("strobe"); // 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 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("f1.out");
<B>if</B>(f1==0) $stop(2); <B>if</B>(f1==2)$display("f1 open");
ch = f1|1; $fdisplay(ch,"Hello"); $fclose(f1); <B>end</B> <B>endmodule</B>
> vlog file_1.v
> vsim -c file_1
# Loading work.file_1
VSIM 1> run 10
# f1 open
# Hello
VSIM 2> q
> more f1.out
Hello
></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>"Hello"</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("mem.dat", mem, 1, 6); // start_address=1, end_address=6
<B>for</B> (i= 0; i<8; i=i+1) $display("mem[%0d] %b", i, mem[i]);
<B>end</B> <B>endmodule</B>
> vsim -c load
# Loading work.load
VSIM 1> 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> q
></PRE>
<H2><A NAME="pgfId=121180"></A>11.13.3 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, " ns", 10); <B>endmodule</B>
/* $timeformat [ ( n, p, suffix , min_field_width ) ] ;
units = 1 second ** (-n), n = 0->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 11.11.</P>
<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">
<TR>
<TH COLSPAN="3"><P CLASS="TableTitle"><A NAME="pgfId=140769"></A>TABLE 11.11 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> 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 -> after):</P>
<PRE>
x->0, 0->1, 1->0, z->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) < limit */
$setup(data, <B>posedge</B> clock, tSU);
/* $hold (reference_event, data_event, limit [, notifier]);
violation =
(time_of_data_event)-(time_of_reference_event) < limit */
$hold(<B>posedge</B> clock, data, tH);
/* $setuphold (reference_event, data_event, setup_limit,
hold_limit [, notifier]);
parameter_restriction = setup_limit + hold_limit > 0 */
$setuphold(<B>posedge</B> clock, data, tSU, tH);
/* $width (reference_event, limit, threshold [, notifier]);
violation =
threshold < (T_data_event) - (T_reference_event) < 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) < 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) > 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) < limit */
$recovery(<B>posedge</B> clock, <B>posedge</B> clock_2, tR);
/* $nochange (reference_event, data_event, start_edge_offset,
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> // clock data notifier:state: q
r 0 ? : ? : 0 ;
r 1 ? : ? : 1 ;
n ? ? : ? : - ;
? * ? : ? : - ;
? ? * : ? : x ; <B>endtable</B> // notifier
<B>endprimitive</B>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?