用户必须要认识到,学习一下技巧可以让更多的逻辑放在更少的Slice中,使工具能够达到既实现设计时序要求又满足用户对功耗的要求。而现在很多用户缺乏代码编写的想法,编写出一个有时序问题的设计。为了满足要求,就会不停修改,再综合再布局布线来满足自己的时序目标。其实,他们需要的是重新评估他们的HDL代码技术以及他们的控制信号。
例如,如何使用这些D触发器呢?首先说明几个概念:
所有触发器为D类型,所有的触发器具有一个时钟输入(CLK),所有触发器都有一个使能信号(CE),所有触发器有一个高有效的复位信号(SR),SR可以是同步或异步控制来设置触发器值,所有触发器的值在配置过程中将会被确定下来。
所有D触发器在7系列FPGA有一个芯片使能(CE)引脚,并通过时钟进行相关操作。当使能信号有效的时候,D触发器的输出等于前一个输入,当使能信号无效时,D触发器保持当前值。下面的代码就是一个很好的例子来说明FPGA的D触发器会被工具推断出来是寄存器。
Verilog:
always @ (posedge CLK )
begin
if (CE)
Q <= D;
end
VHDL:
FF: process (CLK)
begin
if (rising_edge CLK) then
if (CE = ‘1’) then
Q <= D;
end if;
end if;
end
对于XILINX的器件来说,大部分都是高有效。如果用户想使用低有效,需要占用LUT作为一个反转逻辑来使用,这也无疑增加了资源的使用。
D触发器有一个高有效的SR端口信号,SR端口可以被配置成同步置位/复位、异步置位或者复位、清零端口。它是基于用户的编码风格被配置为同步或异步的。置位时,触发器输出将被强制为触发器的置位/复位值,综合工具会自动从用户的HDL代码中推断出初始值进行设置的。
介绍一下异步复位。首先必须指出,虽然XILINX的器件支持异步复位,但是XILINX不建议使用异步复位。当用户必须使用异步复位的时候,想使工具能够推断出异步复位逻辑,那么必须把异步复位信号放在敏感列表里面,当该复位信号有效的时候,输出的信号必须立即等于复位的值。下面的例子可以很好的阐述该问题。
Verilog
always @ (posedge CLK or posedge RST )
begin
if (RST)
Q <= 1’b0;
else
Q <= D;
End
VHDL
FF: process (CLK, RST)
begin
if (RST = ‘1’) then
Q <= ‘0’;
elsif (rising_edge CLK) then
Q <= D;
end if;
end
上图这个例子很好的说明了如何同步用户的异步复位设计。这个电路设置能够有效的避免亚稳态。在用户必须使用异步复位的时候,应该使用该例子推荐的方法来进行设计,也就是异步复位必须同步化。如果没有把异步复位同步化,那么将可能引起亚稳态或者增加亚稳态的风险。
Verilog
always @ (posedge CLK)
begin
if (RST)
Q <= 1’b0;
else
Q <= D;
end
VHDL
FF: process (CLK)
begin
if (rising_edge CLK) then
if (RST = ‘1’) then
Q <= ‘0’;
else
Q <= D;
end if;
end
再说说同步复位。这个例子说明了如何HDL代码中正确的使用同步复位。有几个关键点很重要,首先就是复位信号不能在敏感列表里面,其次,只有当时钟有效的翻转的时候,输出信号才能有效赋值。当复位信号有效的时候,只是得到了一个同步复位的行为,只有当有复位效后的第一个有效时钟翻转才能传递复位信息。这个Reset信号就是一个时序路径上的一个节点,会被工具自动进行相对应的时序约束。这意味这工具会根据你的时序目标进行优化的布线。这也是XILINX推荐的复位的方法。