引言
FPGA 是现场可编程门 阵 列 的 缩 写,它 是 在PAL,GAL 及 EPLD 等可编程器件的基础上发展起 来的。FPGA 具有速度快、密 度 高、功 耗 小 的 特点。 采用 FPGA 芯片进行专用集成电路设计,既可以解决定制电路缺乏灵活性的不足,又可以通过相关的软 硬件环境掌握芯片的最终功能,提高一次设计的成功 率,所以,目前 FPGA 在电子设计中已被广 泛使用。 同时,由于 FPGA 经常要和外部存储器及 CPU 进行数据输入输出交换,而利用双向端口的设计来进行数据交换可以成倍地节省各自的引脚资源。
双向端口顾名思义是一种既可以作为输入端口 接收数据,也可以作为输出端口发出数据,它对数据 的操作是双向的。 比如某个设计需要一个 16 位的 数据输入口和一个16 位的数据输出口,并且数据输 入和输出不会同时发生。 如果数据输入口和输出口 分别设计则需要32根数据线,而用双向端口来设计,则只需要16 根数据线,这样就节省了16 根数据 线引脚。由于现在的大多数资料对双向端口的设计介绍很少,本文给出 FPGA 中双向端口的设计原理和方法,以及仿真和初始化双向端口的方法,同时选用Xilinx的Spartan2E 芯片进行实际应用。
1、 FPGA 中双向端口的设计原理和Verilog硬件语言程序设计
首先介绍双向端口在 FPGA 内部硬件资源是怎样实现的。 在 FPGA 中 它是通过对三态门控制来实现双向端口的,比如在 Xilinx 的Spartan2E 中 的图例(如图1 所示):
图1 双向端口的硬件图
当z=0 时,上面输出的管子开通,此时数据可以从上面的管子中输出,这时双向端口就作为输出口;当z=1 时,上面的管子被置为高阻态,数据不能从上面的管子输出,此时数据只可以从下面的管子由外向内输入,这时的双向端口是输入口。限于篇幅,我们做一个简单的模型来说明双向 端口的设计。下面我们用 Verilog 硬件语言进行双向端口的程序设计,为了看出双向端口分别作为输入端口和输出端口的功能,我们的模块分别定义一个数据输入口 din 和一个数据输出口 dout,一个三态门选通信号 z,触发 时钟 clk,还有双向端口 dinout。 我们设数据为8 位宽。 图2为该模块图:
图2 定义的模块图
输入口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 作为输出口用。
三态门控制语句为: asigndinout=(!z)?din_reg:8'bz;
总的完整程序如下:
module dinout(din,z,clk,dout,dinout);
input [7:0] din;
input z;
input clk;
output[7:0] dout;
inout [7:0] dinout;
reg [7:0] dout;
reg [7:0] din_reg;
asign dinout= (!z)?din_reg:8'bz;
always @ (posedge clk)
begin
if(!z)
din_reg=din;
else
dout=dinout;
end
Endmodule
2、 仿真及初始化双向端口
下面我们对上述程序进行时序仿真。 这里我们选用的 FPGA 芯片为 Xilinx 的 Spartan2E 系列,型 号为 xc2s300e-7pq208,在ISE Foundation6.1 软件中综合及布局布线,并用 Modelsim Simulator进行时序仿真。
当双向端口dinout作为输出口时,我们不需要 对它进行初始化,只要开通三态门。
我们设定在200ns后,让数 据10,11,12,13,14,15,16,17,18,19,20 依次从 din 口输入,然后用20ns的采样时钟从dinout口输出。
它的测试仿真顶层模块为
`timescale 1ns/1ps
module dinoutest();
reg [7:0] din;
reg z;
reg clk;
wire [7:0] dout;
wire [7:0] dinout;
integer i;
dinout uut(
.din(din),
.z(z),
.clk(clk),
.dout(dout),
.dinout(dinout)
);
always #10clk=~clk;
initial begin
din = 0;
z = 0;
clk = 0;
# 200 din=10;
for(i=0;i<10;i=i+1)
#20 din=din+1;
end
endmodule
该仿真的时序图如图3 所示:
可以看出这时双向端口 dinout作为输出口, 输出
从din 输入口输入到模块中的数据。
当双向端口dinout作为输入口时,我们需要对它进行初始化赋值,此时关闭三态门。 而对双向端 口的初始化赋值,如果把它跟一般的输入口一样直接赋 值 给它,则会出错,因为在定义它的时候是wire型了,而 不是reg 型。 在许多 Verilog 书籍和参考资料中,有关双向端口的初始化赋值介绍的很少。这里需要 用到一个force 命令,用来给dinout 输入赋值。 我 们设定在200ns 后,让数据20,19,18,17,16,15,14,13,12,11,10 从dinout口输入模块,然后用 20ns的采样时钟从输出口 dout输 出。以下是它的仿真顶层模块
`timescale 1ns/1ps
module dinoutest();
reg [7:0]din;
reg z;
reg clk;
wire [7:0] dout;
wire [7:0] dinout;
integeri;
dinoutuut(
.din(din),
.z(z),
.clk(clk),
.dout(dout),
.dinout(dinout)
);
always #10clk= ~clk;
initial begin
z = 1;
clk = 0;
force dinout=20;
# 200 for (i=0;i<10;i=i+1)
#20 force dinout=dinout-1;
end
endmodule
该仿真的时序图如图4 所示:
图4 双向端口作为输入口时的时序仿真
可以看出这时双向端口 dinout作为输入口,数 据从dinout口 输入模块,然后从输出口dout完整地输出来。
3 、实际应用
这种双向端口设计方法已被我们用到目前开发 的一个多通道图象捕获和显示控制系统中。 在该系 统中,FPGA 接收从两个图像传感器传来的数字视频信号,然后根据CPU的命令对这两路视频信号进行四种显示模式的组合操作。FPGA 将处理好的 信号存到外部存储器中。如果LCD显示信号来了, FPGA 从外部存储器中取数据给LCD显示。如果CPU 想要对某一帧图像数据进行图象识别操作,可 以经过 FPGA 从外部存储器中把该帧图象数据取下来。 其中 LCD 的时钟频率为 6M,FPGA 对外部存储器及 CPU 数据 操作的时钟频率为 24M,并且LCD显示操作优先级最 高。在这个系统中用到了两个双向端口,一个是FPGA 与CPU的数据交换, 另一个是FPGA与外部存储器之间的数据交换,他们都是16 位的数据交换,由于用了双向端口,节省了32个引脚资源,同时优化了器件的选择和整体设计,降低了成本。 图 5为多通道图象捕获和显示控制系统的框图。
图5 应用双向端口的多通道图象捕获和显示控制系统
4、结论
由于现在 FPGA 设计和外部存储器或 CPU 数据交换的频繁运用,以及引脚资源有限,而使用双向端口设计可以成倍的节省数据引脚线,所以设计好FPGA 的双向端口至关重要。 在设计 FPGA 中的双向端口时应注意两点:
其一,要用三态门的控制来 处理实现双向端口;
其二,要分别指定双向端口作为输出口和输入口时,对外部对象的数据操作。