第6章 VHDL程序设计

第6章 VHDL程序设计
第6章 VHDL程序设计

第六章:VHDL程序设计

§6.1 VHDL描述风格

·描述风格:VHDL的构造体用于描述整个设计实体的逻辑功能。对于相同的电路功能行为,可以用不同的描述方式来表达;对于相同的逻辑行为,可以用不同的语句来描述。

·类型:行为描述;

寄存器传递(数据流)描述;

结构描述。

1.行为描述方式

·含义:是对系统数学模型的描述。

·特点:①只表示输入与输出间转换的行为,而不包含任何结构信息;

②主要使用函数、过程和进程语句,以算法形式描述数据的变换和传送;

③比寄存器传递和结构描述具有更高的抽象性;

④行为描述是VHDL编程的核心,可以说,没有行为描述就没有VHDL。

⑤通常不能直接进行逻辑综合,需要转化成RTL描述或结构描述。

·用途:主要用于系统数学模型的仿真或系统工作原理的仿真。

[例6-1]用行为描述方式描述“二选一”电路功能。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY mux2 IS i1

PROT( i0, i1, sel : IN STD_LOGIC;

q: OUT STD_LOGIC ); sel

END mux2;

ARCHITECTURE behav OF mux2 IS

BEGIN

CASE sel IS

WHEN 0 =>q<=i0 AFTER 10ns;

WHEN 1 =>q<=i1 AFTER 10ns;

WHEN OTHERS=>q<=‘X‘ AFTER 10ns;

END CASE

END behav;

2.寄存器传递描述(RTL)方式

·含义:是一种明确规定寄存器描述的方法。

·分类:①采用寄存器之间的功能描述(类似行为描述);

②采用寄存器硬件直接描述(一一对应)。

·特点:①RTL功能描述编程效率高、难度低,但可用的VHDL语句受限;

②RTL硬件描述编程难度大、要求高,但可用的VHDL语句多。[例6-2] 用RTL硬件方式描述“二选一”电路功能。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY mux2 IS

PROT( i0, i1, sel : IN STD_LOGIC;

q: OUT STD_LOGIC );

END mux2;

ARCHITECTURE rtl OF mux2 IS

SIGNAL temp1, temp2, temp3, : STD_LOGIC;

BEGIN

Temp1<=i0 AND sel;

Temp2<=i1 AND (NOT sel);

Temp3<=temp1 OR temp2;

q<=temp3;

END rtl;

3.结构描述方式

·含义:在分层设计中,通过高层次的设计模块调用低层次的设计模块来构成一个复杂的逻辑电路的描述方法。

·特点:①结构清晰,与硬件层层对应,如:系统→板→元件;

②设计效率高,可方便地将已有设计成果用到新的设计中。

[例6-3]用结构描述方式描述“二选一”电路功能。

U3

d0

d1

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY mux2 IS

PROT(d0, d1, sel : IN BIT;

q: OUT BIT );

END mux2;

ARCHITECTURE struct OF mux2 IS

COMPONENT and2

PROT(a, b : IN BIT;

c: OUT BIT );

END COMPONET;

COMPONENT or2

PROT(a, b : IN BIT;

c: OUT BIT );

END COMPONET;

COMPONENT inv

PROT(a : IN BIT;

c: OUT BIT );

END COMPONET;

SIGNAL aa, bb, nsel: BIT;

BEGIN

U1: inv PORT MAP(sel, nsel);

U2: and2 PORT MAP(d1, nsel, bb);

U3: and2 PORT MAP(d0, sel, aa);

U4: or2 PORT MAP(aa, bb, q);

END struct;

说明:①COMPONENT语句用来说明在该电路中所使用的已生成的模块and2,…;

②PORT MAP( ) 语句将已生成模块的端口与所设计的各模块U1,U2…的端口连接起来。

§6.2 组合逻辑电路设计

1.基本门电路

