现代的数字设计中,考虑到实际应用要求,模块的时钟可能频率并不相同,跨时钟域这个比较令人痛疼的问题便油然而生了。为了满足建立时间和保持时间的要求,一种解决异步时钟域数据传送的时序违例方法出现了,采用FIFO来进行异步数据传送。
FIFO中读写指针递增电路设计很重要,常规的利用二进制计数器的方法实现指针的递增会产生时序的违例。简单分析,若计数器从ff到00改变,时钟边沿在数据转换的中间时间区域内来到,那么有可能新时钟域时钟采到的数据为00,01,10,11。这显然是不满足要求的。那么Gray码计数器就可以很好的解决这个问题。
小编说了这么多,其目的是给出一个Gray码应用的背景。好了,进入正题——利用ISE 进行电路设计。
1 配置环境
纵观Quartus II,Vivado,Modesim,Design compiler等EDA软件,可知对于电子设计来说,环境的配置是多么重要。打个比方,就FPGA而言,比较常用的设计方式是代码输入方式,利用的是FPGA内部的资源。环境就相当于一个生存空间一样,没有了生存环境,电路的设计将无法存在。在这里小编就针对常规的数字电路仿真软件modelsim来说。ISE设计,要想利用modelsim进行仿真,就必须配置环境,说道简单点,就是告诉modesim我如何去找ISE设计的文件。关于这一点不再赘述,对于ISE与modesim的联合仿真,则需在编译器件库之后,修改modelsim.ini文件,如下图所示,黄色区域为添加的路径,告诉仿真器在哪里找到器件的模型。
2 电路设计
本次设计采用代码输入,其部分代码如下:
module bin_to_gray(
input [3:0] bin,
output [3:0] gray
);
assign gray = (bin >> 1) ^ bin;
endmodule
以上代码是Binary to Gray 模块的verilog代码。当然了一个完整的设计需要很多模块,不会这么简单,在此,笔者只是以此为例。
3 添加约束
管脚约束,一般情况下写成脚本,直接读入,便于维护与移植,对于ISE来说,是.ucf文件。其格式如下:
NET bin<0> LOC = N5 | IOSTANDARD = "LVCMOS33"; ##
这是一种语言,看起来高大上,实际很简单,不同软件的约束脚本不尽相同。
时序约束,本模块并没有用到时序,因此不需要进行时序约束。但是时序约束是很重要的,笔者不多说,给读者留些学习的空间,感兴趣一定要查询资料,搞懂时序分析的原理,怎么进行约束。
3 电路仿真
电路仿真包括功能仿真和时序仿真。本文利用modelsim进行仿真。需要写testbench脚本,例化模块才能进行仿真,关于写脚本,主要是经验积累,因此需要多写,本文给出一个例子(部分核心代码),脚本质量一般,覆盖率还行,仅供参考,目的为了了解电路设计的人都可以读懂。
reg [3:0] bin;
// Outputs
wire [3:0] gray;
// Instantiate the Unit Under Test (UUT)
bin_to_gray uut (
.bin(bin),
.gray(gray)
);
initial begin
// Initialize Inputs
bin = 0;
#100;
// Add stimulus here
#100 bin = 4'b0010;
#200 bin = 4'b1010;
#100 bin = 4'b0101;
#200 bin = 4'b0010;
end
其结果如下:
注意一定要在保证功能正确的前提下,再进行优化。
4 分析设计
不可能一次设计出来,电路模块就接近完美。因此,必须进行不断的优化。那么优化从那些方面优化,这是一个值得读者思考的问题。下图是综合之后的电路图,易知利用了PPGA内部LUT资源。
可能目前还看得不太清楚,小编进行放大处理,如下图所示。打开后发现时很简单的基本数字电路结构——门。
要想实现很好的电路优化,必须了解FPPA内部的资源,只有熟悉了FPGA内部底层资源组成和工作原理,你才能灵活的分配与调用这些资源,下图就赛琳思一款FPGA的内部资源图,其中上面设计用到的LUT就是CLB的子模块。
同时还有分析时序,看一看时序是否有违规现象,若有就需要迭代以上的步骤。
5 下载及上板测试
在以上步骤都没问题的情况下,就可以进行最后一步,下载,在实际的环境中运行电路,看看是否满足要求。
笔者说的好多了,相比流程介绍来说,这篇文章显得特别简略,好多就没提,笔者只是从一些特定的角度谈一下有关ISE设计的东西。