Перейти к содержанию
    

Проблема с PLL

Есть проект с MAX10 10M50SAE144I7G.

Добавил в проект модули PLL и ADC с уже существующего проекта с таким же FPGA.

component pll is
port
(
	 inclk0 : in std_logic := '0';
	 c0	 : out std_logic;
	 c1	 : out std_logic;
	 c2	 : out std_logic;
	 c3	 : out std_logic  
);
end component;

component adc_qsys is
port 
(
	adc_1_command_valid          : in  std_logic                     := '0';             --  adc_1_command.valid
	adc_1_command_channel        : in  std_logic_vector(4 downto 0)  := (others => '0'); -- .channel
	adc_1_command_startofpacket  : in  std_logic                     := '0';             -- .startofpacket
	adc_1_command_endofpacket    : in  std_logic                     := '0';             -- .endofpacket
	adc_1_command_ready          : out std_logic;                                        -- .ready
	adc_1_response_valid         : out std_logic;                                        -- adc_1_response.valid
	adc_1_response_channel       : out std_logic_vector(4 downto 0);                     -- .channel
	adc_1_response_data          : out std_logic_vector(11 downto 0);                    -- .data
	adc_1_response_startofpacket : out std_logic;                                        -- .startofpacket
	adc_1_response_endofpacket   : out std_logic;                                        -- .endofpacket
		
	clk_clk                      : in  std_logic                     := '0';             --  clk.clk
	reset_reset_n                : in  std_logic                     := '0'              --  reset.reset_n
);
end component;

-----------------------------------------------------------------------------------------------------------------
  
U_SYS_PLL : pll 
port map
(
    inclk0  => OBE_CLK,
	 c0		=> s_pll_clk_120M,
	 c1      => s_pll_clk_100M,
	 c2      => s_pll_clk_30M,
	 c3      => s_pll_clk_10M
);

U_SYS_ADC : adc_qsys 
port map 
(
	clk_clk        => s_pll_clk_10M,
	reset_reset_n  => '1', 
	
	adc_1_command_valid          => adc1_com_valid, 
	adc_1_command_channel        => adc1_com_channel, 
	adc_1_command_startofpacket  => adc1_com_startofpacket,
	adc_1_command_endofpacket    => adc1_com_endofpacket, 
	adc_1_command_ready          => adc1_com_ready,
	adc_1_response_valid         => adc1_resp_valid,
	adc_1_response_channel       => adc1_resp_channel,
	adc_1_response_data          => adc1_resp_data, 
	adc_1_response_startofpacket => adc1_resp_startofpacket,
	adc_1_response_endofpacket   => adc1_resp_endofpacket
);
  
  

Всё скомпилировалось без проблем.

Я добавил процесс сканирования всех каналов каждые 100 мс.

Spoiler
type AdcStateType is (ST_WAIT_FOR_TRIG, ST_SELECT_CHAN, ST_SET_CHAN, 
                      ST_START_CONV, ST_WAIT_FOR_DONE, ST_DATA_READY);
signal Adc1State : AdcStateType := ST_WAIT_FOR_TRIG;


SYS_ADC_SCAN : process(glob_clock)
variable chan : integer range 0 to 9 := 0;
begin

    if rising_edge(glob_clock) then
	 
        case Adc1State is
	 
            when ST_WAIT_FOR_TRIG =>
  
                adc1_ena <= '1';
                chan := 0;
                adc1_com_valid <= '0';
					
                if (adc1_start = '1') then		 
                    Adc1State <= ST_SELECT_CHAN;
                end if;
					
            when ST_SELECT_CHAN =>
                adc1_ena <= '0';
                chan := chan + 1;
                if (chan > 8) then   
                    Adc1State <= ST_WAIT_FOR_TRIG;
                else
                   case chan is
                       when 1 => adc1_com_channel <= "00000";   
                       when 2 => adc1_com_channel <= "00001";
                       when 3 => adc1_com_channel <= "00010";
                       when 4 => adc1_com_channel <= "00011";
                       when 5 => adc1_com_channel <= "00100";
                       when 6 => adc1_com_channel <= "00101";
                       when 7 => adc1_com_channel <= "00110";
                       when 8 => adc1_com_channel <= "00111";
                       when others => 
                   end case;
                    Adc1State <= ST_START_CONV;
			    end if;	
					
            when ST_START_CONV => 
                adc1_com_valid <= '1';
                Adc1State <= ST_WAIT_FOR_DONE;
			
            when ST_WAIT_FOR_DONE =>
                if (adc1_resp_valid = '1') then
                    Adc1State <= ST_DATA_READY;
                end if;
                --timeout
                adc1_timeout <= adc1_timeout + '1';
                if (adc1_timeout >= X"249F00") then  --20 ms
                     adc1_timeout <= (others => '0');
                     Adc1State <= ST_WAIT_FOR_TRIG;
                  end if;
					
            when ST_DATA_READY => 
                adc1_com_valid <= '0';
                case chan is
                    when 1 => adc1_1_data <= adc1_resp_data;   
                    when 2 => adc1_2_data <= adc1_resp_data;
                    when 3 => adc1_3_data <= adc1_resp_data;
                    when 4 => adc1_4_data <= adc1_resp_data;
                    when 5 => adc1_5_data <= adc1_resp_data;  
                    when 6 => adc1_6_data <= adc1_resp_data;
                    when 7 => adc1_7_data <= adc1_resp_data;
                    when 8 => adc1_8_data <= adc1_resp_data;
                    when others => Adc1State <= ST_WAIT_FOR_TRIG;
                end case;
                Adc1State <= ST_SELECT_CHAN;	
				  
            when others => 
                 Adc1State <= ST_WAIT_FOR_TRIG;	  
				
        end case;				
			
    end if;
