1、介绍
IBUFDS、和OBUFDS都是差分信号缓冲器,用于不同电平接口之间的缓冲和转换。IBUFDS 用于差分输入,OBUFDS用于差分输出。
2、IBUFDS
2.1、理论
IBUFDS是差分输入缓冲器,支持低压差分信号(如LVCMOS、LVDS等)。在IBUFDS中,一个电平接口用两个独特的电平接口(I和IB)表示。一个可以认为是主信号,另一个可以认为是从信号。
IBUFDS原语示意图如下所示:
端口说明如下表:
端口 | 类型 | 位宽 | 功能 |
I | 输入 | 1 | 差分输入+端 |
IB | 输入 | 1 | 差分输入-端 |
O | 输出 | 1 | 输出 |
信号真值表如下:
输入 | 输出 | |
I | IB | O |
0 | 0 | 不改变,同上次输出 |
0 | 1 | 0 |
1 | 0 | 1 |
1 | 1 | 不改变,同上次输出 |
2.2、仿真
打开VIvado--Tools--Language Templates,搜索“IBUFDS”,可以找到Xilinx提供的模板如下:
-
IBUFDS #(
-
.
DIFF_TERM(
"FALSE"),
// Differential Termination
-
.
IBUF_LOW_PWR(
"TRUE"),
// Low power="TRUE", Highest performance="FALSE"
-
.
IOSTANDARD(
"DEFAULT")
// Specify the input I/O standard
-
)
IBUFDS_inst (
-
.
O(O),
// Buffer output
-
.
I(I),
// Diff_p buffer input (connect directly to top-level port)
-
.
IB(IB)
// Diff_n buffer input (connect directly to top-level port)
-
);
DIFF_TERM、IBUF_LOW_PWR分别指定差分终端和性能模式,IOSTANDARD指定你需要输出的电平标准。
接下来例化一个IBUFDS原语进行测试,Verilog代码如下:
-
//------------------------------------------------------------------------
-
//--IBUFDS测试模块
-
//------------------------------------------------------------------------
-
//------------<模块及端口声明>----------------------------------------
-
module IBUFDS_test(
-
input clk ,
//时钟,50M
-
input rst_n ,
//复位,低电平有效
-
input data_p ,
//输入数据,差分+
-
input data_n ,
//输入数据,差分-
-
-
output
out
-
);
-
//------------<例化原语>----------------------------------------
-
IBUFDS #(
-
.DIFF_TERM (
"FALSE") ,
// Differential Termination
-
.IBUF_LOW_PWR (
"TRUE") ,
// Low power="TRUE", Highest performance="FALSE"
-
.IOSTANDARD (
"DEFAULT")
// 选择I/O电平标准,这里选择默认
-
)
-
IBUFDS_inst (
-
.O (
out) ,
// 输出
-
.I (data_p) ,
// 差分输入+(需要直接连接到顶层端口)
-
.IB (data_n)
// 差分输入-(需要直接连接到顶层端口)
-
);
-
-
endmodule
每隔20ns分别随机生成2个1位2进制数据作为差分输入,观察输出,Testbench如下:
-
//------------------------------------------------
-
//--IBUFDS原语仿真
-
//------------------------------------------------
-
`timescale
1ns/
1ns
//时间单位/精度
-
//------------<模块及端口声明>----------------------------------------
-
module tb_IBUFDS_test();
-
-
reg clk ;
-
reg rst_n ;
-
reg data_p ;
-
reg data_n ;
-
-
wire
out ;
-
//------------<例化被测试模块>----------------------------------------
-
IBUFDS_test IBUFDS_test_inst(
-
.clk (clk) ,
-
.rst_n (rst_n) ,
-
.data_p (data_p) ,
-
.data_n (data_n) ,
-
-
.out (out)
-
);
-
//------------<设置初始测试条件>----------------------------------------
-
initial begin
-
clk =
1'b1;
//初始时钟为1
-
rst_n <=
1'b0;
//初始复位
-
data_p <=
1'b0;
-
data_n <=
1'b0;
-
#60 //60个时钟周期后
-
rst_n <=
1'b1;
//拉高复位,系统进入工作状态
-
end
-
//------------<设置时钟>----------------------------------------------
-
always
#10 clk = ~clk; //系统时钟周期20ns
-
-
always
#20 data_p <= $random % 2; //每20ns生成 1 或者 0
-
always
#20 data_n <= $random % 2; //每20ns生成 1 或者 0
-
-
endmodule
仿真结果如下:
每隔20ns,2个差分输入端口分别随机生成2个1位2进制数据;输出输入符合上述的真值表。
3、OBUFDS
3.1、理论
OBUFDS 是一个差分输出缓冲器,用于将来自 FPGA 内部逻辑的信号转换成差分信号输出,支持 TMDS、LVDS等电平标准。它的输出用O和OB两个独立接口表示。一个可以认为是主信号,另一个可以认为是从信号。
OBUFDS原语示意图如下所示:
端口说明如下表:
端口 | 类型 | 位宽 | 功能 |
O | 输出 | 1 | 差分输出+端 |
OB | 输出 | 1 | 差分输出-端 |
I | 输入 | 1 | 输入 |
信号真值表如下:
输入 | 输出 | |
I | O | OB |
0 | 0 | 1 |
1 | 1 | 0 |
可以看出,输出+端与输入一致,输出-端与输入相反。
3.2、仿真
打开VIvado--Tools--Language Templates,搜索“OBUFDS”,可以找到Xilinx提供的模板如下:
-
OBUFDS #(
-
.
IOSTANDARD(
"DEFAULT"),
// Specify the output I/O standard
-
.
SLEW(
"SLOW")
// Specify the output slew rate
-
)
OBUFDS_inst (
-
.
O(O),
// Diff_p output (connect directly to top-level port)
-
.
OB(OB),
// Diff_n output (connect directly to top-level port)
-
.
I(I)
// Buffer input
-
);
其中IOSTANDARD指定你需要输出的差分电平标准,SLEW根据你的要求输出FAST或者SLOW。
接下来例化一个OBUFDS原语进行测试,Verilog代码如下:
-
//------------------------------------------------------------------------
-
//--OBUFDS测试模块
-
//------------------------------------------------------------------------
-
//------------<模块及端口声明>----------------------------------------
-
module OBUFDS_test(
-
input clk ,
//时钟,50M
-
input rst_n ,
//复位,低电平有效
-
input
data ,
//输入数据
-
-
output out_p ,
//输出数据,差分+
-
output out_n
//输出数据,差分-
-
);
-
//------------<例化原语>----------------------------------------
-
OBUFDS #(
-
.IOSTANDARD (
"DEFAULT") ,
// 选择I/O电平标准,这里选择默认
-
.SLEW (
"SLOW")
// 选择输出速率,这里选择SLOW
-
)
-
OBUFDS_inst (
-
.O (out_p) ,
// 差分输出+(需要直接连接到顶层端口)
-
.OB (out_n) ,
// 差分输出-(需要直接连接到顶层端口)
-
.I (
data)
// 输入
-
);
-
-
endmodule
每隔20ns随机生成一个1位2进制数据,观察差分输出,Testbench如下:
-
//------------------------------------------------
-
//--OBUFDS原语仿真
-
//------------------------------------------------
-
`timescale
1ns/
1ns
//时间单位/精度
-
//------------<模块及端口声明>----------------------------------------
-
module
tb_OBUFDS_test();
-
reg clk ;
-
reg rst_n ;
-
reg data ;
-
-
wire out_p ;
-
wire out_n ;
-
//------------<例化被测试模块>----------------------------------------
-
OBUFDS_test
OBUFDS_test_inst(
-
.
clk (clk),
-
.
rst_n (rst_n),
-
.
data (data),
-
-
.
out_p (out_p),
-
.
out_n (out_n)
-
);
-
//------------<设置初始测试条件>----------------------------------------
-
initial begin
-
clk =
1
'b1;
//初始时钟为1
-
rst_n <=
1
'b0;
//初始复位
-
data <=
1
'b0;
-
#
60
//60个时钟周期后
-
rst_n <=
1
'b1;
//拉高复位,系统进入工作状态
-
end
-
//------------<设置时钟>----------------------------------------------
-
always #
10 clk = ~clk;
//系统时钟周期20ns
-
always #
20 data <= $random %
2;
//每20ns生成 1 或者 0
-
-
endmodule
仿真结果如下:
每隔20ns,data随机生成0或者1,out_p与输入一致,out_n与输入相反;差分输出信号符合上述的真值表。