繁体   English   中英

VHDL-给触发器加一个变量?

[英]VHDL - Clock a flip flop with a variable?

我已经在工作中继承了一些旧的VHDL,并且一直在试图解决问题。 首先,我想说我对Verilog更有经验,但是在尝试解决此问题时已经使用VHDL。

因此,我们有一款自2011年以来一直运行良好的产品。但是,我们需要更换FPGA,因此我们正在移植代码。 此代码的高级观点是FPGA在板载闪存中为CPU存储了引导加载程序。 上电时,CPU读取FPGA以提取引导加载程序。 在我们的旧设计上,它工作正常。 在新设计中,它在寒冷时不起作用,在温暖温度下也不是100%可靠的。

我注意到,很多代码是按照我认为奇怪的方式完成的,其中触发器是用信号而不是时钟来计时的。 一个例子:

process( N_RESET, DATA_READ, START_ADDRESS, END_ADDRESS )
begin
    if( N_RESET = '0' ) then
        ADDR_TMP    <= START_ADDRESS;

    elsif( DATA_READ'event and (DATA_READ='0') ) then
        if( ADDR_TMP <= END_ADDRESS ) then
            ADDR_TMP <= ADDR_TMP + "10";
            incremented_tmp <= incremented_tmp xor '1';

        end if;
    end if;
end process;

因此,生成的RTL最终是由DATA_READ计时的触发器。 数据读取是来自CPU的读取使能信号。 CPU试图读取以读取该寄存器。

这是做事的有效方法吗? 我自己真的不喜欢使用读取使能作为时钟的想法。 我在Verilog中编写了一个使用时钟来检测DATA_READ的上升沿的代码:

always@(posedge CLK, negedge RESETn )
begin
    if(RESETn  == 1'b0) begin        

    end else begin


                last_usr_read_n <= usr_read;
                // Next state logic, only transition on de-assertion of usr_read
                if (last_usr_read_n == 1'd0 && usr_read == 1'd1) begin
                    // check next state logic
                    envm_internal_address <= envm_internal_address + 18'h2; // incrmeent address counter
                    incremented<= incremented^ 1'b1;

                end
        endmodule 

我注意到,在执行过程中,VHDL停止更改cremented_tmp,而我的Verilog代码继续按预期执行。

我们面临的主要问题是设计在寒冷时无法正常工作。 我不知道为什么。 该设计中有一堆闩锁,我已尽力去除了。 剩下的就是这样的代码(还有很多)。 我的问题是:这是给触发器计时的有效方法吗? 是否会引起我们所看到的意外问题?

谢谢,尼克

VHDL代码在DATA_READ信号上创建一个生成的时钟,这与等效的Verilog代码不同。 尽管从某种意义上来说,这是“有效的”,但可以综合使用,如果不能适当地加以限制,则可能会导致计时问题和边缘行为,例如您在冷热天气中看到的情况。 首选的解决方案是用同步边沿检测电路替换生成的时钟,就像您在Verilog代码中所做的一样。

不幸的是,如果您有很多需要清理的代码,我不知道一种自动化的方法。 如果这些代码的代码遵循相同的通用结构,则可以尝试进行搜索和替换。 我建议开发一个可靠的回归测试套件(如果您还没有的话),以验证您的更改没有任何不受欢迎的副作用。

另外,您可以尝试在布局布线工具中识别和约束所有生成的时钟,并要特别注意在时钟域交叉点的保持时间。 特别是,如果END_ADDRESS和DATA_READ在同一时钟沿启动,则信号之间将存在竞争状态,需要通过增加延迟来解决这些信号。 但是,如果您打算将来重用此代码,则最好在RTL中对其进行修复。

该代码是一团糟-转储,然后重新开始。 关于它的一切都是危险信号。 具体问题:

  1. 检查CPU数据表中的DATA_READ如果不能保证其单调性,则不能用作时钟。 它可能仅具有保证的设置并相对于其他信号保持,因此它可以在其他时间执行所需的任何操作,从而可能为您的代码计时。
  2. 请参阅TJ的答案。 还请注意,如果原始作者使用许多其他信号来执行此操作,则P&R软件可能未将DATA_READ分配给时钟网,并且FPGA的时钟网已用完
  3. incremented_tmp _tmp在时钟分支中分配,但在异步复位分支中未分配。 这是自找麻烦-它必须在N_RESET为低且有时钟沿时保持,因此您有闩锁行为,并且N_RESET相对于DATA_READ的时序存在问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM