首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

fpga内部的延时单元

fpga内部的延时单元

在两片FPGA做信号同步的时候,碰到了这个问题:想延时某个信号,但是不能用锁存的办法。因为时钟是外部给的,频率不定,而且起始相位有0和180度的模糊。
很容易想到加一些组合逻辑延时。又怕给综合器优化掉。
因此,引发第一个问题,如何不让综合器优化我们的信号呢?
参考:Xilinx 自带的Constrains Guide(Xilinx\doc\usenglish\books\docs\cgd\cgd.pdf).
使用keep约束。
Before using KEEP, declare it with the following syntax:
attribute keep : string;
After KEEP has been declared, specify the VHDL constraint as follows:
attribute keep of signal_name: signal is “true”;
For a detailed discussion of the basic VHDL syntax, see “VHDL”.
例子:
在vhdl程序中写下如下代码即可:
attribute keep : string;
attribute keep of keep1: signal is "true";
attribute keep of keep2: signal is "true";

keep1 <= not sig_delay;
keep2 <= not keep1;

布线之后看布线报告,发现加个非门时延也太大了,大于1ns了。不能满足实际项目的要求。
参考了这个帖子:
http://www.fpgatech.net/forum/viewthread.php?tid=121
[原创]在FPGA中使用与逻辑实现延时而又保证不会被优化掉的一种方法
作者:FPGATech
尽管在很多设计建议中不提倡使用连续的与门来实现FPGA内部的延时,但在某些情况下(特别是在高速设计的时候),这种方法还是有点所用。但如果使用 HDL的与逻辑实现的话,这些连续的与延时会被综合工具优化掉。那么有没有办法实现呢?答案是肯定的,我们可以利用FPGA内部的一些特殊原语来实现。下面的例子在V21000、ISE 7.1SP4、Amplify 3.71下已经得到了验证。

