博文目录

  • 写在前面
  • 正文
    • 全双工与半双工
    • FPGA和ASIC中的三态缓冲器
    • 如何在VHDL和Verilog中推断出三态缓冲区
  • 参考资料
  • 交个朋友

写在前面

下面用举例子的方式引出三态门,内容过长,大家可直接跳过,进入正文!

三态门在FPGA以及ASIC设计中十分常用,随便举一个例子,在RAM的设计中(无论是同步读写RAM还是异步读写RAM设计),我们常将数据总线设计成inout类型,下面是一个设计程序实例:

`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 partalways@(posedge i_clk) beginif(cs&wr) beginmem[addr] <= data;endend// read partalways@(posedge i_clk) beginif(cs & !wr) beginmid_data <= mem[addr];endendassign data = (cs & oe & !wr)? mid_data: 'hz;endmodule

在读数据的时候,我们需要设计一个三态缓冲器,如下:

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

读使能有效时,我们将从缓冲区读出的数据放到mid_data中,之后通过一个三态门来将数据mid_data输出到三态总线上,此三态门的使能条件为读使能!
这条语句在综合工具中就会被推断为一个三态缓冲器!
在读使能有效时,将读取数据放在总线上,否则呈现为高阻态,避免占用此数据总线。

在testbench文件中,我们同样需要作出类似的操作,如下针对上面的ram的测试文件:

`timescale 1ns / 1ps
///
// Engineer: Reborn Lee
// Module Name: ram_tb
//
module ram_tb();parameter ADDR_WIDTH = 4;parameter DATA_WIDTH = 16;parameter DEPTH = 2**ADDR_WIDTH;reg i_clk;reg [ADDR_WIDTH - 1 : 0] addr;wire [DATA_WIDTH - 1 : 0] data;reg cs;reg wr;reg oe;reg [DATA_WIDTH-1:0] tb_data;//generate system clockinitial begini_clk = 0;forever begin# 5 i_clk = ~i_clk;endendassign data = !oe ? tb_data : 'hz;initial begin{cs, wr, addr, tb_data, oe} = 0;repeat (2) @ (posedge i_clk);//write testfor (integer i = 0; i < 2**ADDR_WIDTH; i= i+1) beginrepeat (1) @(negedge i_clk) addr = i; wr = 1; cs =1; oe = 0; tb_data = $random;end//read testrepeat (2) @ (posedge i_clk);for (integer i = 0; i < 2**ADDR_WIDTH; i= i+1) beginrepeat (1) @(posedge i_clk) addr = i; wr = 0; cs = 1; oe = 1;end#20 $finish;endsingle_port_syn_ram #(.ADDR_WIDTH(ADDR_WIDTH),.DATA_WIDTH(DATA_WIDTH),.DEPTH(DEPTH)) inst_single_port_syn_ram (.i_clk (i_clk),.addr  (addr),.data  (data),.cs    (cs),.wr    (wr),.oe    (oe));endmodule

由于inout端口在测试文件中必须设置为wire类型,因此,我们在设计写数据时,需要定义一个中间reg类型变量,这个变量在写使能有效时候输入给写数据端口,如下:

 assign data = !oe ? tb_data : 'hz;

否则,也就是写使能无效时,就为高阻态,不占用数据总线!
注:上面用了oe无效代替写使能有效,有点不太严谨,但也没问题 ,仅供各位参考!

  • 个人微信公众号: FPGA LAB
  • 个人博客首页
  • 注:学习交流使用!

正文

三态缓冲器可以处于以下三种状态之一:逻辑0,逻辑1和Z(高阻抗)。它们的使用允许多个驱动程序共享一条公共线路。这使得它们在半双工通信中特别有用。让我们首先讨论半双工和全双工通信之间的区别。

全双工与半双工

全双工和半双工的区别可以使用下面的两幅图来说明:

在全双工系统中,有两个路径用于在两个芯片之间发送数据。从芯片1到芯片2有一条专用路径,从芯片2到芯片1有一条专用路径。在半双工系统中,只有一条路径可以在两个芯片之间发送数据。因此,这两个芯片必须在要传输的对象上达成共识。如果两者尝试同时传输,则线路上将发生冲突,并且数据将丢失。

在以上两个图中,三角形是您的缓冲区。注意,在半双工框图中,存在信号Tx En。这是控制三态发送缓冲器的信号。在全双工块图中,此信号不是必需的,因为两个发送器都可以在100%的时间内打开,而不会在线路上发生冲突。

FPGA和ASIC中的三态缓冲器

如下为三态缓冲器的真值表:

Tx Data Tx Enable Output
0 1 0
1 1 1
X 0 Z (high impedance)

请注意,如果两个Tx En同时都为高,则两个发送器都将在驱动并且线路上将发生冲突。 使用半双工三态缓冲器时,至关重要的是,共享线路的模块必须制定出一种避免数据冲突的通信方案。

如何在VHDL和Verilog中推断出三态缓冲区

综合工具可以推断出三态缓冲器。这是在VHDL中推断三态缓冲区的方法。信号io_data 在实体的端口映射部分中声明为inout。在VHDL中,“ Z”为高阻抗。

inout io_data : std_logic; --port declaration of bidirectional data lineio_data   <= w_Tx_Data when w_Tx_En = '1' else 'Z';
w_Rx_Data <= io_data;

这是在Verilog中推断三态缓冲区的方法。信号io_data 在模块的端口声明部分中声明为inout。在Verilog中,1’bZ是高阻抗。

inout io_data; //port declaration of bidirectional data lineassign io_data = Tx_En ? Tx_Data : 1'bZ;
assign Rx_Data = io_data;

三态缓冲器常用于半双工UART和I2C接口等电路中。它们是数字设计师了解的非常有用的工具。您应该知道如何在VHDL和Verilog中推断三态缓冲区。