[例6-4] 用VHDL程序描述二输入“异或”门电路。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY xor2 IS

PORT (a, b: IN STD_LOGIC;

y: OUT STD_LOGIC);

END xor2;

ARCHITECTURE xor2_1 OF xor2 IS

BEGIN

y<=a XOR b;

END xor2_1;

[例6-5] 用VHDL 程序描述二输入“异或”门电路。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY xor2 IS

PORT (a, b: IN STD_LOGIC;

y: OUT STD_LOGIC);

END xor2;

ARCHITECTURE xor2_2 OF xor2 IS

BEGIN

PROCESS(a, b)

V ARIABLE comb:STD_LOGIC VECTOR( 1 DOWNTO 0 );

BEGIN

Comb:= a & b;

CASE comb is

WHEN ―00‖=> y <=‘0‘;

WHEN ―01‖=> y <=‘1‘;

WHEN ―10‖=> y <=‘1‘;

WHEN ―11‖=> y <=‘0‘;

WHEN OTHERS=> y <=‘X‘;

END CASE;

END PROCESS;

END xor2_2;

2.加法器

(1) 半加器

真值表 电路符号

二进制输入 和

进位

b a s co

0 0 0 0

0 1 1 0 1 0 1 0

1 1 0 1

逻辑表达式: S = (a + b)·/(a·b)

C0 = /(a·b)

[例6-6] 用VHDL 程序描述半加器电路功能。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY half_adder IS

PORT (a, b: IN STD_LOGIC;

s, co: OUT STD_LOGIC);

END half_adder;

ARCHITECTURE half1 OF half_adder IS

SIGNAL c, d: STD_LOGIC;

BEGIN

c<=a OR b;

d<=a NAND b;

s<=c AND d;

co<=NOT d;

END half1;

(2)全加器

[例6-7] 用VHDL程序描述全加器电路功能。

a

b

分析:·用两个半加器构成一个全加器;

·原理电路图示意;:

·采用元件例化语句COMPONET---PORT MAP( )。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY full_adder IS

PORT (a, b, ci: IN STD_LOGIC;

s, co: OUT STD_LOGIC);

END full_adder;

ARCHITECTURE full1 OF full_adder IS

COMPONENT half_adder

PORT (a, b: IN STD_LOGIC;

s, co: OUT STD_LOGIC);

END COMPONENT;

SIGNAL u0_s, u0_co, u1_s, u1_co: STD_LOGIC;

BEGIN

U0:half_adder PORT MAP(a, b, u0_s,u0_co);

U1:half_adder PORT MAP(ci, u0_s, u1_s, u1_co);

s<=u1_s;

co<=u0_co OR u1_co;

END fall1;

3.其它

编码器(优先级)/译码器(3-8)/选择器(四选一)/缓冲器(单/双)等(自学)

§6.3 时序电路设计

1.时钟信号

(1) 含义:周期性系列脉冲

(2) 作用:是描述时序电路的VHDL程序执行的条件。

(3) 描述方式:以进程的形式描述时序电路。

①时钟信号是进程的敏感信号

如:PROCESS (clk_signal)

BEGIN

IF (clock_edge_condition) THEN

Signal_out <= signal_in

END IF;

END PROCESS;

②时钟信号是进程中的激活信号

如:PROCESS

BEGIN

WAIT ON (clock_signal) UNTIL (clock_edge_condition)

Signal_out<=signal_in

END PROCESS;

(4) 边沿触发

①上升沿

·图形描述:

·语句描述:

IF clk=‘1‘AND clk‘LAST_V ALUE=‘0‘AND clk‘EVENT;

②下升沿

·图形描述:

·语句描述:

IF clk=‘0‘AND clk‘LAST_V ALUE=‘1‘AND clk‘EVENT;

2.复位信号

(1) 类型:·同步复位:当复位信号有效且给定时钟边沿到来时,触发器才被

复位。

·非同步复位(异步复位):一旦复位信号有效,触发器就被复位。

