VHDL语言程序设计中INOUT端口的使用与实例分析
目录1、双向电路的基本格式 (2)2、控制条件 (3)2.1、双向信号作一个信号的输入,作另一信号的输出 (3)2.2、双向信号既做输出又做输出 (4)3、实例说明-INOUT端口仿真暨三态门仿真 (6)3.1、三态门的原理与仿真三态总线 (6)3.3、VHDL 的三态门实现与仿真 (7)参考文献 (12)VHDL语言程序设计中INOUT端口的使用与实例分析摘要:VHDL是由美国国防部为描述电子电路所开发的一种语言,其全称为(Very High Speed Integrated Circuit) Hardware Description Language。
与另外一门硬件描述语言Verilog HDL相比,VHDL 更善于描述高层的一些设计,包括系统级(算法、数据通路、控制)和行为级(寄存器传输级),而且VHDL 具有设计重用、大型设计能力、可读性强、易于编译等优点逐渐受到硬件设计者的青睐。
但是,VHDL是一门语法相当严格的语言,易学性差,特别是对于刚开始接触VHDL的设计者而言,经常会因某些小细节处理不当导致综合无法通过。
VHDL共定义了5种类型的端口,分别是In, Out,Inout, Buffer及Linkage,实际设计时只会用到前四种。
本文主要讨论讨论如何正确使用INOUT端口。
关键词:VHDL;INOUT端口;三态门原理1、双向电路的基本格式工程应用中,双向电路是设计者不得不面对的问题.在实际应用中,数据总线往往是双向的.如何正确处理数据总线是进行时序逻辑电路设计的基础.在程序设计过程中,关键技术在于:实体部分必须对端口属性进行申明,端口属性必须为inout类型,在构造体需要对输出信号进行有条件的高阻控制.在双向电路的处理问题上,常用的处理方式有两种,在介绍双向电路的处理方式之前,先看看双向电路的基本格式:ENTITY bidir_pin IS(bidir : INOUT std_logic;oe, clk, from_core : IN std_logic;to_core : OUT std_logic;……END bidir_pin;ARCHITECTURE behavior OF bidir_pin ISBEGINbidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;to_core <= bidir;END behavior;该程序揭示了双向电路的处理技巧,首先在实体部分bidir属于双向信号,在端口定义时,端口属性为inout类型,即把bidir信号作为输入三态输出. 语句“bidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;”表示bidir信号三态输出,语句”to_core <= bidir;”把bidir信号作为输入信号.由此可见,双向电路在程序设计中,didir输入当着普通的in类型,而在输出时,需要加一定的控制条件,三态输出.问题的关键在于:如何确定这个条件?2、控制条件2.1、双向信号作一个信号的输入,作另一信号的输出ENTITY bidir ISPORT(bidir : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);oe, clk : IN STD_LOGIC;from_core : IN STD_LOGIC_VECTOR (7 DOWNTO 0);to_core : OUT STD_LOGIC_VECTOR (7 DOWNTO 0));END bidir;ARCHITECTURE logic OF bidir ISSIGNAL a : STD_LOGIC_VECTOR (7 DOWNTO 0);SIGNAL b : STD_LOGIC_VECTOR (7 DOWNTO 0);BEGINPROCESS (clk)BEGINIF clk = '1' AND clk'EVENT THENa <= from_core;to_core <= b;END IF;END PROCESS;PROCESS (oe, bidir)BEGINIF( oe = '0') THENbidir <= "ZZZZZZZZ";b <= bidir;ELSEbidir <= a;b <= bidir;END IF;END PROCESS;END logic;这种设计方式叫做寄存双向信号的方法.本设计中bidir为双向信号,from_core为数据输入端,to_core为数据输出端,oe为三态输出使能,clk为读写数据的时钟.在程序设计中,需要定义两个signal a和b信号.a信号用于输入数据from_core的寄存器,b用于输出数据to_core的寄存器.采用寄存器的方法需要设计两个进程,一个进程把a,b信号在时钟的控制下负责端口的输入信号from_core和端口输出信号to_core的连接,这一步实现了寄存双向的功能.另外一个进程则负责信号a,b和双向口之间的赋值关系.本设计只揭示了简单的双向信号操作方式,即bidir既可以作为from_core的输出,又可以作为to_core的输入2.2、双向信号既做输出又做输出上例是最简单的双向信号应用的特例.在实际的工程中,双向信号既做信号的输入,又做信号的输出,常见的数据总线就是这种操作模式.library IEEE;use IEEE.STD_LOGIC_1164.all;entity dir_data isport(clk : in STD_LOGIC;rst : in STD_LOGIC;rw : in STD_LOGIC;address : in STD_LOGIC_VECTOR(1 downto 0);data : inout STD_LOGIC_VECTOR(7 downto 0));end dir_data;architecture arc_dir of dir_data issignal data_in : STD_LOGIC_VECTOR(7 downto 0);signal data_out: STD_LOGIC_VECTOR(7 downto 0);signal reg_a: STD_LOGIC_VECTOR(7 downto 0);signal reg_b: STD_LOGIC_VECTOR(7 downto 0);begindata_in<=data;d1:process(clk,rst,rw)beginif rst='1' thenreg_a<= (others=>'0');reg_b<= (others=>'0');elsif clk'event and clk='1' then if rw='1' thenif address="00" thenreg_a<=data_in;elsif address="01" thenreg_b<=data_in;else null;end if;else null;end if;else null;end if;end process d1;d2:process(clk,rw,reg_a,reg_b) beginif clk'event and clk='1' thenif rw='0' thenif address="00" thendata_out<=reg_a;elsif address="01" thendata_out<=reg_b;else null;end if;else null;end if;else null;end if;end process d2;data<=data_out when (rw='0' and address(1)='0') else(others=>'Z');end arc_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 isPort ( 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 beginprocess(clk,we) beginif(clk'event and clk='1') thenif(we='0') thendataout<=dsta;end if;end if;end process; --读取部分process(clk,re) beginif(clk'event and clk='1') thenif(re='0') thendsta<=datain;else dsta<="ZZZZ";end if; end if;---================================================================ 如果期望和verilog的代码有一样的综合结果,请使用下面的话描述读取,即异步读取。
汇编语言中OUT和IN的用法
汇编语言中OUT和IN的用法在汇编语言中,OUT和IN是两条常用的指令,用于进行输入输出操作。
OUT指令用于向外部设备输出数据,而IN指令则用于从外部设备读取数据。
本文将详细介绍这两条指令的用法和常见应用情况。
一、OUT指令的用法OUT指令用于将数据从微处理器输出到外部设备,通常用于与键盘、显示器等设备的交互。
OUT指令的格式如下:```OUT DX, AL```其中,DX为输出端口的地址,而AL为要输出的数据。
OUT指令的使用步骤如下:1. 向DX寄存器中加载要输出数据的端口地址;2. 使用AL寄存器存放要输出的数据;3. 执行OUT指令完成输出操作。
例如,若需要向端口地址为80h的显示器输出数据55h,可以使用如下汇编代码:```MOV DX, 80hMOV AL, 55hOUT DX, AL```这样,55h将被输出到端口地址为80h的显示器上。
二、IN指令的用法与OUT指令相反,IN指令用于从外部设备读取数据到微处理器中,用于实现键盘、鼠标等设备的输入操作。
IN指令的格式如下:```IN AL, DX```其中,AL为读取到的数据,而DX为输入端口的地址。
IN指令的使用步骤如下:1. 向DX寄存器中加载要读取数据的端口地址;2. 执行IN指令,将读取到的数据存放到AL寄存器中。
例如,若需要从端口地址为60h的键盘读取数据,可以使用如下汇编代码:```MOV DX, 60hIN AL, DX```这样,从键盘读取到的数据将被存放在AL寄存器中。
三、OUT和IN的常见应用1. 输入和输出控制:通过OUT指令向显示器输出字符、控制光标位置等;通过IN指令从键盘读取字符,实现用户输入控制。
2. 与外设通信:通过OUT指令向串口、并口等外部设备输出数据,用于与其它设备进行通信;通过IN指令从这些外部设备读取数据,实现数据的接收和处理。
3. 程序调试与测试:在程序调试时,可以使用OUT指令将调试信息输出到控制台或显示器上,方便程序员进行调试;同时,可以使用IN指令从特定的端口读取调试信息,实现程序的测试与分析。
inout 申明参数
inout 申明参数(实用版)目录1.介绍 inout 申明参数2.inout 参数的作用3.inout 参数的使用方法4.inout 参数的注意事项5.结论正文一、介绍 inout 申明参数inout 申明参数是编程语言中一种用于声明输入输出参数的方式。
在函数或方法中,我们经常需要接收从外部传入的数据,或者将函数或方法的结果返回给外部,这时候就需要使用 inout 申明参数。
二、inout 参数的作用inout 参数主要用于在函数或方法中接收外部传入的数据,同时也可以将函数或方法的结果返回给外部。
通过使用 inout 参数,可以方便地实现数据的传递和返回,使程序的逻辑更加清晰。
三、inout 参数的使用方法在使用 inout 参数时,需要在声明函数或方法时,在参数前加上inout 关键字。
在调用函数或方法时,将需要传入或返回的数据赋值给inout 参数,程序会自动处理数据的传递和返回。
例如,假设有一个函数`calculate`,需要接收一个整数参数`num`,并返回一个计算结果。
我们可以使用 inout 参数来声明这个函数:```def calculate(num: inout int):result = num * 2num = result```在调用这个函数时,可以直接将一个整数赋值给`num`参数,程序会自动将计算结果返回给`num`:```var num = 10calculate(num)print(num) // 输出 20```四、inout 参数的注意事项在使用 inout 参数时,需要注意以下几点:1.不能将一个常量赋值给 inout 参数,因为常量不能被修改。
2.在调用函数或方法时,需要确保传入的参数是可变的,否则程序会报错。
3.使用 inout 参数时,应尽量避免在多个地方同时修改一个参数,以免引起数据不一致的问题。
五、结论总之,inout 申明参数是编程语言中一种方便的数据传递和返回方式。
verilog中双向端口inout的使用的心得
verilog中双向端口inout的使用的心得见许多问这个问题的,总结一下,希望能对大家有点用处,如果有不对的地方,欢迎指出.芯片外部引脚很多都使用inout类型的,为的是节省管腿。
一般信号线用做总线等双向数据传输的时候就要用到INOUT类型了。
就是一个端口同时做输入和输出。
inout在具体实现上一般用三态门来实现。
三态门的第三个状态就是高阻'Z'。
当inout端口不输出时,将三态门置高阻。
这样信号就不会因为两端同时输出而出错了,更详细的内容可以搜索一下三态门tri-state的资料.1 使用inout类型数据,可以用如下写法:inout data_inout;input data_in;reg data_reg;//data_inout的映象寄存器reg link_data;assign data_inout=link_data?data_reg:1’bz;//link_data控制三态门//对于data_reg,可以通过组合逻辑或者时序逻辑根据data_in对其赋值.通过控制link_data 的高低电平,从而设置data_inout是输出数据还是处于高阻态,如果处于高阻态,则此时当作输入端口使用.link_data可以通过相关电路来控制.2 编写测试模块时,对于inout类型的端口,需要定义成wire类型变量,而其它输入端口都定义成reg类型,这两者是有区别的.当上面例子中的data_inout用作输入时,需要赋值给data_inout,其余情况可以断开.此时可以用assign语句实现:assign data_inout=link?data_in_t:1’bz;其中的link ,data_in_t 是reg类型变量,在测试模块中赋值.另外,可以设置一个输出端口观察data_inout用作输出的情况:Wire data_out;Assign data_out_t=(!link)?data_inout:1’bz;else,in RTLinout use in top module(PAD)dont use inout(tri) in sub module也就是说,在内部模块最好不要出现inout,如果确实需要,那么用两个port实现,到顶层的时候再用三态实现。
verilog input output inout 用法-概述说明以及解释
verilog input output inout 用法-概述说明以及解释1.引言1.1 概述引言是文章开头的一部分,用于介绍文章要讨论的主题。
在这篇文章中,我们将探讨Verilog中的input、output和inout的用法。
Verilog是一种硬件描述语言,被广泛应用于数字电子系统的设计和验证。
在数字电路设计中,输入(input)、输出(output)和双向的输入输出(inout)信号是非常重要的概念。
input关键字用于定义模块的输入信号,它们是外部输入到模块中的信号。
output关键字用于定义模块的输出信号,它们是从模块中输出到外部的信号。
而inout关键字则用于定义双向的输入输出信号,它们既可以从外部输入到模块中,也可以从模块中输出到外部。
在本文的后续部分,我们将详细介绍Verilog中input、output和inout的用法,包括定义变量、使用信号等方面。
通过学习这些内容,读者将能够更好地理解和应用Verilog语言,并能够利用它进行数字电路设计和验证。
接下来我们将进入正文部分,首先介绍Verilog中input的用法。
文章结构部分的内容如下:1.2 文章结构本文将对Verilog中的input、output和inout的用法进行详细介绍。
首先,将在引言部分概述Verilog的基本概念和应用场景。
然后,通过正文部分分别介绍input、output和inout的定义和使用方法。
在每个小节中,将详细说明如何定义相应的变量,并说明如何使用这些变量进行输入、输出和双向信号的传输。
在每个小节结束时,将提供实际示例以帮助读者更好地理解和应用Verilog中的input、output和inout。
在结论部分,将对各个部分进行总结,分别总结input、output和inout的用法,包括定义和使用方法等重要内容。
通过本文的阅读,读者将能够全面了解Verilog中input、output和inout的用法,并能够灵活应用于实际的工程设计中。
Verilog inout 双向口使用和仿真
Verilog inout 双向口使用和仿真芯片外部引脚很多都使用inout类型的,为的是节省管腿。
一般信号线用做总线等双向数据传输的时候就要用到INOUT类型了。
就是一个端口同时做输入和输出。
inout在具体实现上一般用三态门来实现。
三态门的第三个状态就是高阻' Z'。
当inout端口不输出时,将三态门置高阻。
这样信号就不会因为两端同时输出而出错了,更详细的内容可以搜索一下三态门tri-state的资料.1 使用inout类型数据,可以用如下写法:inout data_inout;input data_in;reg data_reg;//data_inout的映象寄存器reg link_data;assign data_inout=link_data?data_reg:1’bz;//link_data控制三态门//对于data_reg,可以通过组合逻辑或者时序逻辑根据data_in对其赋值.通过控制link_data的高低电平,从而设置data_inout是输出数据还是处于高阻态,如果处于高阻态,则此时当作输入端口使用.link_data可以通过相关电路来控制.2 编写测试模块时,对于inout类型的端口,需要定义成wire类型变量,而其它输入端口都定义成reg类型,这两者是有区别的.当上面例子中的data_inout用作输入时,需要赋值给data_inout,其余情况可以断开.此时可以用assign语句实现:assign data_inout=link?data_in_t:1’bz;其中的l ink ,data_in_t是reg类型变量,在测试模块中赋值.另外,可以设置一个输出端口观察data_inout用作输出的情况:Wire data_out;Assign data_out_t=(!link)?data_inout:1’bz;else,in RTLinout use in top module(PAD)dont use inout(tri) in sub module也就是说,在内部模块最好不要出现inout,如果确实需要,那么用两个port实现,到顶层的时候再用三态实现。
【FPGA基础】双向端口inout端口的使用指北
【FPGA基础】双向端⼝inout端⼝的使⽤指北在查阅了各种书和帖⼦之后,总结了以下inout端⼝的使⽤注意事项。
(以下资料来源: 《Xilinx FPGA开发实⽤教程第⼆版》)⾸先是⼀些要先理解的基本概念:0、什么是双向端⼝inout端⼝ 顾名思义,双向端⼝既可以作为输⼊端⼝接收数据,也可以作为输出端⼝发出数据,它对数据的操作是双向的。
双向端⼝在综合时是以三态门的形式存在的,其典型结构如图所⽰。
1、三态门 在Xilinx的《XST User Guide》中给出了三态门的verilog描述1// Tristate Description Using Concurrent Assignment23// Combinatorial Always Block Can be Used too.45module v_three_st_2 (T, I, O);67input T, I;89output O;1011assign O = (~T) ? I: 1’bZ;1213endmodule 上述描述表明,当控制信号T=1时,管⼦被置为⾼阻态,输出O为⾼阻态;当控制信号T=0时,管⼦开通,输出O=输⼊I。
(跟控制信号T是⾼有效或低有效有关)2、⾼阻和悬空 三态门中有⼀个状态是⾼阻。
⾼阻,即可以认为是没有输出,作为输出端⼝⽽⾔,对下级电路没有任何影响。
悬空是针对输⼊端⼝来说的,也就是说没有接输⼊。
这也就意味着,实际上⾼阻和悬空是⼀个状态,在HDL语⾔⾥都表⽰为Z。
也就是说,⼀个输出端⼝在⾼阻态的时候,其状态是由于其相连的其他电路决定的,可以将其看作是输⼊。
双向端⼝⽤作输出时,就和平常⼀样,但双向端⼝作输⼊引脚时需要将此引脚置为⾼阻态,这样其电平就可以由外部输⼊信号决定了(这是⾼阻态的特性)。
在上述基本概念的基础上,讨论三个⽅⾯的问题:⼀、双向端⼝的实现原理 通过上⾯的基本概念应该已经清楚双向端⼝的实现原理了,只要搞清楚上⾯管⼦的开通状态与整个双向端⼝的对外特性之间的关系就⾏了。
verilog中双向端口inout地使用地心得
verilog中双向端口inout的使用的心得见许多问这个问题的,总结一下,希望能对大家有点用处,如果有不对的地方,欢迎指出.芯片外部引脚很多都使用inout类型的,为的是节省管腿。
一般信号线用做总线等双向数据传输的时候就要用到INOUT类型了。
就是一个端口同时做输入和输出。
inout在具体实现上一般用三态门来实现。
三态门的第三个状态就是高阻'Z'。
当inout端口不输出时,将三态门置高阻。
这样信号就不会因为两端同时输出而出错了,更详细的内容可以搜索一下三态门tri-state的资料.1 使用inout类型数据,可以用如下写法:inout data_inout;input data_in;reg data_reg;//data_inout的映象寄存器reg link_data;assign data_inout=link_data?data_reg:1’bz;//link_data控制三态门//对于data_reg,可以通过组合逻辑或者时序逻辑根据data_in对其赋值.通过控制link_data的高低电平,从而设置data_inout是输出数据还是处于高阻态,如果处于高阻态,则此时当作输入端口使用.link_data可以通过相关电路来控制.2 编写测试模块时,对于inout类型的端口,需要定义成wire类型变量,而其它输入端口都定义成reg类型,这两者是有区别的.当上面例子中的data_inout用作输入时,需要赋值给data_inout,其余情况可以断开.此时可以用assign语句实现:assign data_inout=link?data_in_t:1’bz;其中的link ,data_in_t是reg类型变量,在测试模块中赋值.另外,可以设置一个输出端口观察data_inout用作输出的情况:Wire data_out;Assign data_out_t=(!link)?data_inout:1’bz;else,in RTLinout use in top module(PAD)dont use inout(tri) in sub module也就是说,在内部模块最好不要出现inout,如果确实需要,那么用两个port实现,到顶层的时候再用三态实现。
vhdl iobuf语句
vhdl iobuf语句IOBUF语句是VHDL中的一种类型,用于定义输入输出缓冲器。
它在FPGA设计中具有重要的作用,可以实现输入和输出信号的驱动和接收。
本文将列举一些常见的IOBUF语句,并对其功能进行简要说明。
1. IOBUF语句用于定义一个输入输出缓冲器。
例如:```vhdlIOBUF_inst : IOBUFport map (I => input_signal, O => output_signal, T => enable_signal, IO => bidirectional_signal);```这个语句定义了一个名为IOBUF_inst的IOBUF实例,它将输入信号input_signal通过输出信号output_signal输出,同时通过使能信号enable_signal控制输出的有效性。
2. IOBUF语句可以用于实现双向通信。
例如:```vhdlIOBUF_inst : IOBUFport map (I => input_signal, O => output_signal, T => enable_signal, IO => bidirectional_signal);```这个语句将输入信号input_signal通过输出信号output_signal输出,同时也可以通过bidirectional_signal接收外部信号。
3. IOBUF语句还可以实现输入信号的驱动。
例如:```vhdlIOBUF_inst : IOBUFport map (I => input_signal, O => open, T => enable_signal, IO => open);```这个语句将输入信号input_signal通过IOBUF实例直接驱动到外部,输出信号O和IO都设置为open,表示开路。
4. IOBUF语句可以用于实现输出信号的接收。
VHDL中双向端口设计小结【转】
VHDL中双向端口设计小结【转】FPGA / VHDL 2009-08-03 16:00 阅读53 评论0字号:大中小在工程应用中,双向电路是设计者不得不面对的问题.在实际应用中,数据总线往往是双向的.如何正确处理数据总线是进行时序逻辑电路设计的基础.在程序设计过程中,关键技术在于:实体部分必须对端口属性进行申明,端口属性必须为inout类型,在构造体需要对输出信号进行有条件的高阻控制.在双向电路的处理问题上,常用的处理方式有两种,在介绍双向电路的处理方式之前,先看看双向电路的基本格式:ENTITY bidir_pin IS(bidir : INOUT std_logic;oe, clk, from_core : IN std_logic;to_core : OUT std_logic;……END bidir_pin;ARCHITECTURE behavior OF bidir_pin ISBEGINbidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;to_core <= bidir;END behavior;该程序揭示了双向电路的处理技巧,首先在实体部分bidir属于双向信号,在端口定义时,端口属性为inout类型,即把bidir信号作为输入三态输出.语句“bidir <= from_core WHEN oe=‘1’ ELSE “ZZZZ”;”表示bidi r信号三态输出,语句”to_core <= bidir;”把bidir信号作为输入信号. 由此可见,双向电路在程序设计中,didir输入当着普通的in类型,而在输出时,需要加一定的控制条件,三态输出.问题的关键在于:如何确定这个条件?1)双向信号作一个信号的输入,作另一信号的输出ENTITY bidir ISPORT(bidir : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0);oe, clk : IN STD_LOGIC;from_core : IN STD_LOGIC_VECTOR (7 DOWNTO 0);to_core : OUT STD_LOGIC_VECTOR (7 DOWNTO 0));END bidir;ARCHITECTURE logic OF bidir ISSIGNAL a : STD_LOGIC_VECTOR (7 DOWNTO 0);SIGNAL b : STD_LOGIC_VECTOR (7 DOWNTO 0);BEGINPROCESS (clk)BEGINIF clk = '1' AND clk'EVENT THENa <= from_core;to_core <= b;END IF;END PROCESS;PROCESS (oe, bidir)BEGINIF( oe = '0') THENbidir <= "ZZZZZZZZ";b <= bidir;ELSEbidir <= a;b <= bidir;END IF;END PROCESS;END logic;这种设计方式叫做寄存双向信号的方法.本设计中bidir为双向信号,from _core为数据输入端,to_core为数据输出端,oe为三态输出使能,clk为读写数据的时钟.在程序设计中,需要定义两个signal a和b信号.a信号用于输入数据from_core的寄存器,b用于输出数据to_core的寄存器.采用寄存器的方法需要设计两个进程,一个进程把a,b信号在时钟的控制下负责端口的输入信号from_core和端口输出信号to_core的连接,这一步实现了寄存双向的功能.另外一个进程则负责信号a,b和双向口之间的赋值关系.本设计只揭示了简单的双向信号操作方式,即bidir既可以作为from_core的输出,又可以作为to_core的输入2)双向信号既做输出又做输出上例是最简单的双向信号应用的特例.在实际的工程中,双向信号既做信号的输入,又做信号的输出,常见的数据总线就是这种操作模式.library IEEE;use IEEE.STD_LOGIC_1164.all;entity dir_data isport(clk : in STD_LOGIC;rst : in STD_LOGIC;rw : in STD_LOGIC;address : in STD_LOGIC_VECTOR(1 downto 0);data : inout STD_LOGIC_VECTOR(7 downto 0));end dir_data;architecture arc_dir of dir_data issignal data_in : STD_LOGIC_VECTOR(7 downto 0);signal data_out: STD_LOGIC_VECTOR(7 downto 0);signal reg_a: STD_LOGIC_VECTOR(7 downto 0);signal reg_b: STD_LOGIC_VECTOR(7 downto 0);begindata_in<=data;d1:process(clk,rst,rw)beginif rst='1' thenreg_a<= (others=>'0');reg_b<= (others=>'0');elsif clk'event and clk='1' thenif rw='1' thenif address="00" thenreg_a<=data_in;elsif address="01" thenreg_b<=data_in;else null;end if;else null;end if;else null;end if;end process d1;d2:process(clk,rw,reg_a,reg_b)beginif clk'event and clk='1' thenif rw='0' thenif address="00" thendata_out<=reg_a;elsif address="01" thendata_out<=reg_b;else null;end if;else null;end if;else null;end if;end process d2;data<=data_out when (rw='0' and address(1)='0') else(others=>'Z');end arc_dir;在程序设计中,首先需要定义data_in, data_out, reg_a, reg_b四个si gnal,我们把data_in叫做输入寄存器,它是从双向信号data接收数据的寄存器,data_out叫做输出寄存器,它是向双向信号data发送信号的寄存器, reg_a和reg_b叫做操作寄存器,它们是在一定的时序控制下把data_in数据送给reg_a,reg_b,在一定的时序控制下从reg_a和reg_b读出数据的. 这样的处理方式必须有两个进程,因为在architecture arc_dir of dir_ data is和begin之间定义了data_in, data_out, reg_a, reg_b四个signal,它在同一进程内不支持既赋值,又调用,也就是说它不支持在d1进程中对信号reg_a, reg_b赋值,又在d1进程中又调用reg_a, reg_b.首先有语句”data_in<=data;”它表示输入寄存器无条件的接收双先信号的数据.在d1进程中,首先在rst信号有效时,对操作寄存器reg_a,和reg_b进行清零操作,然后在时钟(clk)的控制下,在写(rw)信号有效的情况下,对reg_a, reg_b寄存器在不同的地址控制下写入不同的data_in值.在d2进程中,在时钟(clk)的控制下,在读(rw)信号有效的时候,把不同地址的reg_a, reg_b的值送进data_out中.最关键的是最后一句:“data<=data_out when (rw='0' and address(1)='0') else (others=>'Z');”它表示双向信号的三态输出,而最最关键的是when后面的条件,如果条件限制太宽,就会错误占用双向信号总线,引起总线的误操作,如果条件限制太窄,输出寄存器的数据就不能够正确的送到数据总线上去,会引起数据的丢失.也就是说,只有正确的限制了when语句后面的条件,才能够把输出寄存器的数据正确地送到数据总线上去.仔细查看此条件,有如下的规律:when语句后的条件是操作寄存器写入输出寄存器的条件的公共条件.比如:rw=’0’是操作寄存器的数据写入输出寄存器的读使能信号,address(1)是地址线的公共部分.在实际工程应用中,需要设计者在分配地址总线的时候掌握一定的技巧,尽量从地址的低位到到高位,保证地址总线有更多位的公共部分,比如只对四个寄存器操作时,地址线分配为”100”,”010”,”110”,”001”是不科学的,而”000”,”001”,”010”和”011”则是理想的.两者不同的是前者地址线没有公共部分,这样的设计无法用when语句对条件进行直接的控制,如果置之不理,由于列举不全,在逻辑综合时,电路会利用器件的乘积项和查找表的资源形成一个Latch, La tch不仅会把电路的时序变得复杂,而且电路存在潜在的危险性.虽然when语句后的条件不能够对条件进行直接的控制,但是可以使用枚举法一一把用到的地址线罗列出来,表示只有在这样的地址线的情况下才会用到数据总线,否则其他状态对数据总线送高阻,表示不占用数据总线.总而言之,双向信号是程序设计中尤其重要的基础,设计者在设计程序的时候,要尤其注意,何时会占用数据总线,何时不占用数据总线。
Verilog中inout端口的使用方法
Verilog中inout端口的使用方法Verilog中inout端口的使用方法(本文中所有Verilog描述仅为展示inout端口的用法,实际描述则需要更丰富的功能描述)Inout端口的使用在芯片中为了管脚复用,很多管脚都是双向的,既可以输入也可以输出。
在Verilog中即为inout型端口。
Inout端口的实现是使用三态门,如FPGA中的管脚复用部分:三态门的第三个状态是高阻态Z。
在实际电路中高阻态意味着响应的管脚悬空、断开。
当三态门的控制信号为真时,三态门导通;控制信号为假时,三态门的输出端是高阻态。
Verilog中的inout端口被综合为如下形式:Inout端口是一个很容易出错的地方,理解inout端口模型必须要抓住三点:inout端口不可能独立存在;作为输入必须有reg型缓冲(一个inout两个控制信号);相连的两个inout端口由一对信号交错控制;下面一一分析。
inout端口不可能独立存在:分析inout的端口特性,对于一个模块来说,inout端口既可以当做输入,又可以当做输出,那么,与inout端口相连的另一模块是什么情形呢?显然,另一模块也应该是inout端口,inout 端口不可能独立存在。
但是在实际编写Verilog代码的过程中,却常常忽略这一点,而仅仅是另一模块的一条输出线和一条输入线同时连接到inout端口上,乍看起来符合逻辑,实则不然。
以下图为例:图中的存储器Memory用RAM实现,无论CPU还是RAM都只有一组数据总线,而图中输入给Memory的有WriteData,从Memory输出的有MemData,这两组其实是一组数据总线,而实现此管脚复用功能的就是管脚复用。
在用Verilog描述的过程中,只考虑CPU的数据通路结构时,就容易忽略它的双向端口的具体实现,并非如图中一般,简简单单的与RAM 模块的inout端口相连。
所以,一定要注意到inout端口不能独立存在,用Verilog描述上图中的CPU模块时也要描述一个inout端口及相关逻辑。