MUXCY muxcy_inst0 (
    .DI (1'b0),
    .CI (in1),
    .S (in2),
    .O (temp_and[0])
);

在这个例子中使用MUXCY的一个好处是:由于使用了具有专用布线资源的进位链实现,使得布线延时对整个延时的影响最小。在其它器件和工具中能否实现,我没有验证。欢迎大家继续讨论更好的实现方法。

这个问题我们可以进行进一步的探讨,在现在许多高速设计中(例如DDR2 SDRAM、QDR、SPI4总线),总线上的很小的偏移就可能导致设计无法正常工作,这时就需要对输入总线作一些微小延时调整,甚至需要动态地调整(DPA)。一个最直接的办法就是在输入信号上串入数字延时线,同时监视信号线上一些“Training Pattern”,然后从数字延迟线的不同点抽出信号。实际上这种方法就是模拟一个数字延迟线。为什么要使用MUXCY呢?这是因为在FPGA中,进位链采用的是专有的布线资源,其延时是可预测的。至于PVT的问题,可以采用DPA来作动态的调整。当然,这种方法存在其固有的缺陷,例如对P&R的要求很高、可移植性差、需要很多人工参与等。但在当前的设计要求下,这也是没有办法的办法。现在FPGA厂家也都已经意识到了这些设计挑战,也推出了相应的解决方案来解决这些问题,例如Xilinx V4、lattice SC系列等。

关于 muxcy 参考lib.pdf。
vhdl代码示例:
component MUXCY
port (O : out STD_ULOGIC;
CI : in STD_ULOGIC;
DI : in STD_ULOGIC;
S : in STD_ULOGIC);
end component;

my_muxcy1 : MUXCY
port map (O => reset_keep2,
CI => '1',
DI => '0',
S => reset_keep1);

用上了这个之后,还真解决了我的问题~~~~~

ps:
关于Xilinx V2Pro DCM调相位超前的问题, Xilinx的问答数据库链接:
Virtex-II/Virtex-II Pro, DCM - The use of negative, FIXED-mode phase shift requires a work-around or a positive PHASE_SHIFT value (DPS)
Answer Record:     13349
http://www.xilinx.com/xlnx/xil_ans_display.jsp?getPagePath=13349&BV_SessionID=@@@@0526526914.1188788148@@@@&BV_EngineID=cccgaddlldjjfflcefeceihdffhdfjf.0






我们打算FPGA或CPLD内部利用门来做延时,但是普通的编译器会自动对程序进行化简,以至于无法从仿真波形看到门延时的效果。

听说Synplify或者LeonadoSpectrum通过约束可以实现门延时。
请问如何实现?

在Leonardo中,可以通过预优化(pre-optimization)选项来控制是否进行综合优化。read文件时,把input标签里的Run Pre-Optimization选项关闭,这样在做RTL到门级转换时(elabration),原有设计保持原样,不被优化。用户还可以在功能标签Pre-Optimize里根据不同需要去详细调节,请查看边上的Help说明。

------此部分由from Mentor 秦贤智回复



在Synplify Pro中,可以给不想被综合器优化的单元或连线预先设定Directive,如syn_keep或syn_preserve,以达到在某个局部不进行优化的目的。可以具体参考相关工具手册的Attribute/Directive章节。
—————————此部分由林斌回复





FPGA设计中的延时电路的产生:在日常的电路设计中,有时候我们需要对信号进行延时处理来适应对外接口的时序关系,最经常也是最典型的情况是做处理机的接口;因为与处理的接口时序关系是异步的,而一个规范的FPGA设计应该是尽可能采用同步设计。那么遇到这种情况该如何处理呢?首先在FPGA中要产生延时,信号必须经过一定的物理资源。在硬件描述语言中有关键词Wait for xx ns,需要说明的是该语法是仅仅用于仿真而不能用于综合的,可综合的延时方法有:使信号经过逻辑门得到延时(如非门);使用器件提供的延时单元(如Altera公司的LCELL,Xilinx公司的);注意:当使用多级非门的时候综合器往往会将其优化掉,因为综合器会认为一个信号非两次还是它。需要说明的是在FPGA/CPLD内部结构是一种标准的宏单元,下图是Xilinx公司的Spartans II系列器件的一个标准宏单元。虽然不同的厂家的芯片宏单元的结构不同,但概括而言都是由一些组合逻辑外加一或二个触发器而构成。在实际应用中,当一个模块内的组合逻辑被使用了那么与其对应的触发器也就不能用了;同样如果触发器单元被用了那么组合逻辑单元也就废了。这就是有时候(特别是使用CPLD)虽然设计使用的资源并不多但布局布线器却报告资源不够使用的原因。 当需要对某一信号作一段延时时,初学者往往在此信号后串接一些非门或其它门电路,此方法在分离电路中是可行的。但在FPGA中,开发软件在综合设计时会将这些门当作冗余逻辑去掉,达不到延时的效果。用ALTERA公司的MaxplusII开发FPGA时,可以通过插入一些LCELL原语来产生一定的延时,但这样形成的延时在FPGA芯片中并不稳定,会随温度等外部环境的改变而改变,因此并不提倡这样做。在此,可以用高频时钟来驱动一移位寄存器,待延时信号作数据输入,按所需延时正确设置移位寄存器的级数,移位寄存器的输出即为延时后的信号。此方法产生的延时信号与原信号比有误差,误差大小由高频时钟的周期来决定。对于数据信号的延时,在输出端用数据时钟对延时后信号重新采样,就可以消除误差。

你可以Quartus的RTL View中比效下面现段程序的区别:
程序1:
module delayg(a,b,out);
input a,b;
output out;
wire t/* synthesis keep = 1 */;
wire x/* synthesis keep = 1 */;
wire y/* synthesis keep = 1 */;
wire z/* synthesis keep = 1 */;
assign t=a^b;
assign x=t;
assign y=x;
assign z=y;
assign out=z;
endmodule


程序2:
module delayg(a,b,out);
input a,b;
output out;
wire t;
wire x;
wire y;
wire z;
assign t=a^b;
assign x=t;
assign y=x;
assign z=y;
assign out=z;
endmodule
返回列表