参考资料

  • 参考资料1
  • 参考资料2
  • 参考资料3

交个朋友

  • 个人微信公众号:FPGA LAB

  • 知乎:李锐博恩

  • FPGA/IC技术交流2020

FPGA基础知识极简教程(8)详解三态缓冲器相关推荐

  1. FPGA基础知识极简教程(7)详解亚稳态与跨时钟域传输

    博文目录 写在前面 正文 FPGA或ASIC中的传播延迟 建立和保持时间是什么? 建立和保持时间与传播延迟和时钟频率有何关系? 如果违反建立和保持时间会发生什么? FPGA中的亚稳定是什么? 亚稳态何 ...

  2. FPGA基础知识极简教程(10)二进制到BCD转换算法

    文章目录 写在前面 正文 快速认识 实现方式一 实现方式二 写在最后 写在前面 FPGA基础知识极简教程(9)讲到了七段数码管的显示Verilog设计,我们都知道,要在数码管上显示的数字,使用BCD编 ...

  3. FPGA基础知识极简教程(4)从FIFO设计讲起之异步FIFO篇

    博文目录 写在前面 正文 同步FIFO回顾 $clog2()系统函数使用 综合属性控制资源使用 异步FIFO设计 FIFO用途回顾 异步FIFO原理回顾 异步FIFO设计 异步FIFO仿真 参考资料 ...

  4. FPGA基础知识极简教程(9)七段数码管显示的Verilog简单设计

    博文目录 写在前面 正文 七段数码管原理 七段数码管译码表 单个七段数码管显示verilog设计 多个数码管动态扫描显示 参考资料 交个朋友 写在前面 作为FPGA的基础知识教程怎么能少得了这个简单的 ...

  5. FPGA基础知识极简教程(6)UART通信与移位寄存器的应用

    博文目录 写在前面 正文 关于UART的介绍 UART通信过程 UART.RS232以及TTL之间的关系 UART的使用场合 有关UART的总结 调试UART的技巧 UART的Verilog实现 波特 ...

  6. FPGA基础知识极简教程(1)从布尔代数到触发器

    博文目录 写在前面 正文 初学者数字设计 什么是FPGA? 什么是ASIC? 数字设计师如何使用布尔代数? 使用查找表(LUT)在FPGA内部执行布尔代数 触发器如何在FPGA中工作? 参考资料 交个 ...

  7. FPGA基础知识极简教程(3)从FIFO设计讲起之同步FIFO篇

    博文目录 写在前面 正文 FPGA/ASIC中的FIFO 同步FIFO的设计 参考资料 交个朋友 写在前面 个人博客首页 注:学习交流使用! 正文 FPGA/ASIC中的FIFO FIFO缓冲区如何用 ...

  8. FPGA基础知识极简教程(5)什么是锁存器以及如何在FPGA开发中避免生成锁存器?

    博文目录 写在前面 正文 什么是D锁存器? 锁存器是如何生成的? 如何避免生成锁存器? 参考资料 交个朋友 写在前面 个人微信公众号: FPGA LAB 个人博客首页 注:学习交流使用! 本文我们将讨 ...

  9. FPGA基础知识极简教程(2)抛却软件思维去设计硬件电路

    博文目录 写在前面 正文 可综合以及不可综合的代码 每个软件程序员需要了解的有关硬件设计的内容 参考资料 交个朋友 写在前面 相关博文 个人博客首页 注:学习交流使用! 学过一门或多门软件语言的数字设 ...

最新文章

  1. Hanlp分词实例:Java实现TFIDF算法
  2. CORS跨域实现思路及相关解决方案
  3. linux设备驱动归纳总结(六):2.分享中断号【转】
  4. MySQL语法规范介绍
  5. ubuntu创建新用户并设置sudo权限
  6. 关于“就地颠倒句子里的词”面试题
  7. react实现的点击拖拽元素效果
  8. 计算机系统-电路设计05-RS触发器的内部电路实现
  9. 首批 5G 手机到位;来电显示暗藏黑色利益链;印度下架抖音国际版 | 极客头条...
  10. python画五子棋棋盘_python 五子棋-文字版(上)
  11. 华为云NP考试题库_华为云服务考试 华为云hcip认证试题
  12. 多地“摇号购房” 开发商迎来了良机?
  13. linux cadaver 命令,(个人学习Linux经历)文本命令
  14. PostgreSQL引入的JSONB解释
  15. android studio模拟手机黑屏,Android Studio 模拟器启动问题——黑屏 死机 解决方法...
  16. 【labview】图表时间轴(数据+时间戳) +源程序
  17. 世上只有一种英雄主义,就是在认清生活真相之后依然热爱生活。
  18. 外呼系统需要服务器么,外呼
  19. C# string格式化(小数点保留/进制转换等)
  20. ERP项目过度开发,等同上了“贼船”!

热门文章

  1. pdo mysql防注入_Php中用PDO查询Mysql来避免SQL注入风险的方法
  2. 判断表格中的一列是否有重复项
  3. rust大油井频率怎么用_数据量大怎么搞?当然是用这个了!
  4. arpr选定的文件非rar压缩包_python解压压缩包
  5. 图解法求最优解的例题_【第四章 最优化理论】4.2 带约束最优化
  6. 如何matlab导入邻接矩阵,“excel如何做矩阵“matlab中读取excle中的邻接矩阵
  7. java curator_[java,zk]在 linux 上快速搭建 zookeeper curator 开发环境
  8. 铅笔线的阻抗有多大?
  9. 智能车竞赛技术报告 | 节能信标组 - 华南理工大学 - 华工雨花队
  10. 2021年春季学期-信号与系统-第十三次作业参考答案-第七小题