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

网友投稿 900 2022-05-30

博文目录

写在前面

正文

全双工与半双工

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 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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

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

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

1

读使能有效时,我们将从缓冲区读出的数据放到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 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

1

2

3

4

5

6

7

8

9

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

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

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

assign data = !oe ? tb_data : 'hz;

1

否则,也就是写使能无效时,就为高阻态,不占用数据总线!

注:上面用了oe无效代替写使能有效,有点不太严谨,但也没问题 ,仅供各位参考!

个人博客首页

注:学习交流使用!

正文

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

全双工与半双工

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

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

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

FPGA和ASIC中的三态缓冲器

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

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

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

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

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;

1

2

3

4

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

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

1

2

3

4

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

参考资料

参考资料1

参考资料2

参考资料3

交个朋友

知乎:李锐博恩

FPGA/IC技术交流2020

FPGA 单片机

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【Akka系列】之 Actor模型如何满足现代分布式系统的需求
下一篇:Java终于开始引入虚拟线程(协程)了
相关文章