АБС, я подозреваю вас в том, что вы используете входной сигнал в качестве клока, а выходы с PLL в качестве данных. Примерно вот так:
Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity sampler is
port(
ref_clk : in std_logic;
probe : in std_logic
);
end sampler;
architecture pa3 of sampler is
signal clocks, clocks_reg : std_logic_vector(7 downto 0); -- 0, 45, 90, 135, 180, 225, 270, 315
signal counter, counter_reg : std_logic_vector(15 downto 0);
begin
pll_0 : pll port map (clk_in => ref_clk, c0=>clock(0), c90 =>clock(2));
pll_1 : pll port map (clk_in => ref_clk, c45=>clock(1), c135 =>clock(3));
clocks(4) <= not clocks(0);
clocks(5) <= not clocks(1);
clocks(6) <= not clocks(2);
clocks(7) <= not clocks(3);
process(clocks(0))
begin
if rising_edge(clocks(0)) then
counter <= counter+1;
end if;
end process;
process(probe)
begin
if rising_edge(probe) then
clocks_reg <= clocks;
counter_reg <= counter;
end if;
end process;
end pa3;
Считаю, что это не к добру, так как FPGA проектируются не для этого и специально сконструированные механизмы доставки клока не используются, как результат, точность доставки сигналов от PLL будет хуже возможной. Как не обкладывай их констрейнами, это не поможет.
Следует делать все наоборот, использовать 8 клоков и по каждому из них захватывать входной сигнал.
Код
gen_regs : for i in 0 to 7 generate
process(clocks(i))
begin
if rising_edge(clocks(i)) then
reg(i) <= D;
end if;
end process;
end generate;
Для существенного уменьшения вероятности сбоя можно применить два приема: последовательный перезахват рядом расположенными регистрами, не имеющими других потребителей (нужно поработать атрибутами или констрейнами) и голосование размноженного сигнала.
Код
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity sampler_channel is
port(
clk : in std_logic;
probe : in std_logic;
Q : out std_logic
);
end sampler_channel;
architecture pa3 of sampler_channel is
attribute syn_keep : boolean;
signal clk : std_logic;
signal reg1, reg2 : std_logic;
signal reg3 : std_logic_vector(2 downto 0);
attribute syn_keep of reg1 : signal is true;
attribute syn_keep of reg2 : signal is true;
attribute syn_keep of reg3 : signal is true;
begin
process(clk)
begin
if rising_edge(clk) then
reg1 <= probe; -- sample
reg2 <= reg1; -- recapture, shortest as possible
reg3 <= reg2 & reg2 & reg2; -- copy
case reg3 is
when "000" => Q <= '0';
when "001" => Q <= '0';
when "010" => Q <= '0';
when "011" => Q <= '1';
when "100" => Q <= '0';
when "101" => Q <= '1';
when "110" => Q <= '1';
when "111" => Q <= '1';
when others => Q <= '0';
end case;
end if;
end process;
end pa3;
Если 8 раз использовать модуль, набросок которого приведен выше, то у вас окажеся захваченный сигнал, но на разных фазах, а нужно все свести к одной, нулевой. Труднее всего будет сигналам, которые близки к ней. Поэтому сначала перезахватите клоком сдвинутым на 180 градусов те сигналы, которые захватывались на фазах после 180 градусов, а потом перезахватите уже нулевым клоком.
Если будет плохо разводиться, то можно последовательно подтягивать сигналы к 0 фазе не за два шага, а за сколько нужно, хоть за 7.