FPGA的设计艺术(20)高阻态的正反两用?

前言

关于高阻态,我们常见到的场景有两处,一种出现在仿真中,一种是逻辑设计中,它常常是无意乱出,还或者是有意而为之。

下面对这几种情况进行简单梳理。

高阻态回顾

我们在上一篇文章中的数据类型中介绍了包括高阻态的一系列数据类型,即线网型和变量型:

线网类型表示电路元件之间的连接,我们常用其中的一种wire,这足以创建所有线网类型的设计。

变量类型表示可以存储值得数据类型,我们常用的变量类型是reg,我们常用reg对寄存器或触发器进行建模,它在always块中进行赋值。另外,不能讲输入端口定义为reg型,输入应该是线网型,这很容易,因为现实中一个电路元件的输入来自于另一方的线网。

对这些数据类型进行赋值,使用到了逻辑值,有4种逻辑值:

0 logic ‘0’ or false condition 1 logic ‘1’ or true condition z high impedance state (used for tri-state buffer) x don’t care or unknown value

其中z就是高阻态。

例如:

reg [4:0] a = 5’bz //z is high impedance reg [4:0] a = 5’bx01 //z is high impedance

高阻态的应用

我们常见到这样的结构,使用inout端口类型定义一个变量,做如下处理:

module test ( inout bidirPin, input toPin, input direction, output fromPin ); assign bidirPin = direction ? 1bz : toPin; assign fromPin = bidirPin;

如下这条语句中就出现了高阻态的赋值:

assign bidirPin = direction ? 1bz : toPin;

这通常是什么含义呢?

可以这么解释:

当direction信号为低电平时,bidirPin则为输出,并且信号toPin连接至引脚。当direction处于高电平时,则bidirPin成为输入。在所有情况下,fromPin表示引脚的当前数据。

这种结构要求FPGA具有双向(三态)I / O缓冲器。许多(大多数?)都支持,但并非所有设备上的所有引脚都支持。

如果要在内部使用相同的结构(例如,您具有上述模块的多个实例,并将所有inout引脚连接到单根电线),那么显然可以推断出的内容必须与I / O引脚不同。大多数(如果不是全部)FPGA没有内部三态布线网络。换句话说,High-Z是不可能的。

然而,该逻辑是可综合的。发生的情况是,综合工具查看inout连接到同一网络的所有信号,并简单地推断出多路复用器逻辑。这实际上表示同一件事,但是需要附加仲裁逻辑。通常,使用多路复用器上的优先级编码器可以解决任何可能的总线争用,从而一次只有一个端口可以传送其信号。

如果您要设计与微控制器类似的架构,这可能是将许多外设(例如SPI,UART,RAM等)连接到共享数据总线的一种非常有用的方法。使用高Z值可使综合器处理任何仲裁逻辑。由于您必须遵循在任何RTL网表查看器中添加的其他逻辑,因此这会使调试更加困难,但这是一种完全有效的处理方式。

在仿真中,High-Z可以是可接受的状态(例如,如果您正在观察三态I / O引脚),也可以是主要问题的指示器(例如,如果您使用了generate循环而丢失了数据总线中的某个位)会变为高阻(Z)。

高Z值可以帮助您确定由于诸如生成循环之类的信号未连接而导致的问题,或者,如果您误说了变量名,则导致两个事物无法正确连接。如果您希望仿真中的信号能够变为High-Z,则没有问题。如果您不期望这样做,则需要对原因进行进一步调查。

内部High-Z总线(推断出仲裁的总线)可能会带来进一步的仿真麻烦。例如,如果仿真综合后网表,则可能永远不会在总线上看到High-Z,因为已经推断出仲裁逻辑。如果从源代码级别进行仿真,则可能会在总线上看到High-Z,因为仿真器非常乐意允许High-Z,因为它不知道综合工具将要推断出什么,因此仿真器会坚持下去完全符合您在代码中编写的内容。

设计示例

我们在使用逻辑设计RAM时可能会使用到inout,并使用到z,即高阻态。

例如:单端口RAM的同步读写逻辑:

