加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

小茗老师带你学习——Verilog-三态门

(2017-04-15 20:35:58)
标签:

三态门

verilog

fpga

我们所接触到的IO都是单纯的输入(input)或者输出(output)类型,而我们的一些总线协议如IIC等,要求信号为三态类型,也就是我们所说的输入输出(inout)类型。那么,本节大家一起来探讨三态门的用法。

项目需求

设计一个三态门电路,可以实现数据的输出和总线“挂起”。

系统架构

http://s12/mw690/003wCLthzy7agq0WkYPfb&690

 

三态门系统架构图

模块功能介绍

模块功能描述表

模块名

功能描述

three_state

控制三态总线sda是否处于挂起状态

顶层模块端口描述

 顶层模块端口描述表

端口名

端口说明

clk

系统时钟

rst_n

系统低电平复位

data_buf

外部待传输数据输入

sda

三态数据总线

代码解释

1.三态门模块代码

00  module three_state(

01                          //系统输入

02                          clk,//系统50M输入

03                          rst_n,//低电平复位信号

04                          data_buf,

05                          //系统输出

06                          sda//三态总线

07                     );

08  //-------------------系统输入-------------------

09  input clk;//系统50M输入

10  input rst_n;//低电平复位信号

11  input data_buf;//待传输数据

12  //-------------------系统输出-------------------

13  inout sda;//三态总线

14  //------------------寄存器定义------------------

15  reg flag;//三态门开关定义

16  reg [10:0]counter;//计数器定义

17  //------------------三态门赋值------------------

18  assign sda=(flag==1)?data_buf:1'bz;

19  //----------------开关控制计数器----------------

20  always@(posedge clk or negedge rst_n)

21      begin

22          if(!rst_n)

23              begin

24                  counter<=0;//计数器复位

25              end

26          else

27              begin

28                  if(counter<</span>25)//计数器范围

29                      counter<=counter+1;//计数器累加

30                  else

31                      counter<=0;//计数器清零

32              end

33      end

34  //----------------开关/数据控制-----------------

35  always@(posedge clk or negedge rst_n)

36      begin

37          if(!rst_n)

38              begin

39                  flag<=0;//开关关闭

40              end

41          else

42              begin

43                  if(counter==25)

44                      flag<=~flag;//开关信号翻转

45              end

46      end

47  endmodule

18行代码就是三态门的赋值方式,三态门什么时候作为输出、什么时候作为输入是由开关信号flag控制的。当开关信号flag==1sda的值等于待发送的数据data_buf(此时,sda相当于是output类型),当开关信号flag==0sda的值变成高阻态(此时,sda相当于是input类型)。

20~33行代码为我们设计的一个定时器,用来控制开关信号的翻转。

43~44行代码表示当定时器到达预定值,开关电平开始翻转。

2.三态门模块测试代码

00  `timescale 1ns/1ns

01  module tb;

02  //-------------------系统输入-------------------

03  reg clk;//系统50M输入

04  reg rst_n;//低电平复位信号

05  reg data_buf;//待传输数据

06  //-------------------系统输出-------------------

07  wire sda;//三态总线

08  //-------------------测试激励-------------------

09  initial

10      begin

11          clk=0;//时钟赋初值

12          rst_n=0;//系统上电复位

13          data_buf=0;//data_buf赋初值

14          #1000 rst_n=1;//复位结束

15          #1000 data_buf=1;

16          #1000 data_buf=0;

17          #1000 data_buf=1;

18          #1000 data_buf=0;

19      end

20     

21  always #10 clk=~clk;//产生50MHZ时钟

22  //-------------------模块实例化-------------------

23  three_state three_state(

24          //系统输入

25          .clk(clk),//系统50M输入

26          .rst_n(rst_n),//低电平复位信号

27          .data_buf(data_buf),

28          //系统输出

29          .sda(sda)//三态总线

30       );

31  endmodule

14~18行代码,模拟的是待传输数据的变化。

仿真结果分析

http://s5/mw690/003wCLthzy7agq4gslu24&690

 

 三态门仿真结果

由仿真波形可以看出,当开关关闭(flag==0),sda总线放开,处于高阻状态,此时外部数据可以输入,相当于我们模块的输入。

当开关打开(flag==1),sda等于data_buf的值,说明此时,sda相当于我们模块的输出。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有