【问题标题】:VHDL Clock dividerVHDL 时钟分频器
【发布时间】:2014-04-22 13:25:03
【问题描述】:

我正在使用以下 VHDL 获取 100 Mhz 时钟并输出 25 Mhz 时钟。 :

process(clk, reset)
  variable count : integer range 0 to 2;
begin
  if (reset = '1') then
    clock_25MHz <= '0';
    count       := 0;
  elsif rising_edge(clk) then
    count := count+1;
    if(count >= 2) then
      clock_25MHz <= not clock_25MHz;
      count       := 0;
    end if;
  end if;
end process;

它给了我这个警告:

“WARNING:Xst:1293 - FF/Latch count_1 在 block 中有一个常数值 0。这个 FF/Latch 将在优化过程中被修整。”

我不明白为什么会这样。任何人都可以为我阐明这一点吗?谢谢!

【问题讨论】:

    标签: vhdl


    【解决方案1】:

    您不需要 2 位计数。一个触发器就足够了。

    如果您添加一个分配了计数的整数信号 CNT(允许我使用 ghdl 在波形上看到它):

     library ieee;
     use ieee.std_logic_1164.all;
    
     entity clk_div is
     end entity;
    
     architecture foo of clk_div is
         signal clk:            std_logic := '0';
         signal reset:          std_logic := '1';
         signal clock_25MHz:    std_logic;
         signal CNT:            integer;
    
    begin
    
    CLKDIV:
        process(clk,reset)
            variable count: integer range 0 to 2;   
        begin
            if (reset = '1') then
                clock_25MHz <= '0';
                count:=0;
            elsif rising_edge(clk) then
                count:=count+1;
                if(count>=2) then
                    clock_25MHz <= not clock_25MHz;
                    count:=0;
                end if;
            end if;
            CNT <= count;
          end process;
    CLOCK:
        process 
        begin
            wait for 5 ns;
            clk <= not clk;
            if Now > 200 ns then
                wait;
            end if;
        end process;
    UNRESET:
        process
        begin
            wait for 20 ns;
            reset <= '0';
            wait;
        end process;
    end architecture;
    

    你会发现:

    count 始终显示为 0 或 1,而不是 2 或 3,因为当它为 2 或更大时,您将其分配为 0。它永远不会在时钟边沿显示为 2。

    正确吗?为什么是的。如果您使用持续 4 100 Mhz 时钟的 clock_25MHz 以波形计时,则它可以完美运行。你的进程正在做一些不必要的事情,count 不需要 0 到 2 的范围,(需要两个触发器)。

    更改计数的评估顺序,以便在 count = 1 时切换时钟_25MHz,然后切换计数。将计数范围更改为 0 到 1 或更好,仍然使其类型为 std_logic。

         -- signal CNT:            integer;
         signal toggle_ff:      std_logic;
    
    begin
    
    CLKDIV:
        process(clk,reset)
            --variable count: integer range 0 to 2;
            variable toggle:  std_logic;
        begin
            if (reset = '1') then
                clock_25MHz <= '0';
                -- count:=0;
                toggle := '0';
            elsif rising_edge(clk) then
                -- count:=count+1;
                -- if(count>=2) then
                if toggle = '1' then
                    clock_25MHz <= not clock_25MHz;
                    -- count:=0; 
                end if;
                toggle := not toggle;
            end if;
            -- CNT <= count;
            toggle_ff <= toggle;
          end process;
    

    这给出了:

    您还可以在流程语句中使用信号而不是变量。在我的示例代码中,将 toggle_ff 重命名为 toggle,删除变量 toggle 声明并将信号赋值语句删除为 toggle_ff。这将无缝工作的原因是因为您在切换toogle FF 之前评估它的输出。

    【讨论】:

      【解决方案2】:

      由于count 中的状态由 Xilinx 实现为 FF/Latch,因此出现警告 变为 0, 1, 0, 1, ...,并且只有 count 的内部组合值 获取值 2,因此count 状态中的任何位 1 将始终为 0,因为 警告说“FF/Latch count_1 在块中有一个常量值 0”。

      您也可以看到这一点,因为可以通过减少“计数”来重写代码 范围为 0 到 1,如果 count 增量放在 if 内,例如:

      process(clk, reset)
        variable count : integer range 0 to 1;
      begin
        if (reset = '1') then
          clock_25MHz <= '0';
          count       := 0;
        elsif rising_edge(clk) then
          if (count = 1) then
            clock_25MHz <= not clock_25MHz;
            count       := 0;
          else
            count := count + 1;
          end if;
        end if;
      end process;
      

      但基于将 100 MHz 除以 4 的具体要求 到 25 MHz 时钟,创建中间 50 MHz 时钟可能更明显 而不是count,代码如下:

      process(clk, reset)
        variable clock_50MHz : std_logic;
      begin
        if (reset = '1') then
          clock_25MHz <= '0';
          clock_50MHz := '0';
        elsif rising_edge(clk) then
          clock_50MHz := not clock_50MHz;
          if clock_50MHz = '1' then
            clock_25MHz <= not clock_25MHz;
          end if;
        end if;
      end process;
      

      【讨论】:

        猜你喜欢
        • 2020-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-04
        • 1970-01-01
        • 1970-01-01
        • 2023-02-25
        • 1970-01-01
        相关资源
        最近更新 更多