ch10.16.htm
来自「介绍asci设计的一本书」· HTM 代码 · 共 545 行 · 第 1/2 页
HTM
545 行
</TD>
<TD ROWSPAN="2"><P><P CLASS="TableLeft"><A NAME="pgfId=464919"></A>FIFO (first-in, first-out)
register</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503107"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503108"></A>Reads (pop = 1) and writes
(push = 1) are synchronous to the rising edge of the clock.</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503111"></A>Read and write should
not occur at the same time. The width (number of bits in each word) and
depth (number of words) are generics.</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503101"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503102"></A>External signals:</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464921"></A><CODE>clk</CODE> , clock</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464922"></A><CODE>rst</CODE> , reset
active-high</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464923"></A><CODE>push</CODE> , write
to FIFO</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464924"></A><CODE>pop</CODE> , read
from FIFO</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464925"></A><CODE>Di</CODE> , data
in</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464926"></A><CODE>Do</CODE> , data
out</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464927"></A><CODE>empty</CODE> ,
FIFO flag</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464928"></A><CODE>full</CODE> , FIFO
flag</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464929"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464930"></A>Internal signals:</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464932"></A><CODE>diff</CODE> , difference
pointer</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464933"></A><CODE>Ai</CODE> , input
address</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464934"></A><CODE>Ao</CODE> , output
address</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464935"></A><CODE>f</CODE> , full
flag</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464936"></A><CODE>e</CODE> , empty
flag</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464937"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464938"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=464939"></A>No delays in this model.</TD></TR>
<TR></TR>
</TABLE>
<P CLASS="Body"><A NAME="pgfId=464573"></A>The FIFO has flags, <CODE>empty</CODE>
and <CODE>full</CODE> , that signify its state. It uses a function to increment
two circular pointers. One pointer keeps track of the address to write to
next, the other pointer tracks the address to read from. The FIFO memory
may be implemented in a number of ways in hardware. We shall assume for
the moment that it will be synthesized as a bank of flip-flops.</P>
<P><P CLASS="Body"><A NAME="pgfId=464574"></A>Table 10.25 shows a controller
for the two FIFOs. The controller handles the reading and writing to the
FIFO. The microcontroller attached to the bus signals which of the FIFOs
it wishes to read from. The controller then places the appropriate data
on the bus. The microcontroller can also ask for the FIFO flags to be placed
in the low-order bits of the bus on a read cycle. If none of these actions
are requested by the microcontroller, the FIFO controller three-states its
output drivers.</P>
<P><P CLASS="Body"><A NAME="pgfId=502006"></A>Table 10.25 shows the
top level of the controller. To complete our model we shall use a package
for the component declarations:</P>
<P><TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">
<TR>
<TH COLSPAN="2" ALIGN="LEFT"><P ALIGN=LEFT><P CLASS="TableTitle"><A NAME="pgfId=503156"></A>TABLE 10.25 A
FIFO controller.</TH></TR>
<TR>
<TD VALIGN="TOP"><PRE><B>library</B> IEEE;<B>use</B> IEEE.STD_LOGIC_1164.<B>all</B>;<B>use</B> IEEE.NUMERIC_STD.<B>all</B>;
<B>entity</B> fifo_control <B>is</B> <B>generic </B>TPD : TIME := 1 ns;
<B>port</B>(D_1, D_2 : <B>in</B> UNSIGNED(11 <B>downto</B> 0);
sel : <B>in</B> UNSIGNED(1 <B>downto</B> 0) ;
read , f1, f2, e1, e2 : <B>in</B> STD_LOGIC;
r1, r2, w12 : <B>out</B> STD_LOGIC; D : <B>out</B> UNSIGNED(11 downto 0)) ;
<B>end</B>;
<B>architecture</B> rtl <B>of</B> fifo_control <B>is</B>
<B>begin</B> <B>process</B>
(read, sel, D_1, D_2, f1, f2, e1, e2)
<B> begin</B>
r1 <= '0' <B>after</B> TPD; r2 <= '0' <B>after</B> TPD;
<B>if</B> (read = '1') <B>then</B>
w12 <= '0' <B>after</B> TPD;
<B>case</B> sel <B>is</B>
<B>when</B> "01" => D <= D_1 <B>after</B> TPD; r1 <= '1' <B>after</B> TPD;
<B>when</B> "10" => D <= D_2 <B>after</B> TPD; r2 <= '1' <B>after</B> TPD;
<B>when</B> "00" => D(3) <= f1 <B>after</B> TPD; D(2) <= f2 <B>after</B> TPD;
D(1) <= e1 <B>after</B> TPD; D(0) <= e2 <B>after</B> TPD;
<B>when</B> <B>others</B> => D <= "ZZZZZZZZZZZZ" <B>after</B> TPD;
<B>end</B> <B>case</B>;
<B>elsif</B> (read = '0') <B>then</B>
D <= "ZZZZZZZZZZZZ" <B>after</B> TPD; w12 <= '1' <B>after</B> TPD;
<B>else</B> D <= "ZZZZZZZZZZZZ" <B>after</B> TPD;
<B>end</B> <B>if</B>;
<B>end</B> <B>process</B>;
<B>end</B> rtl;</PRE>
</TD>
<TD><P><P CLASS="TableLeft"><A NAME="pgfId=503188"></A>This handles the reading
and writing to the FIFOs under control of the processor (mpu). The mpu can
ask for data from either FIFO or for status flags to be placed on the bus.</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503237"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503216"></A>Inputs:</P>
<PRE><A NAME="pgfId=503217"></A> D_1</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=503218"></A> data
in from FIFO1</P>
<PRE><A NAME="pgfId=503219"></A> D_2</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=503220"></A> data
in from FIFO2</P>
<PRE><A NAME="pgfId=503221"></A> sel</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=503222"></A> FIFO
select from mpu</P>
<PRE><A NAME="pgfId=503223"></A> read</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=503224"></A> FIFO
read from mpu</P>
<PRE><A NAME="pgfId=503225"></A> f1,f2,e1,e2</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=503226"></A> flags
from FIFOs</P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503227"></A> </P>
<P><P CLASS="TableLeft"><A NAME="pgfId=503228"></A>Outputs:</P>
<PRE><A NAME="pgfId=571060"></A> r1, r2</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=571061"></A> read
enables for FIFOs</P>
<PRE><A NAME="pgfId=571062"></A> w12</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=503232"></A> write
enable for FIFOs</P>
<PRE><A NAME="pgfId=503233"></A> D</PRE>
<P><P CLASS="TableLeft"><A NAME="pgfId=503234"></A> data
out to mpu bus</TD></TR>
</TABLE>
<TABLE BORDER="1" CELLSPACING="2" CELLPADDING="2">
<TR>
<TH ALIGN="LEFT"><P ALIGN=LEFT><P CLASS="TableTitle"><A NAME="pgfId=445400"></A>TABLE 10.26 Top
level of temperature controller.</TH></TR>
<TR>
<TD ROWSPAN="2"><PRE><B>library</B> IEEE; <B>use</B> IEEE.STD_LOGIC_1164.<B>all</B>; <B>use</B> IEEE.NUMERIC_STD.<B>all</B>;
<B>entity</B> T_Control <B>is</B> <B>port</B> (T_in1, T_in2 : <B>in</B> UNSIGNED (11 <B>downto</B> 0);
sensor: <B>in</B> UNSIGNED(1 <B>downto</B> 0);
clk, RD, rst : <B>in</B> STD_LOGIC; D : <B>out</B> UNSIGNED(11 <B>downto</B> 0));
<B>end</B>;
<B>architecture</B> structure <B>of</B> T_Control <B>is use</B> work.TC_Components.<B>all</B>;
<B>signal</B> F, E : UNSIGNED (2 <B>downto</B> 1);
<B>signal</B> T_out1, T_out2, R_out1, R_out2, F1, F2, FIFO1, FIFO2 : UNSIGNED(11 <B>downto</B> 0);
<B>signal</B> RD1, RD2, WR: STD_LOGIC ;
<B>begin</B>
RG1 : register_in <B>generic</B> <B>map</B> (1ns) <B>port</B> <B>map</B> (T_in1,clk,rst,R_out1);
RG2 : register_in <B>generic</B> <B>map</B> (1ns) <B>port</B> <B>map</B> (T_in2,clk,rst,R_out2);
TC1 : tconv <B>generic</B> <B>map</B> (1ns) <B>port</B> <B>map</B> (R_out1, T_out1);
TC2 : tconv <B>generic</B> <B>map</B> (1ns) <B>port</B> <B>map</B> (R_out2, T_out2);
TF1 : filter <B>generic</B> <B>map</B> (1ns) <B>port</B> <B>map</B> (T_out1, rst, clk, F1);
TF2 : filter <B>generic</B> <B>map</B> (1ns) <B>port</B> <B>map</B> (T_out2, rst, clk, F2);
FI1 : fifo <B>generic</B> <B>map </B>(12,16) <B>port</B> <B>map</B> (clk, rst, WR, RD1, F1, FIFO1, E(1), F(1));
FI2 : fifo <B>generic</B> <B>map </B>(12,16) <B>port</B> <B>map</B> (clk, rst, WR, RD2, F2, FIFO2, E(2), F(2));
FC1 : fifo_control <B>port</B> <B>map</B>
(FIFO1, FIFO2, sensor, RD, F(1), F(2), E(1), E(2), RD1, RD2, WR, D);
<B>end</B> structure;</PRE>
</TD></TR>
<TR></TR>
</TABLE>
</P>
<PRE><B>package</B> TC_Components <B>is</B>
<B>component</B> register_in <B>generic </B>(TPD : TIME := 1 ns);
<B>port</B> (T_in : <B>in</B> UNSIGNED(11 <B>downto</B> 0);
clk, rst : <B>in</B> STD_LOGIC; T_out : <B>out</B> UNSIGNED(11 <B>downto</B> 0));
<B>end</B> <B>component</B>;
<B>component</B> tconv <B>generic </B>(TPD : TIME := 1 ns);
<B>port</B> (T_in : <B>in</B> UNSIGNED (7 <B>downto</B> 0);
clk, rst : <B>in</B> STD_LOGIC; T_out : <B>out</B> UNSIGNED(7 <B>downto</B> 0));
<B>end</B> <B>component</B>;
<B>component</B> filter <B>generic </B>(TPD : TIME := 1 ns);
<B>port</B> (T_in : <B>in</B> UNSIGNED (7 <B>downto</B> 0);
rst, clk : <B>in</B> STD_LOGIC; T_out : <B>out</B> UNSIGNED(7 <B>downto</B> 0));
<B>end</B> <B>component</B>;
<B>component</B> fifo <B>generic</B> (width:INTEGER := 12; depth : INTEGER := 16);
<B>port</B> (clk, rst, push, pop : STD_LOGIC;
Di : UNSIGNED (width-1 <B>downto</B> 0);
Do : <B>out</B> UNSIGNED (width-1 <B>downto</B> 0);
empty, full : <B>out</B> STD_LOGIC);
<B>end</B> <B>component</B>;
<B>component</B> fifo_control <B>generic </B>(TPD:TIME := 1 ns);
<B> port</B> (D_1, D_2 : <B>in</B> UNSIGNED(7 <B>downto</B> 0);
select : <B>in</B> UNSIGNED(1 <B>downto</B> 0); read, f1, f2, e1, e2 : <B>in</B> STD_LOGIC;
r1, r2, w12 : <B>out</B> STD_LOGIC; D : <B>out</B> UNSIGNED(7 <B>downto</B> 0)) ;
<B>end</B> <B>component</B>;
<B>end</B>;</PRE>
<P><P CLASS="Body"><A NAME="pgfId=446521"></A>The following testbench completes
a set of reads and writes to the FIFOs:</P>
<PRE><B>library</B> IEEE;
<B>use</B> IEEE.std_logic_1164.<B>all</B>; -- type STD_LOGIC
<B>use</B> IEEE.numeric_std.<B>all</B>; -- type UNSIGNED
<B>entity</B> test_TC <B>is</B> <B>end</B>;
<B>architecture</B> testbench <B>of</B> test_TC <B>is</B>
<B>component</B> T_Control <B>port</B> (T_1, T_2 : <B>in</B> UNSIGNED(11 <B>downto</B> 0);
clk : <B>in</B> STD_LOGIC; sensor: <B>in</B> UNSIGNED( 1 <B>downto</B> 0) ;
read : <B>in</B> STD_LOGIC; rst : <B>in</B> STD_LOGIC;
D : <B>out</B> UNSIGNED(7 <B>downto</B> 0)); <B>end</B> <B>component</B>;
<B>signal</B> T_1, T_2 : UNSIGNED(11 <B>downto</B> 0);
<B>signal</B> clk, read, rst : STD_LOGIC;
<B>signal</B> sensor : UNSIGNED(1 <B>downto</B> 0);
<B>signal</B> D : UNSIGNED(7 <B>downto</B> 0);
<B>begin</B> TT1 : T_Control <B>port</B> <B>map </B>(T_1, T_2, clk, sensor, read, rst, D);
<B>process</B> <B>begin</B>
rst <= '0'; clk <= '0';
<B>wait</B> <B>for</B> 5 ns; rst <= '1'; <B>wait</B> <B>for</B> 5 ns; rst <= '0';
T_in1 <= "000000000011"; T_in2 <= "000000000111"; read <= '0';
<B> for</B> i <B>in</B> 0 <B>to</B> 15 <B>loop</B> -- fill the FIFOs
clk <= '0'; <B>wait</B> <B>for</B> 5 ns; clk <= '1'; <B>wait</B> <B>for</B> 5 ns;
<B> end</B> <B>loop</B>;
<B>assert</B> (false) <B>report</B> "FIFOs full" <B>severity</B> NOTE;
clk <= '0'; <B>wait</B> <B>for</B> 5 ns; clk <= '1'; <B>wait</B> <B>for</B> 5 ns;
read <= '1'; sensor <= "01";
<B> for</B> i <B>in</B> 0 <B>to</B> 15 <B>loop</B> -- empty the FIFOs
clk <= '0'; <B>wait</B> <B>for</B> 5ns; clk <= '1'; <B>wait</B> <B>for</B> 5 ns;
<B> end</B> <B>loop</B>;
<B>assert</B> (false) <B>report</B> "FIFOs empty" <B>severity</B> NOTE;
clk <= '0'; <B>wait</B> <B>for</B> 5ns; clk <= '1'; <B>wait</B>;
<B>end</B> <B>process</B>;
<B>end</B>;</PRE>
<P><HR ALIGN=LEFT></P>
<P><A HREF="CH10.htm">Chapter start</A> <A
HREF="CH10.15.htm">Previous page</A> <A HREF=
"CH10.17.htm">Next page</A>
</BODY>
<!--#include file="Copyright.html"--><!--#include file="footer.html"-->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?