门控时钟警告

时间:2015-05-10 18:17:51

标签: vhdl

我是涉及VHDL物理描述代码的所有内容的新手,我有一个大学项目要完成(在Nexys2或Nexys3板上有四个不同的文本动画)并且我不断收到此警告消息:

  

警告:Xst:737 - 找到信号的7位锁存器。锁存器可以从不完整的case或if语句生成。我们不建议在FPGA / CPLD设计中使用锁存器,因为它们可能会导致时序问题   警告:Xst:737 - 找到信号的7位锁存器。锁存器可以从不完整的case或if语句生成。我们不建议在FPGA / CPLD设计中使用锁存器,因为它们可能会导致时序问题   警告:Xst:737 - 找到信号的7位锁存器。锁存器可以从不完整的case或if语句生成。我们不建议在FPGA / CPLD设计中使用锁存器,因为它们可能会导致时序问题   警告:Xst:737 - 找到信号的7位锁存器。锁存器可以从不完整的case或if语句生成。我们不建议在FPGA / CPLD设计中使用锁存器,因为它们可能会导致时序问题   警告:PhysDesignRules:372 - 门控时钟。时钟网temp_reg1_not0001由组合引脚提供。这不是好的设计实践。使用CE引脚控制数据加载到触发器中   警告:PhysDesignRules:372 - 门控时钟。时钟网temp_reg3_not0001由组合引脚提供。这不是好的设计实践。使用CE引脚控制数据加载到触发器中   警告:PhysDesignRules:372 - 门控时钟。时钟网temp_reg2_not0001由组合引脚提供。这不是好的设计实践。使用CE引脚控制数据加载到触发器中   警告:PhysDesignRules:372 - 门控时钟。时钟网temp_reg4_not0001由组合引脚提供。这不是好的设计实践。使用CE引脚控制数据加载到触发器中。

以下是所有源文件的链接(我在Ise Design Suite 14.7中工作) http://www.fileshare.ro/e31590660

编辑:不幸的是,我花了差不多半天时间,我仍然无法准确找出问题所在。 我只能非常粗略地说,这是在下面的代码(第73行和第7行)的过程中。

 library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Folosim mai jos pachetul nostru
use work.Constante_si_componente.all;          

entity Optiune1 is   
    port(
    clk_50M:in std_logic;
    reset:in std_logic;
    catozi: out std_logic_vector(0 to 6);
    anozi: out std_logic_vector(0 to 3);
    opt1, opt2, opt3, opt4: in std_logic);
end entity;

architecture Behavioral of Optiune1 is   

-- Instantierea semnalelor locale
signal local_clk_1Hz: std_logic;
signal local_clk_1Khz: std_logic;  
signal adresa: integer range 0 to nr_cuvinte_distincte-1;       
signal sec_4: integer range 0 to limita_sup:=0; -- Numara exact 5 secunde
signal cuvant: std_logic_vector(lungime_cuvinte-1 downto 0);   
signal reg1, reg2, reg3, reg4: std_logic_vector(0 to 6):=(others=>'0');  
signal temp_reg1, temp_reg2, temp_reg3, temp_reg4: std_logic_vector(0 to 6) := (others=> '0');

-- Declarare componente   
component ROM 
    port (addr : in integer range 0 to nr_cuvinte_distincte-1;
          data: out std_logic_vector(lungime_cuvinte-1 downto 0));
end component ROM;      
component numarator 
    port(reset: in std_logic;
         clk: in std_logic; 
         limita_numarare: in integer;
         count: out integer range 0 to limita_sup);

end component; 
component registru
    port(clk_1Hz: in std_logic;
         reset: in std_logic;
         write_mode: in std_logic;
         input: in std_logic_vector(0 to 6);
         output: out std_logic_vector(0 to 6));
end component; 
component RRate 
    port(clk_1KHz: in std_logic;
    reg1, reg2, reg3, reg4: in std_logic_vector(0 to 6);
    catozi: out std_logic_vector(0 to 6);
    b:out std_logic_vector(0 to 3));
end component;

