2011-05-01 18 views
0

我有下面的代码是我的数字时钟的一部分:如何使VHDL输出信号无国籍

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
use ieee.std_logic_unsigned.all; 

-- Seconds counter 
entity SecCounter is 
    port( 
      s_enable: in std_logic; 
      s_load: in std_logic; -- When high, sets this counter to the value in the  data inputs 
      s_clk: in std_logic; -- Clock 
      s_input: in std_logic_vector(5 downto 0); -- Data inputs 
      s_output: out std_logic_vector(5 downto 0); --Outputs 
      s_wrap: out std_logic 
     ); 
    end SecCounter; 

architecture imp of SecCounter is 
    -- Intermediate signal to mainpulate the seconds as integer 
    signal sec: integer range 0 to 60 := 22; 

    begin 
     s_output <= std_logic_vector(to_unsigned(sec,6)); -- Assign the input to the binary  value of sec 

     process(s_clk, s_load, s_enable) -- If clk, enable, or load is changed 
     begin 
      s_wrap <= '0'; -- Clear the wrap 

      if (s_enable = '0' and s_load = '1') then -- Set the clock 
       sec <= to_integer(unsigned(s_input)); 
      elsif (s_enable = '1' and rising_edge(s_clk)) then -- Increment the counter 
       sec <= sec + 1; 
      end if; 

      if sec = 60 then -- Restart counter and toggle the next counter 
       sec <= 0; 
       s_wrap <= '1'; 
      end if; 
     end process; 
end imp; 

s_wrap充当使下一个柜台。我想要做的是,如果这个计数器等于60,我想为单个时钟边缘启用下一个计数器。我试图通过将s_wrap设置为true,然后在下一个时钟边沿将其设置为false;但是,它不会改变。有没有办法让is_wrap无状态?如果不是,我该如何解决这个问题?

+0

您正在使用'ieee.std_logic_unsigned .all',这有几个问题。此外,它与您正在使用的'numeric_std'冲突。只要删除'std_logic_unsigned'使用条款。 – Philippe 2011-05-02 07:48:29

回答

2

你是秒rising_edge(CLK)条款以外的分配值。如果s_enable = 0且s_load = 0,则不会将任何内容分配给sec。这些事实都使秒成为异步信号。如果你解决了这两个问题,那么描述的问题应该消失。

而奥利查尔斯沃斯有一个关于检查59而不是60的好处。那么你不必在你的范围内人为地包含不存在的60。并且将sec初始化为一个值是没有意义的。您应该在重置条款中初始化它。

由于您正在异步读取s_enable,s_load和s_input,您可能还有其他问题。这通常只对复位信号完成。

+2

纠正点:信号的初始化**是有意义的**,前提是得到综合工具的支持。我建议在声明时初始化信号,不要使用复位,特别是如果不需要复位。这可以在地图和P&R期间导致更好的逻辑利用率。在Xilinx器件的世界中,在器件配置/引导中,所有FF都有一个已知状态,可以使用信号初始化进行配置。在此参考中搜索“初始化”:http://www.xilinux.com/support/documentation/sw_manuals/xilinx13_1/xst_v6s6.pdf – Josh 2011-05-02 19:49:16

1

[免责声明:我不是伟大的VHDL,所以我不能对语法建议]

我想你想断言s_wrapsec达到,不。这样,在下一个时钟边沿,分钟计数器将看到s_wrap = 1并递增,同时该计数器输出再次变为0。

你想要的东西,这样我觉得

process(s_clk, s_load, s_enable) -- If clk, enable, or load is changed 
begin 

    if (s_enable = '0' and s_load = '1') then -- Set the clock 
     sec <= to_integer(unsigned(s_input)); 
    elsif (s_wrap = '1') then -- Wrap 
     sec <= 0; 
    elsif (s_enable = '1' and rising_edge(s_clk)) then -- Increment the counter 
     sec <= sec + 1; 
    end if; 

end process; 

s_wrap <= '1' when sec = 59 else '0'; 
0

我会做的是申报秒作为过程变量,作为变量立即更新:

process(s_clk, s_load, s_enable) 
variable v_sec : integer range 0 to 60; 
begin 
if reset = '1' then 
    v_sec := 0; 
    s_sec <= (others => '0'); 
    s_wrap <= '0'; 
elsif rising_edge(s_clk) then 
    s_output <= std_logic_vector(to_unsigned(v_sec,6)); 
    if s_enable = '1' then 
    v_sec := v_sec +1; 
    if v_sec = 60 then 
     v_sec:= 0; 
     s_wrap <= '1'; 
    else 
     s_wrap <= '0'; 
    end if; 
    else 
    s_wrap <= '0'; 
    end if; 
end if; 

如果这个模拟ModelSim中,证券交易委员会将去0,1,2,.. .58,59,0,1,2和s_wrap将等于1,每次秒等于0,除了第一次,当复位条件将其设置为0.