(2) 描述方式:

①同步复位:一定在以时钟为敏感信号的进程中定义,且用IF语句来描述必要的复位条件。

如:PROCESS (clock_signal)

BEGIN

IF (clock_edge_condition) THEN

IF (reset_condition) THEN

Signal_out<= reset_value;

ELSE

Signal_out<= signal_in;

END IF;

END IF;

END PROCESS;

②异步复位:在进程的敏感信号中,时钟和复位信号同时存在,用IF语句描述复位条件,用ELSE语句描述时钟事件。

如:PROCESS (reset_signal,clock_signal)

BEGIN

IF (reset_condition) THEN

Signal_out<= reset_value;

ELSIF (clock_event AND clock_edge_condition) THEN

Signal_out<= signal_in;

END IF;

END PROCESS;

说明:若没有ELSIF语句,当复位信号变化但复位条件不满足时…。

3.触发器

[例6-8] 用VHDL程序描述D触发器功能

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY dff1 IS

PROT(d, clk: IN STD_LOGIC;

q: OUT STD_LOGIC);

END dff1;

ARCHITECTURE rtl Of dff1 IS

BEGIN

PROCESS(clk)

BEGIN

IF (clk=‘1‘) AND (clk‘EVENT) THEN

q<=d;

END IF;

END PROCESS

END rtl;

讨论:①本例是一个上升沿触发的D触发器程序;

②若改为下降沿触发:

clk‘EVENT AND clk=‘1‘→ clk=‘0‘

③若改用WAIT语句、上升沿触发:

IF →WAIT UNTIL clk‘EVENT AND clk=‘1‘

④若改用WAIT语句、下降沿触发:

IF →WAIT UNTIL clk‘EVENT AND clk=‘0‘[例6-9] 用VHDL程序描述异步置位/复位锁存器功能LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY dffcs IS

PROT(d, clk, clr, set: IN STD_LOGIC;

q: OUT STD_LOGIC);

END dffcs;

ARCHITECTURE rtl Of dffcs IS

BEGIN

PROCESS(clk, clr, set)

BEGIN

IF (clr=‘0‘) THEN

Q <= ‘0‘;

ELSIF (SET=‘0‘) THEN

Q <= ‘1‘;

ELSIF (clk‘EVENT AND clk=‘1‘) THEN

Q <= d;

END IF;

END PROCESS

END rtl;

[例6-10] 用VHDL程序描述J-K触发器功能

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY jkff IS

PROT(j, k, clk, clr, set: IN STD_LOGIC;

Q, qb: OUT STD_LOGIC);

END jkff;

ARCHITECTURE rtl Of jkff IS

SIGNAL q_s, qb_s: STD_LOGIC;

BEGIN

PROCESS(clk, clr, set, j, k)

BEGIN

IF (clr=‘0‘) AND (set=‘1‘) THEN

Q_s <= ‘0‘;

Qb_s <= ‘1‘;

ELSIF (clr=‘1‘) AND (set=‘0‘) THEN

Q_s <= ‘1‘;

Qb_s <= ‘0‘;

ELSIF (clk‘EVENT AND clk=‘1‘) THEN

IF (j=‘0‘) AND (k=‘1‘) THEN

Q_s <= ‘0‘;

Qb_s <= ‘1‘;

ELSIF (j=‘1‘) AND (k=‘0‘) THEN

Q_s <= ‘1‘;

Qb_s <= ‘0‘;

ELSIF (j=‘1‘) AND (k=‘1‘) THEN

Q_s <= NOT q_s;

Qb_s <= NOT qb_s;

ELSE

Q_s <= q_s;

Qb_s <= qb_s;

END IF;

Q <= q_s;

Qb <= qb_s;

END PROCESS

END rtl;

4.寄存器

[例6-11] 用VHDL语言设计一硬件电路,实现8位并入/并出移位寄存器循环左移3位。

分析:①电路符号

其中:din(0)~din(7): 8个数据输入端;

dout(0)~dout(7): 8个数据输出端;

s(0)~s(2): 移位位数控制输入端;

enb: 移位/数据输出控制端;

当enb=‘1’时,移位寄存器椐s(0)~s(2)输入的数据确

定循环左移的位数;

当enb=‘0’时,输出dout = din

clk: 移位时钟输入端。

②工作原理

sc = 3位(左移)din(7) din(0)

LSB

LSB Dout(7) dout(0)

③首先设计一个8位循环左移寄存器过程,以供其他调用;

④调用上述过程,设计一8位并入/并出移位寄存并循环左移3位。

※※用VHDL语言设计一循环左移“shift过程”

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

PACKAGE CPAC IS

PROCEDURE shift(din, s: IN STD_LOGIC_VECTOR;

SIGNAL dout: OUT STD_LOGIC_VECTOR );

END CPAC;

PACKGE BODY CPAC IS

PROCEDURE shift(din, s: IN STD_LOGIC_VECTOR;-过程名(参数)

SIGNAL dout: OUT STD_LOGIC_VECTOR ) IS

V ARIABLE sc:INTEGER; --定义变量

BEGIN

SC:=CONV_INTEGER(S); ---位矢量→整数

FOR I IN din‘RANGE LOOP

IF (sc+i <= din‘LEFT) T HEN ---3+I <=7

Dout(sc+I) <= din(i); --左边5位处理

ELSE

dout(sc + I - din‘LEFT-1) <=din(i); --右边3位处理

END IF;

END LOOP;

END shift;

END CPAC;

※※用VHDL语言通过调用上面程序包中的“shift过程”,实现3位循环左移。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE WORK.CPAC.ALL;

ENTITY bsr IS

Port( din: IN STD_LOGIC_VECTOR(7 DOWN 0);

S: IN STD_LOGIC_VECTOR(2 DOWN 0);

Dout: OUT STD_LOGIC_VECTOR(7 DOWN 0);

Clk, enb: IN STD_LOGIC);

END bsr;

ARCHITECTURE rtl OF bsr IS

BEGIN

PROCESS (clk)

BEGIN

IF (clk‘EVENT AND clk=‘1‘) THEN

IF (enb=‘0‘) THEN

Dout <= din;

ELSE

Shift (din, s, dout); ---调用程序包CPAC中的“shift过程”

END IF;

END IF;

END PROCESS;

END rtl;

5.计数器

·分类:

同步:在计数时钟控制下,构成计数器的各触发器状态同步发生变化;

异步:低位计数输出作为高一位计数器的时钟信号,一级一级串行连接。[例6-12] 用VHDL语言设计一六十进制计数器。

分析:①用一个六进制和一个十进制计数器连接起来→60进制计数器

②电路引脚图

clk

bcd1(0)

(1)

(2)

(3)

bcd10(0)

(1)

(2)

con

③引脚说明:

clk: 时钟输入

bcd1w: 个位置数控制端

bcd10w: 十位置数控制端

cin: 个位向十位进位输入端

con: 十位进位输出端

datain(0)~(3): 个位/十位预制数据输入端

bcd1(0)~(3): 个位数据输出端

bcd10(0)~(3): 十位数据输出端(最大为5)

④工作原理:

·bcd1w和bcd10w与datain(0)~(3)配合完成个位和十位预置数。因公用一组输入数据线,所以分别用两个进程串行完成;

·用三个进程分别处理个位、十位计数和进位处理。

VHDL语言源程序

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY bcd60count IS

Port(clk, bcd1w, bcd10w, cin: IN STD_LOGIC;

co: OUT STD_LOGIC;

Datain: IN STD_LOGIC_VECTOR(3 DOWN 0);

Bcd1: OUT STD_LOGIC_VECTOR(3 DOWN 0);

Bcd10: OUT STD_LOGIC_VECTOR(2 DOWN 0));

