ch10.12.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 297 行 · 第 1/2 页
HTM
297 行
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="Adobe PageMill 2.0 Mac">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE> 10.12 Arithmetic</TITLE>
</HEAD><!--#include file="top.html"--><!--#include file="header.html"--><br><!--#include file="AmazonAsic.html"-->
<P><A NAME="pgfId=200123"></A><A HREF="CH10.htm">Chapter start</A> <A HREF="CH10.11.htm">Previous
page</A> <A HREF="CH10.13.htm">Next page</A></P>
<H2>10.12 Arithmetic</H2>
<P><A NAME="pgfId=200378"></A>The following example illustrates type checking
and type conversion in VHDL arithmetic operations [<A HREF="../../VHDL/LRM/HTML/1076_7.HTM#7.3.4">VHDL
93LRM7.3.4</A>-<A HREF="../../VHDL/LRM/HTML/1076_7.HTM#7.3.5">7.3.5</A>]:</P>
<PRE><B>entity</B> Arithmetic_1 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Arithmetic_1 <B>is</B>
<B>begin</B> <B>process</B>
<B>variable</B> i : INTEGER := 1; <B>variable</B> r : REAL := 3.33;
<B>variable</B> b : BIT := '1';
<B>variable</B> bv4 : BIT_VECTOR (3 <B>downto</B> 0) := "0001";
<B>variable</B> bv8 : BIT_VECTOR (7 <B>downto</B> 0) := B"1000_0000";
<B>begin</B>
-- i := r; -- you can't assign REAL to INTEGER.
-- bv4 := bv4 + 2; -- you can't add BIT_VECTOR and INTEGER.
-- bv4 := '1'; -- you can't assign BIT to BIT_VECTOR.
-- bv8 := bv4; -- an error, the arrays are different sizes.
r := REAL(i); -- OK, uses a type conversion.
i := INTEGER(r); -- OK (0.5 rounds up or down).
bv4 := "001" & '1'; -- OK, you can mix an array and a scalar.
bv8 := "0001" & bv4; -- OK, if arguments are the correct lengths.
<B>wait</B>; <B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><A NAME="pgfId=201822"></A>The next example shows arithmetic operations
between types and subtypes, and also illustrates range checking during analysis
and simulation:</P>
<PRE><B>entity</B> Arithmetic_2 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Arithmetic_2 <B>is</B>
<B>type</B> TC <B>is</B> <B>range</B> 0 <B>to</B> 100; -- Type INTEGER.
<B>type</B> TF <B>is</B> <B>range</B> 32 <B>to</B> 212; -- Type INTEGER.
<B>subtype</B> STC <B>is</B> INTEGER <B>range</B> 0 <B>to</B> 100; -- Subtype of type INTEGER.
<B>subtype</B> STF <B>is</B> INTEGER <B>range</B> 32 <B>to</B> 212; -- Base type is INTEGER.
<B>begin</B> <B>process </B>
<B>variable</B> t1 : TC := 25; <B>variable</B> t2 : TF := 32;
<B>variable</B> st1 : STC := 25; <B>variable</B> st2 : STF := 32;
<B>begin</B>
-- t1 := t2; -- Illegal, different types.
-- t1 := st1; -- Illegal, different types and subtypes.
st2 := st1; -- OK to use same base types.
st2 := st1 + 1; -- OK to use subtype and base type.
-- st2 := 213; -- Error, outside range at analysis time.
-- st2 := 212 + 1; -- Error, outside range at analysis time.
st1 := st1 + 100; -- Error, outside range at initialization.
<B>wait</B>; <B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><A NAME="pgfId=202195"></A>The MTI simulator, for example, gives the
following informative error message during simulation of the preceding model:</P>
<PRE># ** Fatal: Value 25 is out of range 32 to 212
# Time: 0 ns Iteration: 0 Instance:/
# Stopped at Arithmetic_2.vhd line 12
# Fatal error at Arithmetic_2.vhd line 12</PRE>
<P><A NAME="pgfId=252855"></A>The assignment st2 := st1 causes this error
(since st1 is initialized to 25). <P CLASS="Body"><A NAME="pgfId=200403"></A>Operations
between array types and subtypes are a little more complicated as the following
example illustrates:</P>
<PRE><B>entity</B> Arithmetic_3 <B>is</B> <B>end</B>; <B>architecture</B> Behave <B>of</B> Arithmetic_3 <B>is</B>
<B>type</B> TYPE_1 <B>is</B> <B>array</B> (INTEGER <B>range</B> 3 <B>downto</B> 0) <B>of</B> BIT;
<B>type</B> TYPE_2 <B>is</B> <B>array</B> (INTEGER <B>range</B> 3 <B>downto</B> 0) <B>of</B> BIT;
<B>subtype</B> SUBTYPE_1 <B>is</B> BIT_VECTOR (3 <B>downto</B> 0);
<B>subtype</B> SUBTYPE_2 <B>is</B> BIT_VECTOR (3 <B>downto</B> 0);
<B>begin</B> <B>process</B>
<B>variable</B> bv4 : BIT_VECTOR (3 <B>downto</B> 0) := "0001";
<B>variable </B>st1 : SUBTYPE_1 := "0001"; <B>variable </B>t1 : TYPE_1 := "0001";
<B>variable </B>st2 : SUBTYPE_2 := "0001"; <B>variable </B>t2 : TYPE_2 := "0001";
<B>begin</B>
bv4 := st1; -- OK, compatible type and subtype.
-- bv4 := t1; -- Illegal, different types.
bv4 := BIT_VECTOR(t1); -- OK, type conversion.
st1 := bv4; -- OK, compatible subtype and base type.
-- st1 := t1; -- Illegal, different types.
st1 := SUBTYPE_1(t1); -- OK, type conversion.
-- t1 := st1; -- Illegal, different types.
-- t1 := bv4; -- Illegal, different types.
t1 := TYPE_1(bv4); -- OK, type conversion.
-- t1 := t2; -- Illegal, different types.
t1 := TYPE_1(t2); -- OK, type conversion.
st1 := st2; -- OK, compatible subtypes.
<B>wait</B>; <B>end</B> <B>process</B>; <B>end</B>;</PRE>
<P><A NAME="pgfId=200399"></A>The preceding example uses <TT>BIT</TT> and
<TT>BIT_VECTOR</TT> types, but exactly the same considerations apply to
<TT>STD_LOGIC</TT> and <TT>STD_LOGIC_VECTOR</TT> types or other arrays.
Notice the use of type conversion, written as type_mark'(expression), to
convert between closely related types. Two types are closely related if
they are abstract numeric types (integer or floating-point) or arrays with
the same dimension, each index type is the same (or are themselves closely
related), and each element has the same type [<A HREF="../../VHDL/LRM/HTML/1076_7.HTM#7.3.5">VHDL
93LRM7.3.5</A>].</P>
<H3><A NAME="pgfId=202431"></A>10.12.1 IEEE Synthesis Packages</H3>
<P><A NAME="pgfId=202434"></A>The IEEE 1076.3 standard synthesis packages
allow you to perform arithmetic on arrays of the type <TT>BIT</TT> and <TT>STD_LOGIC</TT>
.<A HREF="#pgfId=539364" CLASS="footnote"> 1</A> The <TT>NUMERIC_BIT</TT>
package defines all of the operators in Table 10.16 (except for the
exponentiating operator <TT>'**'</TT> ) for arrays of type <TT>BIT</TT>
. Here is part of the package header, showing the declaration of the two
types <TT>UNSIGNED</TT> and <TT>SIGNED</TT> , and an example of one of the
function declarations that overloads the addition operator <TT>'+'</TT>
for <TT>UNSIGNED</TT> arguments:</P>
<PRE><B>package</B> Part_NUMERIC_BIT <B>is</B>
<B>type</B> UNSIGNED <B>is</B> <B>array</B> (NATURAL <B>range</B> <> ) <B>of</B> BIT;
<B>type</B> SIGNED <B>is</B> <B>array</B> (NATURAL <B>range</B> <> ) <B>of</B> BIT;
<B>function</B> "+" (L, R : UNSIGNED) <B>return</B> UNSIGNED;
-- other function definitions that overload +, -, = , >, and so on.
<B>end</B> Part_NUMERIC_BIT;</PRE>
<P><A NAME="pgfId=202473"></A>The package bodies included in the 1076.3
standard define the functionality of the packages. Companies may implement
the functions in any way they wish--as long as the results are the same
as those defined by the standard. Here is an example of the parts of the
NUMERIC_BIT package body that overload the addition operator <TT>'+'</TT>
for two arguments of type <TT>UNSIGNED</TT> (even with my added comments
the code is rather dense and terse, but remember this is code that we normally
never see or need to understand):</P>
<PRE><B>package</B> <B>body</B> Part_NUMERIC_BIT <B>is</B>
<B>constant</B> NAU : UNSIGNED(0 <B>downto</B> 1) := (<B>others</B> =>'0'); -- Null array.
<B>constant</B> NAS : SIGNED(0 <B>downto</B> 1):=(<B>others</B> => '0'); -- Null array.
<B>constant</B> NO_WARNING : BOOLEAN := FALSE; -- Default to emit warnings.
<B>function</B> MAX (LEFT, RIGHT : INTEGER) <B>return</B> INTEGER <B>is</B>
<B>begin</B> -- Internal function used to find longest of two inputs.
<B>if</B> LEFT > RIGHT <B>then</B> <B>return</B> LEFT; <B>else</B> <B>return</B> RIGHT; <B>end</B> <B>if</B>; <B>end</B> MAX;
<B>function</B> ADD_UNSIGNED (L, R : UNSIGNED; C: BIT) <B>return</B> UNSIGNED <B>is</B>
<B>constant</B> L_LEFT : INTEGER := L'LENGTH-1; -- L, R must be same length.
<B>alias</B> XL : UNSIGNED(L_LEFT <B>downto</B> 0) <B>is</B> L; -- Descending alias,
<B>alias</B> XR : UNSIGNED(L_LEFT <B>downto</B> 0) <B>is</B> R; -- aligns left ends.
<B>variable</B> RESULT : UNSIGNED(L_LEFT <B>downto</B> 0); <B>variable</B> CBIT : BIT := C;
<B>begin</B> <B>for</B> I <B>in</B> 0 <B>to</B> L_LEFT <B>loop </B>-- Descending alias allows loop.
RESULT(I) := CBIT <B>xor</B> XL(I) <B>xor</B> XR(I); -- CBIT = carry, initially = C.
CBIT := (CBIT <B>and</B> XL(I)) <B>or</B> (CBIT <B>and</B> XR(I)) <B>or</B> (XL(I) <B>and</B> XR(I));
<B>end</B> <B>loop</B>; <B>return</B> RESULT; <B>end</B> ADD_UNSIGNED;
<B>function</B> RESIZE (ARG : UNSIGNED; NEW_SIZE : NATURAL) <B>return</B> UNSIGNED <B>is</B>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?