end process SYS_ADC_SCAN;	

 

И тут фитер генерирует ошибку

Quote

Info (15535): Implemented PLL "pll:U_SYS_PLL|altpll:altpll_component|pll_altpll:auto_generated|pll1" as MAX 10 PLL type
Info (15535): Implemented PLL "adc_qsys:U_SYS_ADC|adc_qsys_ADC1_PLL:adc1_pll|adc_qsys_ADC1_PLL_altpll_gr22:sd1|pll7" as MAX 10 PLL type
    
    
Error (176394): Can't fit 2 PLLs in the device -- only 1 PLLs are available
    Info (176395): Location PLL_3 cannot be used due to package or device migration constraints
    Info (176395): Location PLL_4 cannot be used due to package or device migration constraints
    Info (176395): Location PLL_2 cannot be used due to package or device migration constraints

Он почему то генерирует два PLL а на самом деле есть один.

Начал убирать куски кода в процессе и нашел что если убрать всего одну строчку Adc1State <= ST_START_CONV; то всё компилируется.

when ST_SELECT_CHAN =>
    adc1_ena <= '0';
	chan := chan + 1;
    if (chan > 8) then  
        Adc1State <= ST_WAIT_FOR_TRIG;
	else
        case chan is
            when 1 => adc_chan := "00001";   
           when 2 => adc_chan := "00010";
           when 3 => adc_chan := "00011";
           when 4 => adc_chan := "00100";
           when 5 => adc_chan := "00101";
           when 6 => adc_chan := "00110";
           when 7 => adc_chan := "00111";
           when 8 => adc_chan := "01000";
           when others => 
       end case;
       --Adc1State <= ST_START_CONV; --без этой строчки компилируеися
    end if;	

Это как вообще? 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jenya7 сказал:
--Adc1State <= ST_START_CONV; --без этой строчки компилируеися

Так у вас там выше в том же блоке кода

Adc1State <= ST_WAIT_FOR_TRIG;

Это как вообще?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 12/14/2023 at 10:26 AM, Zversky said:

Так у вас там выше в том же блоке кода

Adc1State <= ST_WAIT_FOR_TRIG;

Это как вообще?

там же блок - if - else. если одно условие - иди направо, другое условие - иди налево.

и потом - как это влияет на решения фитера создать ещё один PLL?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно вы добавили PLL c кривыми настройками. Или клок с PLL не заходит на глобальное тактовое дерево. Создайте PLL через wizzard.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 12/14/2023 at 10:59 AM, Flip-fl0p said:

Возможно вы добавили PLL c кривыми настройками. Или клок с PLL не заходит на глобальное тактовое дерево. Создайте PLL через wizzard.

я когда кликаю в дереве проекта на моддуле PLL появляется wizzard и я вижу все настройки. 

у модуля ADC есть внутренний PLL, но почему то в другом проекте он не компилируется как аппаратный PLL. я думал может модуль ADC как то криво компилируется но я не получаю никаких ошибок пока не добавляю эту строку в процессе сканирования каналов.

 

Сделал такой эксперимент. Вернул строку Adc1State <= ST_START_CONV; и в следующем состоянии убрал adc1_com_valid <= '1';

when ST_START_CONV => 
    --adc1_com_valid <= '1';
    Adc1State <= ST_WAIT_FOR_DONE;

и всё компилируется. 

сигнал adc1_com_valid это начало конвертации канала. то есть если убрать эту строку то внутренний PLL ADC модуля реализуется фитером как то иначе? что за жесть?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 12/14/2023 at 9:12 AM, jenya7 said:

Есть проект с MAX10 10M50SAE144I7G.

Добавил в проект модули PLL и ADC с уже существующего проекта с таким же FPGA.

Как минимум здесь не хватает reset-а:
 

SYS_ADC_SCAN : process(glob_clock, reset)
variable chan : integer range 0 to 9;
begin
 if reset = '1' then
     Adc1State <= ST_WAIT_FOR_TRIG;
       elsif  glob_clock'event and glob_clock = '1' then
       
            ...

 Ну а причина ошибки скорее всего в том, что где-то создается "комбинаторная" обратная связь

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...