




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、verilog 中双向端口 in out的使用的心得见许多问这个问题的,总结一下,希望能对大家有点用处,如果有不对的地方,欢迎指出芯片外部引脚很多都使用in out类型的,为的是节省管腿。一般信号线用做总线等双向数据传输的时候就要用到INOUT类型了。就是一个端口同时做输入和输出。in out在具体实现上一般用三态门来实现。三态门的第三个状态就是高阻Z o当in out端口不输出时,将三态门 置高阻。这样信号就不会因为两端同时输出而出错了,更详细的内容可以搜索一下三态门tri-state 的资料.1 使用in out类型数据,可以用如下写法:inout datano ut;in put dat
2、a_i n;reg data_reg ;/ data_inout 的映象寄存器reg lin k_data;assign data_inout=link_data?data_reg:1 bz; link_data 控制三态门/对于data_reg,可以通过组合逻辑或者时序逻辑根据 data_in对其赋值.通过控制link_data 的高低电平,从而设置datanout是输出数据还是处于高阻态,如果处于高阻态,则此时当作输 入端口使用.link_data 可以通过相关电路来控制.2编写测试模块时,对于in out类型的端口 ,需要定义成wire类型变量,而其它输入端口都定义 成reg类型,这两者
3、是有区别的.当上面例子中的datanout用作输入时,需要赋值给datanout,其余情况可以断开.此时可以用 assign 语句实现:assign data_inout=link?data_in_t:1 bz;其中的 link ,data_in_t是reg类型变量,在测试模块中赋值.另外,可以设置一个输出端口观察 data_inout用作输出的情况:Wire data_out;else , in RTLinout use in top module(PAD)dont use ino ut(tri) in sub module也就是说,在内部模块最好不要出现in out,如果确实需要,那么用两
4、个 port实现,到顶层的时候再用三态实现。理由是:在非顶层模块用双向口的话,该双向口必然有它的上层跟它相连。 既然是双向口,贝U上层至少有一个输入口和一个输出口联到该双向口上,贝U发生两个内部输出 单元连接到一起的情况出现,这样在综合时往往会出错。芯片外部引脚很多都使用in out类型的,为的是节省管腿。一般信号线用做总线等双向数据 传输的时候就要用到INOUT类型了。就是一个端口同时做输入和输出。in out在具体实现上一般用三态门来实现。三态门的第三个状态就是高阻Z o当in out端口不输出时,将三态门置高 阻。这样信号就不会因为两端同时输出而出错了,更详细的内容可以搜索一下三态门tr
5、i-state的资料1使用inout类型数据,可以用如下写法:inout datano ut;in put data_i n;reg data_reg;/datanout 的映象寄存器reg lin k_data;assign data_inout=link_data?data_reg:1 /bzk_data 控制三态门对于data_reg,可以通过组合逻辑或者时序逻辑根据 datan对其赋值.通过控制link_data 的高低电平,从而设置data_inout是输出数据还是处于高阻态,如果处于高阻态,则此时当作输入 端口使用.link_data可以通过相关电路来控制.2编写测试模块时,对于i
6、n out类型的端口,需要定义成wire类型变量,而其它输入端口都定 义成reg类型,这两者是有区别的.当上面例子中的data_inout用作输入时,需要赋值给data_inout,其余情况可以断开.此时可 以用 assign 语句实现:assign data_inout=link?data_in_t:1其中的 link ,data_in_t 是 reg 类型变量,在测试模块中赋值.一一一一一另外,可以设置一个输出端口观察 data_inout用作输出的情况:Wire data_out;Assign data_out_t=(!link)?data_inout:1 bz;else, in RTL
7、inout use in top module(PAD)dont use ino ut(tri) in sub module也就是说,在内部模块最好不要出现in out,如果确实需要,那么用两个port实现,到顶层 的时候再用三态实现。理由是:在非顶层模块用双向口的话,该双向口必然有它的上层跟它相 连。既然是双向口,则上层至少有一个输入口和一个输出口联到该双向口上,则发生两个内部 输出单元连接到一起的情况出现,这样在综合时往往会出错。对双向口,我们可以将其理解为 2个分量:一个输入分量,一个输出分量。另外还需要一 个控制信号控制输出分量何时输出。此时,我们就可以很容易地对双向端口建模。例子:C
8、ODE:module dual_port (inout_pin,);inout inout_pin;wire inout_pin;wire in put_of_i no ut;wire output_ of_ino ut;wire out_e n;assig n in put_ of_inout = inout_pin;assig n inout_pin = out_e n ? output_ of_inout :高阻;en dmodule可见,此时input_of_inout和output_of_inout就可以当作普通信号使用了。在仿真的时候,需要注意双向口的处理。如果是直接与另外一个模块
9、的双向口连接,那么 只要保证一个模块在输出的时候,另外一个模块没有输出(处于高阻态)就可以了。如果是在ModelSim中作为单独的模块仿真,那么在模块输出的时候,不能使用force命令 将其设为高阻态,而是使用release命令将总线释放掉很多初学者在写testbe nch进行仿真和验证的时候,被in out双向口难住了。仿真器老是提 示错误不能进行。下面是我个人对in out端口写testbe nch仿真的一些总结,并举例进行说明。 在这里先要说明一下in out 口在testbe nch中要定义为wire型变量。先假设有一源代码为:module xx(data_i no ut ,);ino
10、ut datano ut;assig n data_i no ut=(! li nk)?datareg:1bz;en dmodule方法一:使用相反控制信号inout 口,等于两个模块之间用inout双向口互连。这种方法要 注意assign语句只能放在initial和always块内。module test();wire data_i no ut;reg data_reg;reg link;in itial beg inendassig n data_i no ut=li nk?data_reg:1bz;en dmodule方法二:使用force和release语句,但这种方法不能准确反映双向
11、端口的信号变化,但这 种方法可以反在块内。module test();wire data_i no ut;reg data_reg;reg link;#xx;延时force data_i nout=1bx;/ 强制作为输入端口#xx;release data_i no ut;/ 释放输入端口en dmodule很多读者反映仿真双向端口的时候遇到困难,这里介绍一下双向端口的仿真方法。一个典 型的双向端口如图1所示。其中inner_port与芯片内部其他逻辑相连,outer_port为芯片外部管脚,out_en用于控制 双向端口的方向,out_en为1时,端口为输出方向,out_en为0时,端口为
12、输入方向。用Verilog语言描述如下:module bidirectio n_i o(i nn er_port,out_e n,o uter_port);in put out_e n;ino ut7:0 inn er_port;ino ut7:0 outer_port;assig n outer_port=(out_e n=1) ?inn er_port:8hzz;assig n inn er_port=(out_e n=0 )?outer_port:8hzz;en dmodule用VHDL语言描述双向端口如下:library ieee;use IEEE.STD_LOGIC_1164.ALL
13、;entity bidirection_io isport ( inn er_port : inout stdo gic_vector(7 dow nto 0);out_en : in std_logic;outer_port : inout stdo gic_vector(7 dow nto 0);end bidirectiono;architecture behavioral of bidirect ion_io isbegi nouter_portZ);inn er_portZ);end behavioral;仿真时需要验证双向端口能正确输出数据,以及正确读入数据,因此需要驱动out_e
14、n端口,当out_en端口为1时,testbench驱动inner_port端口,然后检查 outer_port端口输出的数据 是否正确;当 out_en端口为0时,testbench驱动outer_port端口,然后检查inner_port端口 读入的数据是否正确。由于inner_port和outer_port端口都是双向端口(在 VHDL和Verilog 语言中都用inout定义),因此驱动方法与单向端口有所不同。验证该双向端口的testbench结构如图2所示。这是一个self-checking testbench,可以自动检查仿真结果是否正确,并在 Modelsim控制 台上打印出提示
15、信息。图中 Monitor完成信号采样、结果自动比较的功能。testbench的工作过程为1) out_en=1时,双向端口处于输出状态,testbench给inner_port_tb_reg 信号赋值,然 后读取outer_port_tb_wire的值,如果两者一致,双向端口工作正常。2) out_en=0时,双向端口处于输如状态,testbench给outer_port_tb_reg 信号赋值,然 后读取inner_port_tb_wire的值,如果两者一致,双向端口工作正常。用Verilog代码编写的testbench如下,其中使用了自动结果比较,随机化激励产生等技术。timescale
16、 1n s/10psmodule tb();reg7:0 inn er_port_tb_reg;wire7:0 inn er_port_tb_wire;reg7:0 outer_port_tb_reg;wire7:0 outer_port_tb_wire;reg out_e n_tb;in teger i;in itialbegi nout_e n_tb=0;inn er_port_tb_reg=0;outer_port_tb_reg=0;i=0;repeat(20)begi n#50i=$ra ndom;out_e n_tb=i0; /ran domize out_en_tbinn er_p
17、ort_tb_reg=$ra ndom; /ran domize dataouter_port_tb_reg=$ra ndom;endend/* drive the ports conn ect ing to bidirctionoassig n inn er_port_tb_wire=(out_e n_tb=1)?i nn er_port_tb_reg:8hz z; assig n outer_port_tb_wire=(o ut_en _tb=0)?outer_port_tb_reg:8hzz; /instatiate the bidirction_io modulebidirection
18、o bidirectio no_in st(.i nn er_port(i nn er_port_tb_wire),.out_en (out_e n_tb).outer_port(outer_port_tb_wire);mon itor *always(out_e n_tb,i nn er_port_tb_wire,outer_port_tb_wire) begi n#1;if(outer_port_tb_wire=inn er_port_tb_wire)begi n$display(n * time=%t *,$time);$display(OK! out_e n=%d,out_en_tb)
19、;$display(OK! outer_port_tb_wire=%d,i nn er_port_tb_wire=%d, outer_port_tb_wire,i nn er_port_tb_wire);endelsebegi n$display(n * time=%t *,$time);$display(ERROR! out_e n=%d,out_e n_tb);$display(ERROR! outer_port_tb_wire != inn er_port_tb_wire);$display(ERROR! outer_port_tb_wire=%d, i nn er_port_tb_wi
20、re=%d, outer_port_tb_wire,i nn er_port_tb_wire);endenden dmodule在写组合逻辑电路的代码时,我发现书上例子大都用的=;而在写时序逻辑电路代码时,我 发现书上例子大都用的=。之前就知道在Verilog HDL中阻塞赋值=和非阻塞赋值= 有着很大的不同,但一直没有搞清楚究竟有什么不同,现在来慢慢的琢磨它。对于我这样的初学者而言,首先要掌握可综合风格的Verilog模块编程的8个原则,并且牢记,才能在综合布局布线的仿真中避免出现竞争冒险现象。(1) 时序电路建模时,用非阻塞赋值。(2) 锁存器电路建模时,用非阻塞赋值。(3) 用alway
21、s块建立组合逻辑模型时,用阻塞赋值。(4) 在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。(5) 在同一个always块中不要既用非阻塞赋值又用阻塞赋值。(6) 不要在一个以上的always块中为同一个变量赋值。(7) 用$strobe系统任务来显示用非阻塞赋值的变量值。(8) 在赋值时不要使用#0延时。这样做的目的是为了使 综合前仿真和综合后仿真一致。在很多时候,用=或者是=实 际上对应的是不同的硬件电路,这点一定要十分清楚。阻塞赋值(=):我们先做下面定义: RHS 赋值等号右边的表达式, LHS 赋值等号左边的表达式。 在串 行语句块中 ,阻塞赋值语句按照它们在块中的排
22、列顺序依次执行,即前一条语句没有完成赋值 之前,后面的语句不可能被执行,换言之,后面的语句被阻塞了。阻塞赋值的执行可以认为只 有一个步骤的操作,即计算 RHS 并更新 LHS ,此时不允许有来自任何其他 Verilog 语句的干扰。 所谓阻塞的概念是指在同一个 always 块中,其后面的赋值语句从概念上是在前一条赋值语句 结束后开始赋值的。有句话我一直没读懂 :从理论上讲,它与后面的赋值语句只有概念上的先 后,而无实质上的延时。例如:beginB = A;C = B + 1 ;end首先第一条语句执行,将A的值赋给B,接着执行第二条语句,将B+1(即A加1),并赋给 C 。也就是说 C =
23、A + 1。非阻塞赋值 (=):非阻塞语句的执行过程是:首先计算语句块内部 所有右边表达式 (RHS) 的值,然后完成对 左边寄存器变量的赋值操作,例如,下面两条非阻塞赋值语句的执行过程是:先计算右边表达 式的值并 暂存在一个暂存器中 , A 的值被保存在一个寄存器中,而 B+1 的值被保存在另一个寄 存器中,在 begin 和 end 之间所有语句的右边表达式都被计算并存储完后,对左边的寄存器变 量的赋值才会进行。这样 C得到的是B的原始值而不是A加一。beginB = A ;C ENACLRCLRPRED ENAoQAregDoQASoQA1 Bmodule blocking(2 clkf iD,3 OQB4 );5 input elk,iD;6 output oQA,oQB;7 reg oQA,oQB;81 3module non_blocking(2 clkf iD73 OQA,OQ
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 智能制造系统合作开发合同(2篇)
- 嘴唇干裂脱皮的临床护理
- 新质生产力的质态
- 《家长会班主任》课件
- 《建筑行业》课件
- 2025届高三化学化学反应机理(解析版)
- 2025企业合作合同纠纷预防策略全解析
- 2025大学生租房签订租房合同应该注意什么
- 社旗县九年级试卷及答案
- 陕西初一地理试卷及答案
- 每10立方米砼模板含量参考表(山东2003消耗量定额)
- 礼仪评分标准
- 南昊网上阅卷系统用户手册
- 道路交通事故责任认定课件
- NB∕T 10731-2021 煤矿井下防水密闭墙设计施工及验收规范
- DB37-T 3658-2019地质灾害治理工程施工技术规范
- 中国军事发展简述课件
- 中华人民共和国建设部城市地下管线探测技术规程
- 碧桂园物业案场私宴接待操作规程
- 数学中考复习:一次函数与反比例函数综合课件
- 胰岛素分类及使用方法PPT课件
评论
0/150
提交评论