VHDL тактовый делитель для контроля дежурства и фазы - PullRequest
0 голосов
/ 11 января 2019

Я использую высокоскоростные часы (из внутреннего ФАПЧ) и пытаюсь разделить их, чтобы сгенерировать 2 тактовых импульса с разным коэффициентом заполнения и фазой. Код работает правильно, если я пошаговый ввод часов. По мере увеличения частоты фаза и нагрузка вторичного выхода (iDM_out в образце кода) повреждаются. На некоторых частотах рабочий цикл вторичного выхода будет правильным. На других частотах рабочий цикл может доходить до 90 или 199%. То же самое с фазовым соотношением (DMDelay). Мне показались некоторые статьи о необходимости тактовых буферов, поэтому я пробовал несколько типов BUFF, CLKBUF и CLKINT на выходе, и это, кажется, усугубляет ситуацию. У кого-нибудь есть идеи о том, что может быть причиной этого состояния?

use work.A208_pckgs.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity DutyPhaseMod is
    port (
        rst     : in std_logic; 
        GLA     : in std_logic;     -- GLA is 36x faster than target frequency
        EXDuty  : in std_logic_vector(4 downto 0);  -- the number of GLA clock cycles for the EX duty cycle
        DMDuty  : in std_logic_vector(4 downto 0);  -- the number of GLA clock cycles for the DM duty cycle
        DMDelay : in std_logic_vector(4 downto 0);  -- the number of GLA clock cycles for the DM phase delay

        EX_out  : out std_logic;
        DM_out  : out std_logic
    );                   
end entity;

architecture behavioral of DutyPhaseMod is
    signal iGLA     : std_logic;
    signal iFREQlen : integer range 0 to 35;
begin
    process (rst, GLA)
        variable iEX_out    : std_logic;
        variable iDM_out    : std_logic;
        variable iEXctr     : natural range 0 to 35;
        variable iDMctr     : natural range 0 to 35;
    begin
        iFREQlen <= 35;                             -- number of clock cycles

        if rst = '1' then                           -- reset the counters on reset signal
            iEXctr  := 0;
            iDMctr  := 0;
        elsif rising_edge(GLA) then
            if iEXctr <= unsigned(EXDuty) then      -- first part of EX the duty cycle
                iEX_out := '1';             
                iEXctr := iEXctr + 1;
            elsif iEXctr < iFREQlen then            -- second part of EX duty cycle
                iEX_out := '0';
                iEXctr := iEXctr + 1;
            else                                    -- set for the start of the next cycle
                iEX_out := '1'; 
                iEXctr := 0;
            end if;

            if iEXctr = unsigned(DMDelay) then      -- reset for DM phase offset
                iDMctr := 0;                            
            elsif iDMctr <= unsigned(DMDuty) then   -- first part of the DM duty cycle
                iDM_out := '1';
                iDMctr := iDMctr + 1;
            elsif iDMctr <= iFREQlen - 1 then       -- second part of the DM duty cycle
                iDM_out := '0';
                iDMctr := iDMctr + 1;
            else                                    -- set for the start of the next cycle
                iDM_out := '1';
            end if;

            EX_out <= iEX_out;
            DM_out <= iDM_out;

        end if;
    end process;
end behavioral;

1 Ответ

0 голосов
/ 12 января 2019

Я собираюсь выйти на конечность и ответить на свой вопрос. Не стесняйтесь комментировать, если вы чувствуете, что мой ответ неверен (или вы можете добавить / уточнить далее). Я решил разделить свою сущность на два процесса, и, похоже, она работает должным образом. Первый процесс обрабатывает базовое деление тактовой частоты на восходящем фронте высокоскоростной тактовой частоты. Второй процесс обрабатывает вторичные (с фазовой задержкой) тактовые импульсы на падающем_скоре высокоскоростных тактовых импульсов.

        library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity DutyPhaseMod is
        port (
            rst     : in std_logic; 
            GLA     : in std_logic;     
            EXDuty  : in std_logic_vector(3 downto 0);
            DMDuty  : in std_logic_vector(3 downto 0);
            DMDelay : in std_logic_vector(4 downto 0);

            EX_out  : out std_logic;
            DM_out  : out std_logic
        );                   
    end entity;

    architecture behavioral of DutyPhaseMod is
        signal iGLA     : std_logic;
        signal iFREQlen : integer range 0 to 35;
        signal iEXctr   : natural range 0 to 35;
    begin
        process (rst, GLA)
            variable iEX_out    : std_logic;
        begin
            iFREQlen <= 35;

            if rst = '1' then
                iEXctr  <= 0;
            elsif rising_edge(GLA) then

                if iEXctr <= unsigned(EXDuty) then
                    iEX_out := '1';                         --
                    iEXctr <= iEXctr + 1;
                elsif iEXctr < iFREQlen then
                    iEX_out := '0';
                    iEXctr <= iEXctr + 1;
                else
                    iEX_out := '1';
                    iEXctr <= 0;
                end if;

                EX_out <= iEX_out;
            end if;
        end process;

        process (rst, GLA)
            variable iDM_out    : std_logic;
            variable iDMctr     : natural range 0 to 30;
        begin
            case FW_FREQ is
            when F_46 =>
                iFREQlen <= 35;
            when F_82 =>
                iFREQlen <= 23;
            end case;

            if rst = '1' then
                iDMctr  := 0;
            elsif falling_edge(GLA) then
                if iEXctr = unsigned(DMDelay) then  
                    iDMctr := 0;                
                elsif iDMctr <= unsigned(DMDuty) then
                    iDM_out := '1';
                    iDMctr := iDMctr + 1;
                elsif iDMctr <= iFREQlen - 1 then
                    iDM_out := '0';
                    iDMctr := iDMctr + 1;
                else
                    iDM_out := '1';
                end if;

                DM_out <= iDM_out;
            end if;
        end process;
    end behavioral;
...