begin               
    -- Instantiem divizoarele de tact
    COMP_CLOCK_tat: divizor port map(clk_50M=>clk_50M, reset => reset, clk_1Hz => local_clk_1Hz, clk_1KHz=>local_clk_1KHz);


    -- Instantiem numaratorul
    Numarator_1: numarator port map(reset => reset, clk => local_clk_1Hz, limita_numarare => nr_cuvinte_distincte-1, count => adresa);      
    Numarator_2: numarator port map(reset => reset, clk => local_clk_1Hz, limita_numarare => 4, count => sec_4);

    -- Instantiem memoria
    Memorie1: ROM port map(addr => adresa, data => cuvant);

    -- Instantiem registrul
    Registrul_1: registru port map(local_clk_1Hz, reset, '1', temp_reg1, reg1);   
    Registrul_2: registru port map(local_clk_1Hz, reset, '1', temp_reg2, reg2);
    Registrul_3: registru port map(local_clk_1Hz, reset, '1', temp_reg3, reg3);
    Registrul_4: registru port map(local_clk_1Hz, reset, '1', temp_reg4, reg4);  

    -- Instantiem refresh rate-ul de la anozi
    Refresh_Rate: RRate port map (local_clk_1KHz, reg1, reg2, reg3, reg4, catozi, anozi);

    process(opt1, opt2, opt3, opt4, local_clk_1Hz, temp_reg1, temp_reg2, temp_reg3, temp_reg4, cuvant, sec_4) 
    begin
        if(opt1='1')and(opt2='0')and(opt3='0')and(opt4='0')and(local_clk_1Hz='1') then     
            temp_reg1 <= cuvant;
            temp_reg2 <= temp_reg1;
            temp_reg3 <= temp_reg2;
            temp_reg4 <= temp_reg3;         
        elsif(opt1='0')and(opt2='1')and(opt3='0')and(opt4='0')and(local_clk_1Hz='1') then
            temp_reg4 <= cuvant;
            temp_reg3 <= temp_reg4;
            temp_reg2 <= temp_reg3;
            temp_reg1 <= temp_reg2; 
        elsif(opt1='0')and(opt2='0')and(opt3='1')and(opt4='0')and(local_clk_1Hz='1') then 
            if sec_4 = 0 then 
                temp_reg1 <= cuvant;
            elsif sec_4 = 1 then 
                temp_reg2 <= cuvant;
            elsif sec_4 = 2 then
                temp_reg3 <= cuvant;
            elsif sec_4 = 3 then
                temp_reg4 <= cuvant;
            elsif sec_4 = 4 then
                temp_reg1 <= "1111111"; 
                temp_reg2 <= "1111111";
                temp_reg3 <= "1111111";
                temp_reg4 <= "1111111";
            end if;
       elsif(opt1='0')and(opt2='0')and(opt3='0')and(opt4='1')and(local_clk_1Hz='1') then 
            if sec_4 = 0 then 
                temp_reg1 <= cuvant;
            elsif sec_4 = 1 then            
                temp_reg2 <= cuvant;
                temp_reg1<="1111111";
            elsif sec_4 = 2 then
                temp_reg3 <= cuvant;
                temp_reg2<="1111111";
            elsif sec_4 = 3 then
            temp_reg4 <= cuvant;
            temp_reg3<="1111111";
            elsif sec_4 = 4 then
                temp_reg1 <= "1111111"; 
                temp_reg2 <= "1111111";
                temp_reg3 <= "1111111";
                temp_reg4 <= "1111111";
            end if;
        else
            temp_reg1 <= (others => '0');
            temp_reg2 <= (others => '0');
            temp_reg3 <= (others => '0');
            temp_reg4 <= (others => '0');           
        end if;
    end process;

end architecture Behavioral;

上次编辑:我昨天必须上交项目,它在Nexys2 FPGA板上按预期运行,我将David Koontz的多路复用器代码添加到“未来”开发“项目文档的一部分。

非常感谢你的帮助:)

2 个答案:

答案 0 :(得分:1)

temp_reg1

这可能是错的。由于您的流程是组合式的,因此temp_reg1的分配将再次触发流程,这会将temp_reg2的新值分配给cuvant,依此类推。基本上,这会将temp_regs分配给所有4 regx,但我不确定XST是否可以正确处理组合环回。

这可能不是你想要的。通常,这种过程会使用temp_regx分配给temp_reg1 <= cuvant; temp_reg2 <= reg1; temp_reg3 <= reg2; temp_reg4 <= reg3; ,这可能是您想要的:

if sec_4 = 0 then 
    temp_reg1 <= cuvant;
elsif sec_4 = 1 then            
    temp_reg2 <= cuvant;
    temp_reg1<="1111111";
elsif sec_4 = 2 then
    temp_reg3 <= cuvant;
    temp_reg2<="1111111";
elsif sec_4 = 3 then
temp_reg4 <= cuvant;
temp_reg3<="1111111";
elsif sec_4 = 4 then
   temp_reg1 <= "1111111"; 
   temp_reg2 <= "1111111";
   temp_reg3 <= "1111111";
   temp_reg4 <= "1111111";
end if;

正如David Koontz所指出的,这段代码负责锁存器:

temp_reg2

在组合过程中,过程中分配的每个信号必须在过程的每个路径中分配,否则您将获得一个锁存器。在这种情况下,例如,sec_4 = 0时未分配btnAdd.setOnClickListener(new OperationClick(Add).listenerOn(this));

答案 1 :(得分:1)

在翻译完所有罗马尼亚名称和评论并注意到temp_reg1 - temp_reg4是注册表的输入后,它不会显示您想要的锁定。

