zoukankan      html  css  js  c++  java
  • FPGA中双向端口的设计原理及仿真

    在FPGA中,双向端口一般是通过对三态们控制来实现的。硬件结构如下图所示:

    当Z=0时,上面的管子开通,此时数据可以从上面的管子输出,这是双向端口就作为输出口;当Z=1时,上面管子被置为高阻态,数据不能从上面的管子输出,此时数据只可以从下面的管子由外向内输入,这是的双向端口是输入口。

    双向端口示意图如下所示:

    输入口din定义:input [7:0] din;当双向端口dinout作为输出口时,我们从din端口输入数据到模块中,让数据从dinout口出来。

    输出口dout定义:output [7:0] dout;当双向端口dinout作为输入口时,我们让数据从dinout口输入,从输出口dout输出。

    双向端口dinout定义:inout [7:0] dinout;

    三态门选通信号Z:input Z;当Z=1时,把三态们置为高阻态,这时dinout作为输入口用;当Z=0时,开通三态门,这时dinout作为输入口用。

    三态们控制语句为; assign dinout = (!z) ? din_reg : 8’bz;

    总体程序设计如下:

    module bidirec_data(
    clk,
    z,
    din,
    dinout,
    dout
    );
    // --------------Port Declaration----------------------
    input				clk;
    input				z;
    input	[15:0]		din;
    inout	[15:0]		dinout;
    output	[15:0]		dout;
    //--------------Port data type declaration-------------
    reg		[15:0]		dout;
    //--------------Define Parameter-----------------------
    //--------------Internal Registers---------------------
    reg		[15:0]		din_t;
    //--------------Code Starts Here-----------------------
    assign dinout = (!z) ? din_t : 16'dz;
    always @ (posedge clk) begin
    	if(!z)
    		din_t <= din;
    	else
    		dout <= dinout;
    end
    endmodule
    
    
    

     

    激励文件如下:

    `define  test = 1;
    
    module test_bidata;
    	// Inputs
    	reg clk;
    	reg z;
    	reg [15:0] din;
    	// Outputs
    	wire [15:0] dout;
    	// Bidirs
    	wire [15:0] dinout;
    	integer i;
    	// Instantiate the Unit Under Test (UUT)
    	bidirec_data uut (
    		.clk(clk), 
    		.z(z), 
    		.din(din), 
    		.dinout(dinout), 
    		.dout(dout)
    	);
    always #10clk=~clk; 
    `ifdef test
    	initial begin
    		// Initialize Inputs
    		clk = 0;
    		z = 1;
    		din = 0;
    		force dinout = 20;
    		// Wait 100 ns for global reset to finish
    		#200 for(i = 0; i < 10; i = i + 1)
    		#20 force dinout = dinout - 1;
    		// Add stimulus here
    	end
    `else
    initial begin
       din = 0; 
       z = 0; 
       clk = 0;
       # 200 din= 10;
       for(i=0;i<20;i=i+1)
          #20 din = din+1;
    end    
    `endif  
    endmodule
    
    
    
    

    RTL如图所示

    仿真波形如图所示

    当仿真代码中添加了 `define test; 则代码中选择编译 Z=1,即选择将dinout作为输入端口使用,波形如图所示:

    当仿真代码中将 `define test;  注释掉,则代码中选择编译 Z = 0,即选择将dinout作为输出端口使用,波形如图所示:

    注意:当双向端口dinout作为输入端口时,我们需要对它进行初始化赋值,此时关闭三态门,即Z=1。对于双向端口的初始化赋值,如果我们采用一般的输入端口的赋值方式给它赋值,则会出错。因为输入输出端口既是输入端口也是输出端口,所以在激励中采用一般的赋值方式是不行的。在Verilog的书籍中对于双向端口的初始化赋值介绍比较少。在此需要使用force命令来给dinout进行输入赋值,详细见激励代码。

  • 相关阅读:
    Atitit. visual studio vs2003 vs2005 vs2008  VS2010 vs2012 vs2015新特性 新功能.doc
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit. C#.net clr 2.0  4.0新特性
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit.通过null 参数 反射  动态反推方法调用
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit..net clr il指令集 以及指令分类  与指令详细说明
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.变量的定义 获取 储存 物理结构 基本类型简化 隐式转换 类型推导 与底层原理 attilaxDSL
    Atitit.跨语言反射api 兼容性提升与增强 java c#。Net  php  js
  • 原文地址:https://www.cnblogs.com/icelyb24/p/2086288.html
Copyright © 2011-2022 走看看