Прежде всего, вы управляете внешними часами и хотите обработать их с вашими внутренними часами 1 МГц, для этого приложения вы должны использовать блок синхронизации.
Я буду действовать следующим образом. Управляйте внешним сигналом SYN C как часами и используйте его для подсчета восходящего_размера, другой совет - избегать подсчета std_logic_vector (использование целого числа для подсчета делает код более читабельным)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity SYNC_detection1 is
Port ( SYNC : in STD_LOGIC;
EDGE : out STD_LOGIC;
OUTPUT : out STD_LOGIC;
BITSOUT : out STD_LOGIC_VECTOR (3 downto 0)
);
end SYNC_detection1;
architecture workingarchi of SYNC_detection1 is
signal SYNC_edge : std_LOGIC := '0';
signal TEMP : std_LOGIC := '0';
signal counter : integer := 0;
begin
SYNC_edge_p : process(SYNC)
begin
SYNC_edge <= '0';
if (rising_edge(SYNC)) then
counter <= counter + 1;
SYNC_edge <= '1';
if (counter = 0) then
TEMP <= '1';
end if;
end if;
end process;
OUTPUT <= TEMP;
BITSOUT <= std_logic_vector(to_unsigned(counter, BITSOUT'length));
EDGE <= SYNC_edge;
end workingarchi;
С этим Реализация Теперь у вас есть выходные сигналы в тактовой области 4 кГц, вам просто нужно добавить блок синхронизации для каждой выходной линии с тактовой частотой источника 4 кГц и тактовой частотой назначения 1 МГц.
Для блока синхронизации просто в качестве ссылки я пишу следующий блок, который может синхронизировать ребро:
library ieee;
use ieee.std_logic_1164.all;
entity edge_sync is
port(
data : in std_logic;
clk_src : in std_logic;
clk_dst : in std_logic;
line_out: out std_logic
);
end edge_sync;
architecture beha of edge_sync is
component ff_D is
port(
lineD : in std_logic;
clk : in std_logic;
lineQ : out std_logic
);
end component ff_D;
signal input_s : std_logic := '0';
signal meta : std_logic:= '0';
signal Q2_D3 : std_logic:= '0';
signal Q3 : std_logic:= '0';
begin
FFsrc : ff_D port map (
lineD => input_s,
clk => clk_src,
lineQ => meta
);
FFdst1 : ff_D port map(
lineD => meta,
clk => clk_dst ,
lineQ => Q2_D3
);
FFdst2 : ff_D port map(
lineD => Q2_D3,
clk => clk_dst ,
lineQ => Q3
);
input_s <= data;
line_out <= (not Q3) and Q2_D3;
end beha;
Но в режиме онлайн вы можете найти другие реализации.
Из вашего кода:
SYNC_edge <= не SYNC_reg и SYNC; </p>
Эта строка может работать, только если SYN C изменяется между передними фронтами CLK. Вы уверены, что не генерируете 2 такта синхронно? Если 2 такта генерируются с нулевой фазой, так как они кратны, вы никогда не получите границу между нарастающими фронтами CLK, в результате чего вы не увидите изменения SYNC_edge.
PS Вы столкнулись с двумя основными fpga предметы, пересечение области часов и управление метастабильностью, я предлагаю вам изучить теоретический материал об этих аргументах. Это может помочь вам сосредоточиться на аппаратных аспектах, а также на кодировании VHDL.
С уважением