打印

verilog与vhdl

[复制链接]
2914|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
uiodh|  楼主 | 2013-1-31 10:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
当综合工具发现这组代码时,其中缺乏如何实施双向缓冲器的明确指示。因此,工具会做出最合理的猜测。
实现上述任务的一种方法是, 在FPGA的I/O环上采用双向缓冲器(事实上,这是一种理想的实施方式)。另一种选择是采用三态输出缓冲器和输入缓冲器,二者都在查询表 (LUT) 逻辑中实施。最后一种可行方法是,在I/O环上采用三态输出缓冲器,同时在LUT中采用输入缓冲器,这是大多数综合器选用的方法。
这三种方法都可以生成有效逻辑,但是后两种实施方式会在I/O引脚与LUT之间传输信号时产生更长的路由延迟。此外,它们还需要附加的时序约束,以确保时序收敛。FPGA编辑器清晰表明:在图1中,我们的双向I/O有一部分散布在I/O缓冲器之外。

教训是切记不要让综合工具猜测如何实施代码的关键部分。即使综合后的逻辑碰巧达到您的预期,在综合工具进入新版本时情况也有可能发生改变。
应当明确定义您的I/O逻辑和所有关键逻辑。以下VHDL代码显示了如何采用Xilinx® IOBUF原语对I/O缓冲器进行隐含定义。另外需要注意的是,采用相似方式明确定义缓冲器的所有电气特性。
sda_buff: IOBUF
g e n e r i c m a p ( I O S TANDARD =>
"LVCMOS25",
IFD_DELAY_VALUE => "0", DRIVE =>
12,
SLEW => "SLOW")
port map(o=> data_out, io=> sda,
i=> data_in, t=> enable_in);

FPGA编辑器明确显示,我们已完全在I/O缓冲器内部实施了双向I/O。
异步逻辑的劣势异步代码会产生难以约束、仿真及调试的逻辑。异步逻辑往往产生间歇性错误,而且这些错误几乎无法重现。另外,无法生成用于检测异步逻辑所导致的错误的测试平台。
虽然异步逻辑看起来可能容易检测,但是,事实上它经常不经检测;因此,设计人员必须小心异步逻辑在设计中隐藏的许多方面。所有钟控逻辑都需要一个最短建立与保持时间,而且这一点同样适用于触发器的复位输入。以下代码采用异步复位。在此无法为了满足触发器的建立与保持时间需求而应用时序约束。
data_proc : PROCESS (sys_clk,reset)
BEGIN
if (reset = '1') then
data_in <= '0';
elsif rising_edge(sys_clk) then
data_in <= serial_in;
end if;
END PROCESS data_proc;
下列代码采用同步复位。但是,大多数系统的复位信号都可能是按键开关,或是与系统时钟无关的其它信号源。尽管复位信号大部分情况是静态的,而且长期处于断言或解除断言状态,不过其水平仍然会有所变化。相当于系统时钟上升沿,复位解除断言可以违反触发器的建立时间要求,而对此无法约束。
data_proc : PROCESS (sys_clk)
BEGIN
if rising_edge(sys_clk) then
if (reset = '1') then
data_in <= '0';
else
data_in <= serial_in;
end if;
end if;
END PROCESS data_proc;
只要我们明白无法直接将异步信号馈送到我们的同步逻辑中,就很容易解决这个问题。以下代码创建一个称sys_reset 的新复位信号,其已经与我们的系统时钟sys_clk同步化。在异步逻辑采样时会产生亚稳定性问题。我们可以采用与阶梯的前几级进行了‘与’运算的梯形采样降低此问题的发生几率。

看起来好像一切都已经同步化,但是nibble_proc采用乘积项divide_by_4对来自时钟域sys_clk_bufg的 nibble_wide_data进行采样。由于路由延迟,divde_by_4与sys_clk_bufg之间并无明确的相位关系。将divide_by_4转移到BUFG也于事无补,因为此进程会产生路由延迟。解决方法是将nibble_proc保持在sys_clk_bufg域,并且采用divide_by_4作为限定符,如下所示。
nibble_proc : PROCESS (sys_clk_bufg)
BEGIN
if rising_edge(sys_clk_bufg) then
if (sys_reset = '1') then
nibble_data_in <= "0000";
elsif (divide_by_4 = '1') then
nibble_data_in
<= nibble_wide_data;
end if;
end if;
END PROCESS nibble_proc
时序约束的重要性
如果您希望自己的逻辑正确运行,则必须采用正确的时序约束。如果您已经慎重确保代码全部同步且注册了全部I/O,则这些步骤可以显著简化时序收敛。在采用上述代码并且假定系统时钟为100MHz时,则只需四行代码就可以轻松完成时序约束文件,如下所示:
NET sys_clk_bufg TNM_NET =
sys_clk_bufg;
TIMESPEC TS_sys_clk_bufg = PERIOD
sys_clk_bufg 10 ns HIGH 50%;
OFFSET = IN 6 ns BEFORE sys_clk;
OFFSET = OUT 6 ns AFTER sys_clk;
请注意:赛灵思FPGA中I/O注册逻辑的建立与保持时间具有很高的固定性,在一个封装中切勿有太大更改。但是,我们仍然采用它们,主要用作可确保设计符合其系统参数的验证步骤。

相关帖子

沙发
uiodh|  楼主 | 2013-1-31 10:27 | 只看该作者
三步简单操作
仅需遵循以下三步简单操作,设计人员即可轻松实施可靠的代码。
• 切勿让综合工具猜测您的预期。采用赛灵思原语对所有 I/O 引脚和关键逻辑进行明确定义。确保定义 I/O 引脚的电气特性;
• 确保逻辑 100% 同步,并且让所有逻辑参考主时钟域;
• 应用时序约束确保时序收敛。
只要遵循上述三个步骤,您就能够消除综合与时序导致的差异。扫除这两个主要障碍会让您获得具有100%可靠性的代码。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

95

帖子

0

粉丝