VHDL - 比较 IF 语句中的信号(整数)

VHDL - comparing signals (integers) in IF-statement

我正在尝试编写代码来更改我的时钟频率。但输出始终为零...

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;

我认为您在测试平台中更改 S 的速度太快了。我在您的测试台中更改了行以等待更长的时间,它似乎工作正常。

根据 Andy 的建议,我会将您设计的第 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