`timescale 1ns / 1ps // Engineer: Reborn Lee // Module Name: single_port_syn_ram module single_port_syn_ram#( parameter ADDR_WIDTH = 4, parameter DATA_WIDTH = 16, parameter DEPTH = 2**ADDR_WIDTH )( input i_clk, input [ADDR_WIDTH – 1 : 0] addr, inout [DATA_WIDTH – 1 : 0] data, input cs, input wr, input oe ); reg [DATA_WIDTH – 1 : 0] mem[0 : DEPTH – 1]; reg [DATA_WIDTH – 1 : 0] mid_data; // write part always@(posedge i_clk) begin if(cs&wr) begin mem[addr] <= data; end end // read part always@(posedge i_clk) begin if(cs & !wr) begin mid_data <= mem[addr]; end end assign data = (cs & oe & !wr)? mid_data: hz; endmodule
<

对于:

assign data = (cs & oe & !wr)? mid_data: hz;

表达的意义是条件:cs & oe & !wr满足时(ram读),data作为输出端口,而不满足(ram写),data作为输入端口,将数据写入RAM。 总结一下:

assign x = a? b: hz;

当a有效时,x作为输出。 当a无效时,x作为输入值,在逻辑中将其设置为高阻态。

仿真中的高阻态

如果你经常仿真你会发现,高阻态时长会出现在仿真波形中,有两种情况,一种是它本身就应该是高阻态值,另一种情况是你弄错了。 例如,我在Xilinx论坛中,看到一个十分搞笑的错误,虽然搞笑,但能说明问题:

High Impedance Output in Simulation of A Simple Verilog Code

链接中贴出一段代码:

`timescale 1 ns / 1 ps module invT ( input wire inv_in, output wire inv_out ); reg tmp; always @(*) begin tmp <= !inv_in; end assign inv_output = tmp; endmodule

说自己仅仅实现一个反相器,对其进行仿真,给出了输入值,但是输出值一直为高阻态,见鬼了?

提问者很纳闷呀,一个反相器而已,仿真也出现高阻态,简直是对学习热情的打击,这就像是突然想学习一门编程语言,但是决定了几天,一个编码环境都没有搭建成功,这多令人灰心呀。

为什么说这能说明问题?

可以看看输出一致为高阻态的原因,很显然,旁观者清,你的输出根本就没有接入任何输入信号呀,是悬空的,当然是高阻态!

这说明了,输出未有输入值,会出现高阻态的情况,这可能是你的有意而为之,也可能是你的失手,这就为查找bug提供了思路。

当然,还有其他情况,当你遇到了,记得留意分析。

京云律所-娄底站 京云律所-朔州站 京云律所-枣庄站 京云律所-仁怀站 京云律所-罗定站 京云律所-扬中站 京云律所-甘南站 京云律所-荣成站 京云律所-原平站 京云律所-和龙站 京云律所-江门站 京云律所-会理站 京云律所-涟源站 京云律所-临汾站 京云律所-界首站 京云律所-阿里站 京云律所-中卫站 京云律所-个旧站 京云律所-奎屯站 京云律所-北安站 京云律所-漳州站 京云律所-银川站 京云律所-鞍山站 京云律所-阜新站 京云律所-北京站 京云律所-庐山站 京云律所-吐鲁番站 京云律所-弥勒站 京云律所-霍尔果斯站 京云律所-洮南站 京云律所-北海站 京云律所-宁安站 京云律所-柳州站 京云律所-万源站 京云律所-昆山站 京云律所-昌都站 京云律所-阿拉善站 京云律所-武冈站 京云律所-瓦房店站 京云律所-怀化站 京云律所-三亚站 京云律所-瑞安站 京云律所-枝江站 京云律所-湘潭站 京云律所-滕州站 京云律所-钦州站 京云律所-华阴站 京云律所-巴彦淖尔站 京云律所-嫩江站 京云律所-侯马站 京云律所-河池站 京云律所-绥化站 京云律所-乳山站 京云律所-南京站 京云律所-介休站 京云律所-绵竹站 京云律所-萍乡站 京云律所-海北站 京云律所-京山站 京云律所-四会站 京云律所-巩义站 京云律所-韩城站 京云律所-通化站 京云律所-兴义站 京云律所-六安站 京云律所-日喀则站 京云律所-额尔古纳站 京云律所-武安站 京云律所-邹城站 京云律所-肇庆站 京云律所-慈溪站 京云律所-兰溪站 京云律所-喀什站 京云律所-齐齐哈尔站 京云律所-玉林站 京云律所-焦作站 京云律所-讷河站 京云律所-茂名站 京云律所-安庆站 京云律所-禄丰站 京云律所-宜宾站 京云律所-张掖站 京云律所-霍林郭勒站 京云律所-昌邑站 京云律所-老河口站 京云律所-张家界站 京云律所-荔浦站 京云律所-黄南站 京云律所-利川站 京云律所-林州站 京云律所-巴中站 京云律所-信阳站 京云律所-周口站 京云律所-梅州站 京云律所-库车站 京云律所-宣威站 京云律所-自贡站 京云律所-遵义站 京云律所-泸水站 京云律所-宁波站

免责声明:文章内容来自互联网,本站不对其真实性负责,也不承担任何法律责任,如有侵权等情况,请与本站联系删除。
转载请注明出处:FPGA的设计艺术(20)高阻态的正反两用? https://www.yhzz.com.cn/a/12826.html

FPGA的设计艺术(21)Verilog中如何对组合逻辑进行建模?
上一篇 2023-05-11 14:04:51
FPGA的设计艺术(19)触发器以及线网的建模工具之Verilog中的两类数据类型
下一篇 2023-05-11 14:07:29

相关推荐

联系云恒

在线留言: 我要留言
客服热线:400-600-0310
工作时间:周一至周六,08:30-17:30,节假日休息。