无意推断的锁存器是由于缺少完整的条件分配覆盖范围,并且无法保证组合时钟(或锁存器使能)由于通过改变数量的“门”而导致的延迟差异而无毛刺。目标设备中的等价物,&#39; wire&#39;由于放置而导致的延迟以及上升和下降时间的差异。防止锁存需要在case语句中的每个条件或选项下进行赋值,基本上是可达的elseothers

Jonathan注意到由影响模拟的灵敏度列表引起的模拟循环。摆脱敏感性列表问题可以通过将过程分解为单独的多路复用器来完成。

这是两个问题的示例解决方案。它是用并发信号赋值语句实现的。

我添加了组件divizor的声明以供分析(它可能位于非包含的包Constante_si_componente中)。

将三个必要声明(nr_cuvinte_distinctelimita_suplungime_cuvinte)生成到虚拟包constante_si_componente之后,我替换了流程声明。

我将以下本地信号实例添加为架构声明项:

-- added declarations

    component divizor is
        port (
            clk_50M:    in  std_logic;
            reset:      in  std_logic;
            clk_1Hz:    out std_logic;
            clk_1KHz:   out std_logic
        ) ;
    end component;

    signal some_cond0:     std_logic;
    signal some_cond1:     std_logic;
    signal some_cond2:     std_logic;
    signal some_cond3:     std_logic;

begin

这些取代了未标记过程中指定的外部if语句条件:

-- new concurrent signal assignment statements:

    some_cond0 <= opt1 and not opt2 and not opt3 and not opt4 and local_clk_1Hz;

    some_cond1 <= not opt1 and opt2 and not opt3 and not opt4 and local_clk_1Hz;

    some_cond2 <= not opt1 and not opt2 and opt3 and not opt4 and local_clk_1Hz;

    some_cond3 <= not opt1 and not opt2 and not opt3 and opt4 and local_clk_1Hz;

这些可以被命名以反映条件所代表的含义。看起来您可以将二进制编码opt1opt4分成两个信号,它们是独占的。

这个想法主要是为了简化多路复用器描述。

使用条件信号分配实现多路复用器:

MUX1: 
    temp_reg1 <= cuvant    when  some_cond0 = '1' else
                 temp_reg2 when  some_cond1 = '1' else 
                 cuvant    when  (some_cond2 = '1' or some_cond3 = '1') and
                                 sec_4 < 4                                 else
                 "1111111" when (some_cond2 = '1' or some_cond3 = '1')  and
                                 sec_4 = 4                                 else
                 (others => '0');
MUX2:                
    temp_reg2 <= temp_reg1 when  some_cond0 = '1' else
                 temp_reg3 when  some_cond1 = '1' else 
                 cuvant    when  (some_cond2 = '1' or some_cond3 = '1') and
                                 sec_4 < 4                                 else
                 "1111111" when (some_cond2 = '1' or some_cond3 = '1')  and
                                 sec_4 = 4                                 else
                 (others => '0');
MUX3:                
     temp_reg3 <= temp_reg2 when  some_cond0 = '1' else
                  temp_reg4 when  some_cond1 = '1' else 
                  cuvant    when  (some_cond2 = '1' or some_cond3 = '1') and
                                  sec_4 < 4                                 else
                  "1111111" when (some_cond2 = '1' or some_cond3 = '1')  and
                                  sec_4 = 4                                 else
                  (others => '0');  
MUX4:                 
    temp_reg4 <= temp_reg3 when  some_cond0 = '1' else
                 cuvant    when  some_cond1 = '1' else 
                 cuvant    when  (some_cond2 = '1' or some_cond3 = '1') and
                                  sec_4 < 4                                 else
                 "1111111" when (some_cond2 = '1' or some_cond3 = '1')  and
                                  sec_4 = 4                                 else
                 (others => '0');    

在多路复用器分离的情况下,没有敏感列表项导致掉线, 始终 分配 - 每个多路复用器中的最终else

您可以在条件赋值语句中进行各种优化,此示例旨在可追溯到原始进程。

如果op1op4在两个信号上编码为选择而local_clk_1Hz用作启用,则可以实例化四个4:1多路复用器lungime_cuvinte

在修改您的设计后,我们对其进行了分析,但没有divizorROMnumaratorregistruRRate的实体/体系结构对,我无法&#39 ;精心设计或模拟您的设计。

<强>附录

我发生故障并下载了您的RAR,清理了我的修改后的问题代码副本以使用您的标题包。这一切都进行了分析,尽管我删除了一些不需要的使用条款。

详细说明但是numarator中存在运行时模拟错误,由inter增加超出count的范围引起,这也表示您没有先模拟这个

整数(inter中的numarator)的默认值是左边界(通常为-2147483647)。在初始化期间,将对countrange 0 to limita_sup)进行分配,这将导致绑定检查失败。

signal inter: integer; -- acest semnal chiar e intermediar fiindca nu prea

应该是positive而不是整数,所以默认值在count的范围内,或者应该在count' bounds ( 0`中提供默认值。