2016-02-12 135 views
0

我正在尝试编写代码来改变我的时钟频率。但输出始终归零......VHDL - 比较IF语句中的信号(整数)

signal cycle_counter : integer := 0; 
signal HALFCYCLES : integer; 
signal MY_CLK1, temporal : std_logic :='0'; 

frequency_divider: process (Clk,cycle_counter, HALFCYCLES) 
begin 
    if rising_edge(Clk) then 
      cycle_counter <= cycle_counter + 1; 
      if cycle_counter = (HALFCYCLES-1) then 
       temporal <= NOT(temporal); 
       cycle_counter <= 0; 
      end if; 
    end if; 
     MY_CLK1 <= temporal; 
    end process frequency_divider; 

当我把HALFCYCLES-1而不是某个整数值,一切都工作得很好,但我需要这个信号是可变的。 我相信,问题在于比较,但无法检测到它。

我试图让HALFCYCLES一个变量,而不是信号,但是编译器是反对:)

的完整代码(主果阿 - 把在LED两个不同频率的动画和动画的类型,你应该选择。通过切换器(输入logic_vector S)

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity LED2 is 
    generic (FIFT : std_logic_vector (15 downto 0) := "1111111111111111"; 
     ZERO : std_logic_vector (15 downto 0) := "0000000000000000"); 
    Port (S : in STD_LOGIC_VECTOR (7 downto 0); 
      Clk : in STD_LOGIC; 
      R : in STD_LOGIC; 
      LED : out STD_LOGIC_VECTOR (7 downto 0)); 
end LED2; 

architecture Behavioral of LED2 is 
signal statement: std_logic_vector (7 downto 0); 
signal cycle_counter : integer := 0; 
signal CNT1, CNT2, CURCNT, CNT_NO : integer:= 0; 
signal HALFCYCLES : integer; 
signal MY_CLK1, MY_CLK2, temporal : std_logic :='0'; 

begin 

frequency_divider: process (Clk,cycle_counter, HALFCYCLES) begin 
    if rising_edge(Clk) then 
     cycle_counter <= cycle_counter + 1; 
    if cycle_counter = (HALFCYCLES-1) then --(HALFCYCLES-1) 
     temporal <= NOT(temporal); 
     cycle_counter <= 0; 
    end if; 
    end if; 
    MY_CLK1 <= temporal; 
    MY_CLK2 <= temporal; 
end process frequency_divider; 




counter1: PROCESS (MY_CLK1, R) 
BEGIN 
IF (MY_CLK1 = '1' AND MY_CLK1'EVENT) THEN 
    IF (R='1') THEN 
    CNT1 <=0; 
    ELSIF (CNT1 = 15) THEN 
     CNT1 <= 0; 
    ELSE 
     CNT1 <= CNT1 + 1; 
    END IF; 
END IF; 
END PROCESS counter1; 

counter2: PROCESS (MY_CLK2, R) 
BEGIN 
IF (MY_CLK2 = '1' AND MY_CLK2'EVENT) THEN 
    IF (R='1') THEN 
    CNT2 <=0; 
    ELSE 
    if (CNT2 = 15) then 
     CNT2 <= 0; 
     else 
     CNT2 <= CNT2 + 1; 
    end if; 
    END IF; 
END IF; 
END PROCESS counter2; 

freq_changer: PROCESS (CNT1, CNT2, S) 
BEGIN 
    IF (S(7) = '1') 
    THEN HALFCYCLES <= 50000000; CURCNT <= CNT1; CNT_NO <= 1;--1hz 
    ELSIF (S(6) = '1') 
    THEN HALFCYCLES <= 5000000; CURCNT <= CNT2; CNT_NO <= 2;--10hz 
    ELSIF (S(5) = '1') 
    THEN HALFCYCLES <= 500000; CURCNT <= CNT1; CNT_NO <= 1;--100hz 
    ELSIF (S(4) = '1') 
    THEN HALFCYCLES <= 50000;  CURCNT <= CNT2; CNT_NO <= 2;--1khz 
    ELSIF (S(3) = '1') 
    THEN HALFCYCLES <= 5000;  CURCNT <= CNT1; CNT_NO <= 1;--10khz 
    ELSIF (S(2) = '1') 
    THEN HALFCYCLES <= 500;   CURCNT <= CNT2; CNT_NO <= 2;--100khz 
    ELSIF (S(1) = '1') 
    THEN HALFCYCLES <= 50;   CURCNT <= CNT1; CNT_NO <= 1;--1mhz 
    ELSIF (S(0) = '1') 
    THEN HALFCYCLES <= 10;   CURCNT <= CNT2; CNT_NO <= 2;--5mhz 
    ELSE HALFCYCLES <= 5;   CURCNT <= CNT1; CNT_NO <= 1;--10mhz 
    END IF; 
END PROCESS freq_changer; 

main: PROCESS (CNT_NO, CURCNT) 
BEGIN 
c: CASE CNT_NO IS 
    WHEN 2 => 
counter2:CASE CURCNT IS 
     WHEN 0 => statement <= "00000001"; 
     WHEN 1 => statement <= "00000010"; 
     WHEN 2 => statement <= "00000100"; 
     WHEN 3 => statement <= "00001000"; 
     WHEN 4 => statement <= "00010000"; 
     WHEN 5 => statement <= "00100000"; 
     WHEN 6 => statement <= "01000000"; 
     WHEN 7 => statement <= "10000000"; 
     WHEN 8 => statement <= "10000000"; 
     WHEN 9 => statement <= "01000000"; 
     WHEN 10  => statement <= "00100000"; 
     WHEN 11  => statement <= "00010000"; 
     WHEN 12  => statement <= "00001000"; 
     WHEN 13  => statement <= "00000100"; 
     WHEN 14  => statement <= "00000010"; 
     WHEN 15  => statement <= "00000001"; 
     WHEN OTHERS => statement <= "00000000"; 
     END CASE counter2; 

    WHEN OTHERS => 
counter1:CASE CURCNT IS 
     WHEN 0 => statement <= "10000001"; 
     WHEN 1 => statement <= "01000010"; 
     WHEN 2 => statement <= "00100100"; 
     WHEN 3 => statement <= "00011000"; 
     WHEN 4 => statement <= "00011000"; 
     WHEN 5 => statement <= "00100100"; 
     WHEN 6 => statement <= "01000010"; 
     WHEN 7 => statement <= "10000001"; 
     WHEN 8 => statement <= "00011000"; 
     WHEN 9 => statement <= "00100100"; 
     WHEN 10  => statement <= "01000010"; 
     WHEN 11  => statement <= "10000001"; 
     WHEN 12  => statement <= "10000001"; 
     WHEN 13  => statement <= "01000010"; 
     WHEN 14  => statement <= "00100100"; 
     WHEN 15  => statement <= "00011000"; 
     WHEN OTHERS => statement <= "00000000"; 
     END CASE counter1; 
    END CASE c; 
    LED <= statement; 
END PROCESS main; 



end Behavioral; 

测试平台

LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 
USE ieee.Numeric_Std.all; 



ENTITY LED_controller_tb IS 
END LED_controller_tb; 

ARCHITECTURE behavior OF LED_controller_tb IS 

    -- Component Declaration for the Unit Under Test (UUT) 

    COMPONENT LED2 
    PORT(
     S : IN std_logic_vector(7 downto 0); 
     Clk : IN std_logic; 
     R : IN std_logic; 
     LED : OUT std_logic_vector(7 downto 0) 
     ); 
    END COMPONENT; 


    --Inputs 
    signal S : std_logic_vector(7 downto 0) := (others => '0'); 
    signal Clk : std_logic := '0'; 
    signal R : std_logic := '0'; 

     --Outputs 
    signal LED : std_logic_vector(7 downto 0); 

    -- Clock period definitions 
    constant Clk_period : time := 10 ns; 

BEGIN 

     -- Instantiate the Unit Under Test (UUT) 
    uut: LED2 PORT MAP (
      S => S, 
      Clk => Clk, 
      R => R, 
      LED => LED 
     ); 

    -- Clock process definitions 
    Clk_process :process 
    begin 
       Clk <= '0'; 
       wait for Clk_period/2; 
       Clk <= '1'; 
       wait for Clk_period/2; 
    end process; 


    -- Stimulus process 
    stim_proc: process 
    begin   
     -- hold reset state for 100 ns. 
      wait for Clk_period * 8;  

       S <= std_logic_vector(to_unsigned(to_integer(unsigned(S)) + 1, 8)); 

     -- insert stimulus here 

    end process; 

reset: PROCESS 
     BEGIN 
       WAIT FOR 1 us; 
       R <= '1'; 
       WAIT FOR 500 ns; 
       R <= '0'; 
     END PROCESS reset; 
END; 
+1

它看起来并不像你曾经分配'HALFCYCLES'。我建议使这个常量,例如:'常量HALFCYCLES:integer:= 16;' –

+0

我有另一个进程分配HALFCYCLES –

+0

不完整的例子。比较整数信号是可行的,但没有一个完整的例子,我们只能猜测它为什么不在这里。 http://stackoverflow.com/help/mcve –

回答

1

我认为你是在你的测试平台过于快速变化的S上。我CH在你的测试平台中的老化线等待更长的时间,它似乎工作正常。

所推荐的安迪,我将你的设计的26行改为

if cycle_counter >= (HALFCYCLES-1) then --(HALFCYCLES-1) 

这里的(修改)测试平台全面。我还添加了一个过程来停止模拟;否则,它运行永远:

LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 
USE ieee.Numeric_Std.all; 



ENTITY LED_controller_tb IS 
END LED_controller_tb; 

ARCHITECTURE behavior OF LED_controller_tb IS 

    -- Component Declaration for the Unit Under Test (UUT) 

    COMPONENT LED2 
    PORT(
     S : IN std_logic_vector(7 downto 0); 
     Clk : IN std_logic; 
     R : IN std_logic; 
     LED : OUT std_logic_vector(7 downto 0) 
     ); 
    END COMPONENT; 


    --Inputs 
    signal S : std_logic_vector(7 downto 0) := (others => '0'); 
    signal Clk : std_logic := '0'; 
    signal R : std_logic := '0'; 

     --Outputs 
    signal LED : std_logic_vector(7 downto 0); 

    -- Clock period definitions 
    constant Clk_period : time := 10 ns; 

BEGIN 

     -- Instantiate the Unit Under Test (UUT) 
    uut: LED2 PORT MAP (
      S => S, 
      Clk => Clk, 
      R => R, 
      LED => LED 
     ); 

    -- Clock process definitions 
    Clk_process :process 
    begin 
       Clk <= '0'; 
       wait for Clk_period/2; 
       Clk <= '1'; 
       wait for Clk_period/2; 
    end process; 


    -- Stimulus process 
    stim_proc: process 
    begin   
     -- hold reset state for 100 ns. 
      wait for Clk_period * 800; -- WAIT MUCH LONGER BEFORE CHANGING S ! 

       S <= std_logic_vector(to_unsigned(to_integer(unsigned(S)) + 1, 8)); 

     -- insert stimulus here 

    end process; 

reset: PROCESS 
     BEGIN 
       WAIT FOR 1 us; 
       R <= '1'; 
       WAIT FOR 500 ns; 
       R <= '0'; 
     END PROCESS reset; 

     STOP_SIM: process  -- OTHERWISE THE SIM RUNS FOREVER 
     begin 
      wait for Clk_period * 4000; 
      assert FALSE severity FAILURE; 
     end process; 
END; 

http://www.edaplayground.com/x/7XS

+0

你应该在'reset'过程结束时添加'wait;'。要停止模拟,只需停止'clk_process'中的时钟。 –