基础项目(3)三态门程序设计讲解

写在前面的话

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

项目需求

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

系统架构

模块功能介绍

模块名

功能描述

three_state

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

顶层模块端口描述

端口名

端口说明

Clk

系统时钟

Rst_n

系统低电平复位

Data_buf

外部待传输数据输入

Sda

三态数据总线

代码解释

三态门模块代码

/****************************************************          

 *   Engineer      :   梦翼师兄

 *   QQ             :   761664056

 *   The module function:三态门模块

*****************************************************/

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<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==1,Sda的值等于待发送的数据data_buf(此时,Sda相当于是output类型),当开关信号flag==0,Sda的值变成高阻态(此时,Sda相当于是input类型)。

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

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

三态门模块测试代码

/****************************************************          

 *   Engineer      :   梦翼师兄

 *   QQ             :   761664056

 *   The module function:三态门测试模块

*****************************************************/

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行代码,模拟的是待传输数据的变化

仿真分析

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

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

 

posted @ 2019-09-14 08:45  梦翼师兄  阅读(799)  评论(0编辑  收藏  举报