简体   繁体   English

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

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

I've inherited some legacy VHDL at work and have been banging my head against the wall trying to figure out an issue. 我已经在工作中继承了一些旧的VHDL,并且一直在试图解决问题。 First let me say that I'm more experienced with Verilog but have been plugging away with VHDL for awhile trying to fix this issue. 首先,我想说我对Verilog更有经验,但是在尝试解决此问题时已经使用VHDL。

So we have a product that has been working fine since 2011. However, we needed to change FPGAs, so we are in the middle of porting our code. 因此,我们有一款自2011年以来一直运行良好的产品。但是,我们需要更换FPGA,因此我们正在移植代码。 A high level view of this code is that the FPGA stores a bootloader for the CPU in the on board flash. 此代码的高级观点是FPGA在板载闪存中为CPU存储了引导加载程序。 At power on, the CPU reads the FPGA to extract the bootloader. 上电时,CPU读取FPGA以提取引导加载程序。 On our old design it worked fine. 在我们的旧设计上,它工作正常。 On the new design it doesn't work when cold, and it is also not 100% reliable at warm temperatures either. 在新设计中,它在寒冷时不起作用,在温暖温度下也不是100%可靠的。

I noticed that a lot of the code is done what I would consider strangely, where flip flops are clocked with signals, rather than clocks. 我注意到,很多代码是按照我认为奇怪的方式完成的,其中触发器是用信号而不是时钟来计时的。 An example: 一个例子:

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;

So the RTL that that generates ends up being a flip flop that is clocked by DATA_READ. 因此,生成的RTL最终是由DATA_READ计时的触发器。 Data read is a read enable signal coming from a CPU. 数据读取是来自CPU的读取使能信号。 The CPU is trying to read to read this register. CPU试图读取以读取该寄存器。

Is this a valid way to do things? 这是做事的有效方法吗? I don't really like the idea of using a read enable as a clock myself. 我自己真的不喜欢使用读取使能作为时钟的想法。 I wrote one in Verilog that uses a clock to detect the rising edge fo DATA_READ: 我在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 

I noticed that during execution the VHDL stops changing incremented_tmp, whereas my verilog code continues executing as expected. 我注意到,在执行过程中,VHDL停止更改cremented_tmp,而我的Verilog代码继续按预期执行。

The main issue we are having is that the design doesn't work when it's cold. 我们面临的主要问题是设计在寒冷时无法正常工作。 I'm not sure why. 我不知道为什么。 The design had a bunch of latches in it that I've done my best to remove. 该设计中有一堆闩锁,我已尽力去除了。 All that's remaining is code like this (and there's a lot of it). 剩下的就是这样的代码(还有很多)。 My question is: Is this a valid way to clock a flip flop? 我的问题是:这是给触发器计时的有效方法吗? Could it cause unexpected issues like we are seeing? 是否会引起我们所看到的意外问题?

Thanks, Nick 谢谢,尼克

The VHDL code creates a generated clock on the DATA_READ signal, not unlike the equivalent Verilog code would do. VHDL代码在DATA_READ信号上创建一个生成的时钟,这与等效的Verilog代码不同。 While this is certainly "valid" in the sense that it is synthesizable, if not constrained properly, this could create timing issues and marginal behavior like what you're seeing at cold and hot. 尽管从某种意义上来说,这是“有效的”,但可以综合使用,如果不能适当地加以限制,则可能会导致计时问题和边缘行为,例如您在冷热天气中看到的情况。 The preferred solution is to replace the generated clocks with a synchronous edge-detect circuit, like what you've done in your Verilog code. 首选的解决方案是用同步边沿检测电路替换生成的时钟,就像您在Verilog代码中所做的一样。

Unfortunately, I don't know a good way to automate this if you have a lot of code that needs to be cleaned up. 不幸的是,如果您有很多需要清理的代码,我不知道一种自动化的方法。 If the code follows the same general structure for these constructs, you can try a search-and-replace. 如果这些代码的代码遵循相同的通用结构,则可以尝试进行搜索和替换。 I recommend developing a solid regression test suite, if you haven't already, to verify your changes don't have any unwelcome side-effects. 我建议开发一个可靠的回归测试套件(如果您还没有的话),以验证您的更改没有任何不受欢迎的副作用。

Alternatively, you can try to identify and constrain all the generated clocks in the place-and-route tool, paying careful attention to hold time at the clock domain crossings. 另外,您可以尝试在布局布线工具中识别和约束所有生成的时钟,并要特别注意在时钟域交叉点的保持时间。 In particular if END_ADDRESS and DATA_READ are launched on the same clock edge, you'll have a race condition between the signals that will need to be resolved by adding delay. 特别是,如果END_ADDRESS和DATA_READ在同一时钟沿启动,则信号之间将存在竞争状态,需要通过增加延迟来解决这些信号。 If you plan to reuse this code in the future, though, you're better off fixing it in the RTL. 但是,如果您打算将来重用此代码,则最好在RTL中对其进行修复。

The code is a mess - dump it, start again. 该代码是一团糟-转储,然后重新开始。 Everything about it is a red flag. 关于它的一切都是危险信号。 Specific problems: 具体问题:

  1. Check the CPU datasheet for DATA_READ - it's not usable as a clock if it's not guaranteed monotonic. 检查CPU数据表中的DATA_READ如果不能保证其单调性,则不能用作时钟。 It probably just had a guaranteed setup and hold relative to other signals, so it can do whatever it wants at other times, potentially clocking your code. 它可能仅具有保证的设置并相对于其他信号保持,因此它可以在其他时间执行所需的任何操作,从而可能为您的代码计时。
  2. See TJ's answer. 请参阅TJ的答案。 Note also that your P&R software may not have assigned DATA_READ to a clock net if the original author did this with lots of other signals, and you've run out of clock nets in your FPGA 还请注意,如果原始作者使用许多其他信号来执行此操作,则P&R软件可能未将DATA_READ分配给时钟网,并且FPGA的时钟网已用完
  3. incremented_tmp is assigned in the clock branch, but not the async reset branch. incremented_tmp _tmp在时钟分支中分配,但在异步复位分支中未分配。 This is asking for trouble - it has to hold when N_RESET is low and there's a clock edge, so you've got latch behaviour, and issues with the timing of N_RESET relative to DATA_READ . 这是自找麻烦-它必须在N_RESET为低且有时钟沿时保持,因此您有闩锁行为,并且N_RESET相对于DATA_READ的时序存在问题。

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

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