END bcd60count;

ARCHITECTURE rtl OF bcd60count IS

SIGNAL bcd1n: STD_LOGIC_VECTOR(3 DOWN 0); SIGNAL bcd10n: STD_LOGIC_VECTOR(2 DOWN 0); BEGIN

Bcd1<= bcd1n;

Bcd10<= bcd10n;

PROCESS (clk, bcd1w) ---个位置数/计数BEGIN

IF (bcd1w=‘1‘) THEN

Bcd1n<= datain;

ELSIF (clk‘EVENT AND clk=‘1‘) THEN

IF (cin=‘1‘) THEN----加1计数IF (bcd1n=‘9‘) THEN

Bcd1n<=‖0000‖;

ELSE

Bcd1n<=bcd1n+1;

END IF;

END IF;

END IF;

END PROCESS;

PROCESS (clk, bcd10w) ---十位置数/计数BEGIN

IF (bcd10w =‘1‘) THEN

Bcd10n<= datain(2 DOWNTO 0);

ELSIF (clk‘EVENT AND clk=‘1‘) THEN

IF (cin=‘1‘ AND bcd1n=‘9‘) THEN

IF (bcd10n=‘5‘) THEN

Bcd10n<=‖000‖;

ELSE

Bcd10n<=bcd10n+1;

END IF;

END IF;

END IF;

END PROCESS;

PROCESS(bcd10n, bcd1n, cin)

BEGIN

IF (cin=‘1‘ AND bcd1n=‘9‘ AND bcd10n=‘5‘) THEN

c o<=‘1‘;

ELSE

c o<=‘0‘;

END IF;

END PROCESS;

END rtl;

6.存储器

主要内容:ROM、RAM、FIFO等

1)基本概念

(1)存储器的描述

·存储器中存放的数据与数组中的元素相对应

·用整数表示元素的数组描述存储器的结构:

TYPE memory IS ARRAY (INTEGER RANEG<>) OF INTEGER;

·用位矢量表示元素的数组描述存储器的结构:

SUBTYPE word IS STD_LOGIC_VECTOR(k-1 DOWNTO 0);

TYPE memory IS ARRAY (0 TO 2**w -1) OF WORD;

其中:k表示存储单元的二进制位数,

w表示数组的元素个数。

(2)存储器的初始化

·实现方法:通过读取外部文件获得原始数据,然后赋给数组变量。

·变量说明:

V ARIABLE startup: BOOLEAN:=TRUE;

V ARIABLE l: LINE;

V ARIABLE j: INTEGER;

V ARIABLE rom: memory;

FILE romin:TEXT IS IN ―rom24s10.in‖

·初始化程序:

IF startup THEN

FOR j IN rom‘RANGE LOOP

READLINE(romin,l);

READ(l,rom(j));

END LOOP;

END IF;

2)只读存储器(ROM)

[例6-13] 试用VHDL设计一只读存储器(ROM)。

要求:①存储器容量:4K*8bit

②当rd、cs信号均为高电平时,输出数据;否则输出呈高阻状态。

分析:地址线:12条adr(0) — adr(11)

·数据线:8条dout(0) — dout(7)

·控制线:2条rd、cs

·存储器引脚图

·

··

·

·

源程序

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY roms IS

PORT ( rd, cs: IN STD_LOGIC;

adr: IN STD_LOGIC_VECTOR(11 DOWNTO 0);

dout: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));

END roms;

ARCHITECTURE behav OF roms IS

SUBTYPE word IS STD_LOGIC_VECTOR(7 DOWNTO 0);

TYPE memory ARRAY (0 TO 4095) OF word ;

SIGNAL adr_in: INTEGER RANGE 0 TO 4095;

V ARIABLE startup: BOOLEAN:=TRUE;

V ARIABLE l: LINE;

V ARIABLE j: INTEGER;

V ARIABLE rom: memory;

FILE romin:TEXT IS IN ―roms.in‖;

BEGIN

