2016-03-10 94 views
0

线62:信号s不能合成,坏的同步描述。 当前软件 版本中不支持用于描述同步元素 (寄存器,内存等)的说明风格。VHDL:信号s不能合成

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity clock is 
    Port (start : in STD_LOGIC;      
      reset : in STD_LOGIC;      
      CLOCK : in STD_LOGIC;      
      setH, setM, setS : in STD_LOGIC;    
      alarmH, alarmM, alarmS : in STD_LOGIC; 
      Alarm_On : in STD_LOGIC;      
      Buzzer_Stop : in STD_LOGIC;     
      BUZZER : out STD_LOGIC;      
      hh, mm, ss : out INTEGER);     
end clock; 

architecture Behavioral of clock is 

signal h, m, s : INTEGER range 0 to 60 := 0; 
signal hA, mA, sA : INTEGER range 0 to 60 := 0; 
signal clk : std_logic :='0'; 
signal count : integer :=1; 

begin 

Frequency_Reducer : process(CLOCK) --Reducing Frequency From 40MHz to 1Hz 
begin 
    if rising_edge(CLOCK) then 
      count <= count + 1; 
     if(count = 20000000) then 
      clk <= not clk; 
      count <=1; 
     end if; 
    end if; 
end process; 

Clock_Logic : process(start, reset, clk) 
begin 
    if reset = '1' then 
     h <= 00; 
     m <= 00; 
     s <= 0; 
    end if; 

    if start = '1' then 
     if rising_edge(clk) then  --Clock Logic Start 
      s <= s + 1; 
     end if; 
    end if; 

     if s = 60 then 
      s <= 0; 
      m <= m + 1; 
     end if; 
     if m = 60 then 
      m <= 0; 
      h <= h + 1; 
     end if; 
     if h = 24 then 
      h <= 0; 
     end if;        --Clock Logic End 

    if setH = '1' then     --Set Time Logic Start 
     h <= h + 1; 
    end if; 
    if setM = '1' then 
     m <= m + 1; 
    end if; 
    if setS = '1' then 
     s <= s + 1; 
    end if;         -- Set Time Logic End 
end process; 

hh <= h; 
mm <= m; 
ss <= s; 

end Behavioral; 
+1

并非所有的任务,以's'是同步的上升沿时钟。而你的代码也不是闩锁的描述。请在支持的寄存器样式上查看综合工具手册。似乎低于复位的所有分配应该与时钟的上升沿同步。 –

+0

@MartinZabel我试过了,它没有解决问题 –

+0

使用一秒时钟不能设置时钟运行的秒数,这需要一个负载。您可以考虑使用寄存器从时钟加载的秒,分钟和小时,并通过一个按钮增加,完成后重新加载到时钟(设置模式)。额外的寄存器也可以用于报警。或者,您可以简单地重置秒并按照[vhdl手动时钟小时集](https://stackoverflow.com/questions/27207698/vhdl-manual-clock-hour-set)递增分钟和小时。检查答案,它显示了所有钟表并且合成合格。 – user1155120

回答

3

让我们来看看信号s只的任务:

Clock_Logic : process(start, reset, clk) 
begin 
    if reset = '1' then 
     s <= 0; 
    end if; 

    if start = '1' then 
     if rising_edge(clk) then  --Clock Logic Start 
      s <= s + 1; 
     end if; 
    end if; 

    if s = 60 then 
     s <= 0; 
    end if; 

    if setS = '1' then 
     s <= s + 1; 
    end if;         -- Set Time Logic End 
end process; 

在最后分配,您请求s递增时setS高,运行处理(恢复)。该过程在系统启动后以及每当灵敏度列表中的一个信号发生变化时开始执行。因此,您正在请求在三个信号start,resetclock的两个边沿上同步的触发器。我怀疑,这个增量应该只在时钟的上升沿来完成:

if rising_edge(clk) then  --Clock Logic Start 
     if setS = '1' then 
      s <= s + 1; 
     end if;         -- Set Time Logic End 
    end if; 

s异步复位时s达到60是可能的,但容易出错由于毛刺。 s是硬件中的多位信号。因此,当它增加时,即使最终值低于60,短时间内也可能等于60!您应该重置同步为0,当电流值是59.

s增量时start高,发生在时钟上升沿是好的,但综合工具往往要求重新安排该使得用于上升沿外if块检查:

if rising_edge(clk) then  --Clock Logic Start 
     if start = '1' then 
      s <= s + 1; 
     end if; 
    end if; 

最后,异步复位(或者设置)输入接口触发器始终具有较高优先级,则同步数据的输入。因此,你必须安排,要么是这样的:

Clock_Logic : process(reset, clk) 
begin 
    if reset = '1' then 
     -- asynchronous part 
     s <= 0; 
    elsif rising_edge(clk) then 
     -- synchronous part (add more conditions if required) 
     s <= s + 1; 
    end if; 
end process; 

或者这样说:

Clock_Logic : process(reset, clk) 
begin 
    if rising_edge(clk) then 
     -- synchronous part (add more conditions if required) 
     s <= s + 1; 
    end if; 
    if reset = '1' then 
     -- asynchronous part 
     s <= 0; 
    end if; 
end process; 

同步任务可能更加复杂。例如,如果你想同步重置计数器,当它到达59以及以其他方式增加它在信号setS高:

Clock_Logic : process(reset, clk) 
begin 
    if reset = '1' then 
     -- asynchronous part 
     s <= 0; 
    elsif rising_edge(clk) then 
     -- synchronous part 
     if s = 59 then 
      s <= 0; 
     elsif setS = '1' then 
      s <= s + 1; 
     end if; 
    end if; 
end process;