VHDL语言程序设计中INOUT端口的使用与实例分析.docx
《VHDL语言程序设计中INOUT端口的使用与实例分析.docx》由会员分享,可在线阅读,更多相关《VHDL语言程序设计中INOUT端口的使用与实例分析.docx(12页珍藏版)》请在冰点文库上搜索。
![VHDL语言程序设计中INOUT端口的使用与实例分析.docx](https://file1.bingdoc.com/fileroot1/2023-6/8/566bd327-36c8-44ff-83fe-b39f58ed6b57/566bd327-36c8-44ff-83fe-b39f58ed6b571.gif)
VHDL语言程序设计中INOUT端口的使用与实例分析
VHDL语言程序设计中INOUT端口的使用与实例分析
摘要:
VHDL是由美国国防部为描述电子电路所开发的一种语言,其全称为(VeryHighSpeedIntegratedCircuit)HardwareDescriptionLanguage。
与另外一门硬件描述语言VerilogHDL相比,VHDL更善于描述高层的一些设计,包括系统级(算法、数据通路、控制)和行为级(寄存器传输级),而且VHDL具有设计重用、大型设计能力、可读性强、易于编译等优点逐渐受到硬件设计者的青睐。
但是,VHDL是一门语法相当严格的语言,易学性差,特别是对于刚开始接触VHDL的设计者而言,经常会因某些小细节处理不当导致综合无法通过。
VHDL共定义了5种类型的端口,分别是In,Out,Inout,Buffer及Linkage,实际设计时只会用到前四种。
本文主要讨论讨论如何正确使用INOUT端口。
关键词:
VHDL;INOUT端口;三态门原理
1、双向电路的基本格式
工程应用中,双向电路是设计者不得不面对的问题.在实际应用中,数据总线往往是双向的.如何正确处理数据总线是进行时序逻辑电路设计的基础.在程序设计过程中,关键技术在于:
实体部分必须对端口属性进行申明,端口属性必须为inout类型,在构造体需要对输出信号进行有条件的高阻控制.在双向电路的处理问题上,常用的处理方式有两种,在介绍双向电路的处理方式之前,先看看双向电路的基本格式:
ENTITYbidir_pinIS
(
bidir:
INOUTstd_logic;
oe,clk,from_core:
INstd_logic;
to_core:
OUTstd_logic;
……
ENDbidir_pin;
ARCHITECTUREbehaviorOFbidir_pinIS
BEGIN
bidir<=from_coreWHENoe=‘1’ELSE“ZZZZ”;
to_core<=bidir;
ENDbehavior;
该程序揭示了双向电路的处理技巧,首先在实体部分bidir属于双向信号,在端口定义时,端口属性为inout类型,即把bidir信号作为输入三态输出.语句“bidir<=from_coreWHENoe=‘1’ELSE“ZZZZ”;”表示bidir信号三态输出,语句”to_core<=bidir;”把bidir信号作为输入信号.
由此可见,双向电路在程序设计中,didir输入当着普通的in类型,而在输出时,需要加一定的控制条件,三态输出.问题的关键在于:
如何确定这个条件?
2、控制条件
2.1、双向信号作一个信号的输入,作另一信号的输出
ENTITYbidirIS
PORT(
bidir:
INOUTSTD_LOGIC_VECTOR(7DOWNTO0);
oe,clk:
INSTD_LOGIC;
from_core:
INSTD_LOGIC_VECTOR(7DOWNTO0);
to_core:
OUTSTD_LOGIC_VECTOR(7DOWNTO0)
);
ENDbidir;
ARCHITECTURElogicOFbidirIS
SIGNALa:
STD_LOGIC_VECTOR(7DOWNTO0);
SIGNALb:
STD_LOGIC_VECTOR(7DOWNTO0);
BEGIN
PROCESS(clk)
BEGIN
IFclk='1'ANDclk'EVENTTHEN
a<=from_core;
to_core<=b;
ENDIF;
ENDPROCESS;
PROCESS(oe,bidir)
BEGIN
IF(oe='0')THEN
bidir<="ZZZZZZZZ";
b<=bidir;
ELSE
bidir<=a;
b<=bidir;
ENDIF;
ENDPROCESS;
ENDlogic;
这种设计方式叫做寄存双向信号的方法.本设计中bidir为双向信号,from_core为数据输入端,to_core为数据输出端,oe为三态输出使能,clk为读写数据的时钟.在程序设计中,需要定义两个signala和b信号.a信号用于输入数据from_core的寄存器,b用于输出数据to_core的寄存器.采用寄存器的方法需要设计两个进程,一个进程把a,b信号在时钟的控制下负责端口的输入信号from_core和端口输出信号to_core的连接,这一步实现了寄存双向的功能.另外一个进程则负责信号a,b和双向口之间的赋值关系.本设计只揭示了简单的双向信号操作方式,即bidir既可以作为from_core的输出,又可以作为to_core的输入
2.2、双向信号既做输出又做输出
上例是最简单的双向信号应用的特例.在实际的工程中,双向信号既做信号的输入,又做信号的输出,常见的数据总线就是这种操作模式.
libraryIEEE;
useIEEE.STD_LOGIC_1164.all;
entitydir_datais
port(
clk:
inSTD_LOGIC;
rst:
inSTD_LOGIC;
rw:
inSTD_LOGIC;
address:
inSTD_LOGIC_VECTOR(1downto0);
data:
inoutSTD_LOGIC_VECTOR(7downto0)
);
enddir_data;
architecturearc_dirofdir_datais
signaldata_in:
STD_LOGIC_VECTOR(7downto0);
signaldata_out:
STD_LOGIC_VECTOR(7downto0);
signalreg_a:
STD_LOGIC_VECTOR(7downto0);
signalreg_b:
STD_LOGIC_VECTOR(7downto0);
begin
data_in<=data;
d1:
process(clk,rst,rw)
begin
ifrst='1'then
reg_a<=(others=>'0');
reg_b<=(others=>'0');
elsifclk'eventandclk='1'then
ifrw='1'then
ifaddress="00"then
reg_a<=data_in;
elsifaddress="01"then
reg_b<=data_in;
elsenull;
endif;
elsenull;
endif;
elsenull;
endif;
endprocessd1;
d2:
process(clk,rw,reg_a,reg_b)
begin
ifclk'eventandclk='1'then
ifrw='0'then
ifaddress="00"then
data_out<=reg_a;
elsifaddress="01"then
data_out<=reg_b;
elsenull;
endif;
elsenull;
endif;
elsenull;
endif;
endprocessd2;
data<=data_outwhen(rw='0'andaddress
(1)='0')else
(others=>'Z');
endarc_dir;
3、实例说明-INOUT端口仿真暨三态门仿真
3.1、三态门的原理与仿真三态总线
三态输出缓冲器,即三态门,是指逻辑门的输出除有高、低电平两种状态外,还有第三种状态——高阻状态的门电路。
高阻态相当于隔断状态(电阻很大,相当于开路)。
三态门都有一个EN控制使能端,来控制门电路的通断。
可以具备这三种状态的器件就叫做三态。
图1 TTL逻辑三态门的构成图
当EN端接低电平时,反相器输出一个高电平给T1 ,使整个电路处于工作状态,这样,电路将按与非关系把A,B接受到的信号传送到输出端,使Y或为高电平,或为低电平。
当EN端接高电平时,反相器输出低电平给T1,使T1、T5截止。
另一方面,通过D把T4的基极电位钳在1v左右,使T4截止。
由于T4、T5均截止,从输出端Y
看进去,电路处于高阻状态。
图2文章中的所要仿真的三态总线
如图2所示,总线宽度设为4bit。
WE和RE分别是读写使能信号,低有效。
假设这是一个和DSP的EMIF接口的逻辑模块,在DSP写(WE=0)时,将dataInOut(EMIF)上的数据从dataOut输出;当DSP读(RE=0)时,将dataIn上的数据送到dataInOut(EMIF)上。
约定WE和RE在空闲时都为高,并且二者不能同时为低
3.3、VHDL的三态门实现与仿真
library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity vhdlTBUF is
Port ( clk :
in STD_LOGIC;
datain :
in STD_LOGIC_VECTOR (3 downto 0); dataout :
out STD_LOGIC_VECTOR (3 downto 0); dsta :
inout STD_LOGIC_VECTOR (3 downto 0); we :
in STD_LOGIC; re :
in STD_LOGIC);
end vhdlTBUF;
architecture Behavioral of vhdlTBUF is begin
process(clk,we) begin
if(clk'event and clk='1') then
if(we='0') then
dataout<=dsta;
end if;
end if;
end process; --读取部分
process(clk,re) begin
if(clk'event and clk='1') then
if(re='0') then
dsta<=datain;
else dsta<="ZZZZ";
end if; end if;
---================================================================
如果期望和verilog的代码有一样的综合结果,请使用下面的话描述读取,即异步读取。
--dsta<=datain when re='0' else -- "ZZZZ";
---================================================================
end process; end Behavioral;
在上面的程序中可以看出,对DSP的写数据,三态逻辑模块直接将其同步锁存到寄存器中;对DSP的读数据,在RE有效时输出数据,RE无效时输出Z态。
这样的实现符合FPGA的管脚结构。
if(we='0') then
dataout<=dsta;
end if; end if;
end process; --读取部分
process(clk,re)
begin
if(clk'event and clk='1') then
if(re='0') then
dsta<=datain;
else
dsta<="ZZZZ";
end if; end if;
---================================================================ --如果期望和verilog的代码有一样的综合结果,请使用下面的话描述读取,即异步读取。
--dsta<=datain when re='0' else -- "ZZZZ";
---================================================================ end process; end Behavioral;
在上面的程序中可以看出,对DSP的写数据,三态逻辑模块直接将其同步锁存到寄存器中;对DSP的读数据,在RE有效时输出数据,RE无效时输出Z态。
这样的实现符合图1所示的FPGA的管脚结构。
testbench:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_TEXTIO.ALL; USE STD.TEXTIO.ALL;
ENTITY test IS END test;
ARCHITECTURE testbench_arch OF test IS
FILE RESULTS:
TEXT OPEN WRITE_MODE IS "results.txt";
COMPONENT vhdlTBUF PORT (
clk :
In std_logic;
datain :
In std_logic_vector (3 DownTo 0); dataout :
Out std_logic_vector (3 DownTo 0); dsta :
InOut std_logic_vector (3 DownTo 0); we :
In std_logic;
re :
In std_logic );
END COMPONENT;
SIGNAL clk :
std_logic :
= '0';
SIGNAL datain :
std_logic_vector (3 DownTo 0) :
= "0000"; SIGNAL dataout :
std_logic_vector (3 DownTo 0) :
= "0000"; SIGNAL dsta :
std_logic_vector (3 DownTo 0) :
= "ZZZZ"; SIGNAL we :
std_logic :
= '0';
SIGNAL re :
std_logic :
= '0';
constant PERIOD :
time :
= 200 ns;
constant DUTY_CYCLE :
real :
= 0.5;
constant OFFSET :
time :
= 100 ns;
BEGIN
UUT :
vhdlTBUF
PORT MAP (
clk => clk
datain => datain,
dataout => dataout,
dsta => dsta,
we => we,
re => re);
PROCESS BEGIN
WAIT for OFFSET;
CLOCK_LOOP :
LOOP
clk <= '0';
WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE)); clk <= '1';
WAIT FOR (PERIOD * DUTY_CYCLE); END LOOP CLOCK_LOOP;
END PROCESS;
PROCESS
BEGIN
WAIT FOR 100 ns; we <= '1'; re <= '1';
datain <= "0101"; WAIT FOR 285 ns;
re <= '0'; WAIT FOR 400 ns;
re <= '1'; WAIT FOR 400 ns; we <= '0';
dsta <= "0100"; WAIT FOR 400 ns; we <= '1';
dsta <= "ZZZZ"; WAIT FOR 615 ns; END PROCESS;
END testbench_arch;
参考在VHDL语言里三态门仿真最重要的一点就是在初始化的时候必须将总线初始化成Z态。
不仅如此,在往总线上写的时候,写数据满足要求后要立即将总线恢复成Z态,这样才不至于影响总线上的读取。
原因还是如图1的FPGA管脚结构决定的。
每一个总线管脚都可以看成输入和输出两部分,这里总线的初始化和赋值相当于总线的输出,即DSP的写。
总线赋值如果不是Z,那么当RE=1,三态逻辑模块的输出是Z,总线即为所赋值;当RE=0时,逻辑模块输出dataIn的值,这些值如果和总线上的DSP写的值不一样,如0和1相遇,那么总线上就会出现X状态。
综述一句,对于VHDL语言三态门仿真,对待总线只要不是DSP写,就要将其置成Z态。
仿真和综合结果参考图3、图4和图4。
从图上可以看出,同步的三态总线和异步的三态总线差别在于三态门的前面是否加了一个同步的D触发器。
仿真时序图上能够清楚的看出来同步三态门的输出和时钟的同步。
在实际的逻辑设计中建议尽可能使用同步逻辑。
图3
图4
图5
参考文献
[1]VHDL的一些心得体会,
[2]XX文库,FPGA 中双向端口IO的研究
[3]潘松,VHDL实用教程[J],电子科技大学出版社,2000-03-01
[4]姜立东等,VHDL语言程序设计及应用[J],北京邮电大学出版社 ,2001-8-1
VHDLlanguage programming INOUT portusage andcaseanalysis
Liukun
Riverside College,Nanjing UniversityofInformationScience DepartmentofElectronicEngineering, Nanjing 210044
Abstract:
VHDL bytheU.S. DepartmentofDefense developed todescribetheelectroniccircuit inalanguage, its fullname (VeryHighSpeedIntegratedCircuit)HardwareDescriptionLanguage. Withtheadditionof a hardwaredescriptionlanguage VerilogHDL compared,VHDL descriptions arebetterat some high-leveldesign,including system-level (algorithms,data path, control) and behavioral (registertransferlevel) and VHDL designreuse with large designcapacity ,readable, easytobuild,etc. graduallyby hardwaredesigners ofallages. However,VHDL is a verystrictsyntax language, learn ofthepoor, especiallyfor justgettingstartedwith theVHDLdesigners, often due toimproper handling ofcertain smalldetails cannotpasscomprehensive. VHDL definesatotalof fivetypesof ports, respectively, In,Out,Inout,Buffer and Linkage, practicaldesign willonlyuse thefirstfour. Thisarticlefocuses onhow theproperuseof INOUT port.