PROCESS(rd, cs, adr)

IF startup THEN

FOR j IN rom‘RANGE LOOP

READLINE(romin,l);

READ(l,rom(j));

END LOOP;

startup:= FALSE;

END IF;

adr_in <=CONV_INTEGER(adr);

IF ( rd=‘1‘ AND cs=‘1‘ ) THEN

dout <= rom(adr_in);

ELSE

Dout <= ―zzzzzzzz‖;

END IF;

END PROCESS

END behav;

3)随机读写存储器(RAM)

[例6-14 ] 试用VHDL设计一随机读写存储器(RAM)。

要求:①存储器容量:8*8bit;

②当cs = 1,rd= 0, wr = 1时,由adr 指定的单元内容从dout数据线上输出;

③当cs = 1,rd= 1, wr上升沿到来时,din数据线的数据写入由adr 指定的单元;

分析:①信号线

·地址线:3条adr(0) — adr(2)

·数据输入线:8条din(0) — din(7)

·数据输出线:8条dout(0) — dout(7)

·控制线:3条rd,wr,cs

②存储器引脚图

··

··

··

③存储器操作:

读/写两种操作对时间都有比较严格的要求。写数据时,数据线上数据建立时间必须大于800ps,数据保持时间必须大于300ps。

源程序:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY sram8 IS

GENERIC(k: INTEGER:= 8;

w: INTEGER:= 3 );

PORT ( wr, rd, cs: IN STD_LOGIC;

adr: IN STD_LOGIC_VECTOR(w-1 DOWNTO 0);

din: IN STD_LOGIC_VECTOR(k-1 DOWNTO 0);

dout: OUT STD_LOGIC_VECTOR(k-1 DOWNTO 0));

END sram8;

ARCHITECTURE behav OF sram8 IS

SUBTYPE word IS STD_LOGIC_VECTOR(k-1 DOWNTO 0);

TYPE memory IS ARRAY (0 TO 2**w -1) OF word ;

SIGNAL adr_in: INTEGER RANGE 0 TO 2**w -1;

SIGNAL sram: memory;

SIGNAL din_change, wr_rise,: TIME:= 0ps;

BEGIN

Adr_in <= CONV_INTEGER(adr);

PROCESS(wr) -- 写进程

BEGIN

IF (wr‘EVENT AND wr=‘1‘) THEN

IF (cs=‘1‘ AND wr=‘1‘) THEN

Sram (adr_in)<=din AFTER 2 ns;

END IF;

END IF;

wr_rise<=NOW; -- 数据建立时间检查

ASSERT (NOW-din_change>=800 ps) –若<800ps报警

REPORT‖SETUP ERROR din(sram)‖–表明数据线上的

SEVERITY WARNING; -- 数据未达到稳定END PROCESS; --(ASSERT语句条件为“假”,报告错误)

PROCESS (rd, cs) -- 读进程

BEGIN

IF (rd=‘0‘ AND cs=‘1‘) THEN

dout<=sram(adr_in) AFTER 3 ns;

ELSE

dout<=‖zzzzzzzz‖ AFTER 4 ns;

END IF;

END PROCESS;

PROCESS (din)

BEGIN

din_change<=NOW;

ASSERT (NOW-wr_rise>=300ps) -- 数据保持时间检查

REPORT ―HOLD ERROR din(sram)‖–若<300ps报警

SEVERITY WARNING; -- 表明数据有效时间END PROCESS; -- 太短,不能保证可

END behav; -- 靠写入

4)先进先出缓冲器(FIFO)

[例6-15 ] 试用VHDL设计一先进先出缓冲器(FIFO)。

要求:①存储器容量:8 * 4bit;

②当WR=0且FULL=0时,DIN的数据压入FIFO;

③当RD=0且EMPTY=0时,新的数据从DOUT输出。

分析:①信号线

·数据输入线:4条DIN(0) — DIN(3)

