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;
我正在尝试编写代码来更改我的时钟频率。但输出始终为零...
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;