前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >FPGA基础知识极简教程(8)详解三态缓冲器

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

作者头像
Reborn Lee
发布2020-06-28 16:42:46
9610
发布2020-06-28 16:42:46
举报
文章被收录于专栏:用户7494468的专栏
  • 写在前面
  • 正文
    • 全双工与半双工
    • FPGA和ASIC中的三态缓冲器
    • 如何在VHDL和Verilog中推断出三态缓冲区
  • 参考资料
  • 交个朋友

写在前面

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

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

代码语言:javascript
复制
`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

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

代码语言:javascript
复制
assign data = (cs & oe & !wr)? mid_data: 'hz;

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

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

代码语言:javascript
复制
`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 clock
 initial begin
  i_clk = 0;
  forever begin
   # 5 i_clk = ~i_clk;
  end
 end

 assign data = !oe ? tb_data : 'hz;

 initial begin
    {cs, wr, addr, tb_data, oe} = 0;
 
    repeat (2) @ (posedge i_clk);

    //write test
 
    for (integer i = 0; i < 2**ADDR_WIDTH; i= i+1) begin
      repeat (1) @(negedge i_clk) addr = i; wr = 1; cs =1; oe = 0; tb_data = $random;
    end

    //read test
    repeat (2) @ (posedge i_clk);
 
    for (integer i = 0; i < 2**ADDR_WIDTH; i= i+1) begin
      repeat (1) @(posedge i_clk) addr = i; wr = 0; cs = 1; oe = 1;
    end
 
    #20 $finish;
  end

 single_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类型变量,这个变量在写使能有效时候输入给写数据端口,如下:

代码语言:javascript
复制
 assign data = !oe ? tb_data : 'hz;

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

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

正文

三态缓冲器可以处于以下三种状态之一:逻辑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”为高阻抗。

代码语言:javascript
复制
inout io_data : std_logic; --port declaration of bidirectional data line
 
io_data   <= w_Tx_Data when w_Tx_En = '1' else 'Z';
w_Rx_Data <= io_data;

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

代码语言:javascript
复制
inout io_data; //port declaration of bidirectional data line
 
assign io_data = Tx_En ? Tx_Data : 1'bZ;
assign Rx_Data = io_data;

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


参考资料

  • 参考资料1[2]
  • 参考资料2[3]
  • 参考资料3[4]

交个朋友

  • 个人微信公众号:FPGA LAB
  • 知乎:李锐博恩
  • FPGA/IC技术交流2020[5]

参考资料

[1]

个人博客首页: https://blog.csdn.net/Reborn_Lee

[2]

参考资料1: http://suo.im/6oGKsG

[3]

参考资料2: https://www.nandland.com/articles/tri-state-buffer-half-full-duplex.html

[4]

参考资料3: https://www.nandland.com/articles/tri-state-buffers-and-keep-hierarchy.html

[5]

FPGA/IC技术交流2020: https://blog.csdn.net/Reborn_Lee/article/details/105844330

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FPGA LAB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
  • 正文
    • 全双工与半双工
      • FPGA和ASIC中的三态缓冲器
        • 如何在VHDL和Verilog中推断出三态缓冲区
        • 参考资料
        • 交个朋友
          • 参考资料
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档