·数据输出线:4条DOUT(0) — DOUT(3)

·时钟线:1条CLK

·控制线:2条WR, RD

·状态线:2条FULL, EMPTY

②存储器示意图

06H

05H

04H

03H

02H

01H

③ WP: 写指示器,指示待写入单元地址;

RP:读指示器,指示已读出单元地址,读新值RP=RP+1

④ FIFO复位后,WP=0,RP=7,FIFO处于空状态;

⑤满信号产生条件:在RP=WP时,再写一个数据进入满状态;

空信号产生条件:在RP=WP-2时,再读一个数据进入空状态;源程序:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY fifo IS

GENERIC(k: INTEGER:=4;

w: INTEGER:= 8 );

PORT ( clk, reset, wr, rd: IN STD_LOGIC;

din: IN STD_LOGIC_VECTOR(k-1 DOWNTO 0);

dout: OUT STD_LOGIC_VECTOR(k-1 DOWNTO 0)

full, empty: OUT STD_LOGIC );

END fifo;

ARCHITECTURE behav OF fifo IS

SUBTYPE word IS STD_LOGIC_VECTOR(k-1 DOWNTO 0);

TYPE memory IS ARRAY (0 TO w -1) OF word ;

SIGNAL ram: memory;

SIGNAL wp, rp: INTEGER RANGE 0 TO w-1

SIGNAL in_full, in_empty: STD_LOGIC; ----中间变量

BEGIN

full<= in_full;

empty<=in_empty;

dout<=ram(rp);

PROCESS (clk) -- 数据写入缓冲区BEGIN

IF (clk‘EVENT AND clk=‘1‘) THEN

IF (wr=‘0‘ AND in_full=‘0‘) THEN

ram (wp)<=din ;

END IF;

END IF;

END PROCESS;

PROCESS (clk, reset) ----写数据指针修改(wp)BEGIN

IF (reset=‘1‘ ) THEN

wp<=0;

‘EVENT AND clk=‘1‘) THEN

‘0‘ AND in_full=‘0‘) THEN

wp<=0; ----缓冲区首尾相连

ELSE

wp<=wp+1;

END IF;

END IF;

END IF;

END PROCESS;

PROCESS (clk, reset) ----读数据指针修改(rp)BEGIN

IF (reset=‘1‘ ) THEN

rp<=w-1;

ELSEIF (clk‘EVENT AND clk=‘1‘) THEN

IF (rp=‘0‘ AND in_empty=‘0‘) THEN

IF (rp=w-1) THEN

rp<=0; ----缓冲区首尾相连

ELSE

rp<=rp+1;

END IF;

END IF;

END IF;

END PROCESS;

PROCESS (clk, reset) ---空标志的产生(empty=‘1’)BEGIN

IF (reset=‘1‘ ) THEN

in_empty<= ?1‘;

ELSEIF (clk‘EVENT AND clk=‘1‘) THEN

IF ((rp=wp-2 ----中间部位

OR (rp=w-1 AND wp=1) ---- 上部

OR (rp=w-2 AND wp=0)) ---- 下部

AND (rd=‘0‘ AND wr=‘1‘)) THEN

in_empty<= ?1‘; --“空”

ELSEIF (in_empty=‘1‘ AND wr=‘0‘) THEN

in_empty<= ?0‘; -- “不空”

END IF;

END IF;

END PROCESS;

PROCESS (clk, reset) ---满标志的产生(full=‘1‘)BEGIN

IF (reset=‘1‘ ) THEN

in_full<= ?0‘;

ELSEIF (clk‘EVENT AND clk=‘1‘) THEN

IF (rp=wp AND wr=‘0‘ and rd=‘1‘) THEN

in full<= ?1‘; -- “满”

ELSEIF (in_full=‘1‘ AND rd=‘0‘) THEN

in_full<= ?0‘; -- “不满”

END IF;

END IF;

END PROCESS

END behav;

/end/

相关主题
相关文档
最新文档