Page 1 of 1

Непонятное поведение сигнала INT

PostPosted: Mon, 26.01.2015 18:24:21
by Mick
Вобщем смысл такой. Есть кусок кода на AHDL, ну там для железячников станет все ясно сразу.
Так вот, если синхрогенератор делать на стандартную частоту телека 15625 проблем с Интом не видно, по крайней мере я не замечал
Но стоит так сказать приподняться на VGA частоту 31250, так начинаются непонятки с Интом, он появляется как то нестабильно, то два проскочет, то нормально пройдет, а может и вообще пропустить.

Кто что может посоветовать.
Вот кусок кода. А то я уже всю башню сломал

Code: Select all
    ------------------------------------------------------------------------------------
    --                            Синхрогенератор
    ------------------------------------------------------------------------------------
    -- Системные сигналы
    ------------------------------------------------------------------------------------
    Sync_count[].clk  = CLK_14MHZ;                  -- Системные сигналы TI, H0, H1, H2   
    Sync_count[].d      = Sync_count[].q+1;

    VCLK = !(Sync_count[0].q & Sync_count[1].q & Sync_count[2].q);
--    VCLK = !(Sync_count[0].q & Sync_count[1].q & Sync_count[2].q & Sync_count[3].q); -- Сигнал H2
    ------------------------------------------------------------------------------------
    -- Строчная развертка
    ------------------------------------------------------------------------------------
    HSync_count[].clk  = VCLK;                      -- Сигналы строчной развертки H3, H4, H5, H6, H7, BC
    HSync_count[].d    = HSync_count[].q+1;
    HSync_count[].clrn = !HReset;

    HReset  = HSync_count[3].q & HSync_count[4].q & HSync_count[5].q; -- сигнал RH = H6 & H7 & BC
    HBorder = HSync_count[5].q;            -- сигнал BC
    HBlank  = !(HSync_count[5].q & !HSync_count[4].q & HSync_count[3].q); --сигналы SG/ = !(BC & !H7 & H6)
    HSync   = HBlank # HSync_count[2].q;    -- сигналы SS/ = SG/ # H5
    ------------------------------------------------------------------------------------
    -- Кадровая развертка
    ------------------------------------------------------------------------------------
    VSync_count[].clk  = !HBorder;               -- Сигналы кадровой развертки V0...V7
    VSync_count[].d    = VSync_count[].q+1;
    VSync_count[].clrn = !VReset;

    VReset  = VSync_count[9].q & !VSync_count[8].q & !VSync_count[7].q & VSync_count[6].q & VSync_count[5].q & VSync_count[4].q;
    VBorder = VSync_count[9].q # (VSync_count[8].q & VSync_count[7].q);             -- сигнал BK = V8 # (V7 & V6)
    VSync   = VSync_count[9].q # !VSync_count[8].q # !VSync_count[7].q # !VSync_count[6].q # !VSync_count[5].q; -- сигнал KS/ = !V8 # !(V7 & V6 & V5 & V4)


--    VReset  = VSync_count[8].q & VSync_count[5].q & VSync_count[4].q & VSync_count[3].q; -- сигнал RV = V8 & V5 & V4 & V3
--    VBorder = VSync_count[8].q # (VSync_count[7].q & VSync_count[6].q);             -- сигнал BK = V8 # (V7 & V6)
--    VSync   = VSync_count[8].q # !VSync_count[7].q # !VSync_count[6].q # !VSync_count[5].q # !VSync_count[4].q; -- сигнал KS/ = !V8 # !(V7 & V6 & V5 & V4)
    ------------------------------------------------------------------------------------
    --  Счетчики мерцания
    ------------------------------------------------------------------------------------
    Flash_count[].clk  = !VSync;               --Сигналы счетчиков мерцания BK/, FLASH   
    Flash_count[].d    = Flash_count[].q+1;
    ------------------------------------------------------------------------------------
    --  Строб бордера
    ------------------------------------------------------------------------------------
    Border_sync.d = !(VBorder # HBorder);
    Border_sync.clk = HSync_count[0].q;          -- сигнал H3
    ------------------------------------------------------------------------------------
    -- Сигнал прерывания
    -- Примечание: прерывание генерится с частотой 50Гц
    ------------------------------------------------------------------------------------
     Int_sync.d = GND;
--    Int_sync.clk = VSync_count[8].q;             -- прерывание на 256 импульсе --VSync; -- сигнал KS/
     Int_sync.clk = VSync_count[9].q;             -- прерывание на 256 импульсе --VSync; -- сигнал KS/
     Int_sync.prn = 2mux1(!HSync_count[3].q, !HSync_count[2].q, Turbo_en); --сигналы H6 и H5
    ------------------------------------------------------------------------------------
    -- Сигнал прерывания
    ------------------------------------------------------------------------------------
    C_INT = Int_sync.q;
    ------------------------------------------------------------------------------------
    -- Сигнал кадровой разверки
    ------------------------------------------------------------------------------------
    VS = VSync;
    ------------------------------------------------------------------------------------
    -- Сигнал строчной развертки
    ------------------------------------------------------------------------------------
    HS = HSync;



Закомментаренные участки относились к телевизору.

Re: Непонятное поведение сигнала INT

PostPosted: Mon, 26.01.2015 19:22:16
by TS-Labs
Каноничная ошибка, о которой я писал на zx.пукан.рву:

Раз:
VSync = VSync_count[9].q # !VSync_count[8].q # !VSync_count[7].q # !VSync_count[6].q # !VSync_count[5].q;
Комбинаторная функция. Продукт этого выражения полон иголками чуть менее, чем полностью.

Два:
Flash_count[].clk = !VSync;
Сигнал с кучей иголок идет в качестве клока для триггера.
При изменении строчной форма иголок и поведение меняются.

Еще:
VCLK = !(Sync_count[0].q & Sync_count[1].q & Sync_count[2].q);
HSync_count[].clk = VCLK;
Int_sync.clk = VSync_count[9].q;

ТАК ДЕЛАТЬ НЕЛЬЗЯ!

Как правильно:
Code: Select all
reg HSync_count[9:0];
reg VSync_count[8:0];
reg Frame_Int_n;   // выход инта на проц

wire VSync_count_stb = (HSync_count == 10'd895);  // максимум строчного счетчика, при этом он должен быть активен в течение 1 периода доменного клока
wire Frame_stb = (VSync_count == 9'd311) && VSync_count_stb; // максимум кадра, опять же строб

always @(posedge clk) // <- клок домена, например 14МГц, ЕДИНЫЙ в клоковом домене - это критично
begin
  if (VSync_count_stb)
    HSync_count <= 10'b0;
  else
    HSync_count <= HSync_count + 1'b1;
 
  if (Frame_stb)
    VSync_count <= 9'b0;
  else if (VSync_count_stb)
    VSync_count <= VSync_count + 1'b1;
   
  if (Frame_stb)
    Frame_Int_n <= 1'b0;
  else if (!iorq_n && !m1) // примитивная дешифрация и отсутствует таймаут - для примера only
    Frame_Int_n <= 1'b1;
end


ПС1.
Всегда желательно приводить весь сорец целиком.

ПС2.
AHDL фтопку - древнее проприетарное говно мамонта с конченым синтаксисом. Выучи верилог, плиииз.

Re: Непонятное поведение сигнала INT

PostPosted: Mon, 26.01.2015 19:40:17
by Mick
TS-Labs wrote:ПС2.
AHDL фтопку - древнее проприетарное говно мамонта с конченым синтаксисом. Выучи верилог, плиииз.



Понимаю, что древнее оно, я только пока в VHDL разбираюсь, до верилога мне еще далеко :) Просто на AHDL как то привычнее, но он вот с подвывертами.

Re: Непонятное поведение сигнала INT

PostPosted: Mon, 26.01.2015 20:12:27
by TS-Labs
VHDL туда же :)

Re: Непонятное поведение сигнала INT

PostPosted: Mon, 26.01.2015 23:12:38
by TS-Labs
Mick wrote:Просто на AHDL как то привычнее, но он вот с подвывертами.

АХДЛ тут ни при чем - ошибка в дизайне.
Еще раз правило: выходы комбинаторных функций нельзя использовать в качестве входов clk для регов. Вместо этого, их надо использовать в качестве входов en регов, а сами реги клочить от общего доменного клока.

Re: Непонятное поведение сигнала INT

PostPosted: Tue, 27.01.2015 06:48:07
by Mick
TS-Labs wrote:VHDL туда же


По крайней мере он мне более понятен чем верилог. Тот пока для меня черный ящик.

TS-Labs wrote:АХДЛ тут ни при чем - ошибка в дизайне.
Еще раз правило: выходы комбинаторных функций нельзя использовать в качестве входов clk для регов. Вместо этого, их надо использовать в качестве входов en регов, а сами реги клочить от общего доменного клока.


Спасибо, я понял, теперь попробую это реализовать.

Re: Непонятное поведение сигнала INT

PostPosted: Tue, 27.01.2015 18:50:43
by Mick
Вот попытался изобразить на том же древнем языке строчную развертку

Code: Select all
    Sync_count[].clk  = CLK_14MHZ;                  
    Sync_count[].d      = Sync_count[].q+1;

--    VCLK = !(Sync_count[0].q & Sync_count[1].q & Sync_count[2].q); 
--    VCLK = !(Sync_count[0].q & Sync_count[1].q & Sync_count[2].q & Sync_count[3].q);
    ------------------------------------------------------------------------------------
    HSync_count[].clk  = CLK_14MHZ;                  
   IF   Sync_count[].q ==7 THEN
      IF   HSync_count[].q == 55 THEN
         HSync_count[].d = GND;
      ELSE
          HSync_count[].d = HSync_count[].q + 1;
      END IF;      
      IF HSync_count[].q >= 32 THEN
          HBorder = GND;
      ELSE
           HBorder = VCC;
      END IF;
      IF HSync_count[].q >= 40 THEN
          HSync  = GND;
         HBlank = GND;   
         IF HSync_count[].q >= 44 THEN
               HSync = VCC;
         END IF;
         IF HSync_count[].q >= 48 THEN
               HBlank = VCC;
         END IF;
      END IF;                  
   END IF;


Так оно типа без и иголок и правильно?

Re: Непонятное поведение сигнала INT

PostPosted: Tue, 27.01.2015 19:16:03
by TS-Labs
Да, подход правильный. Не уверен насчет логики формировования импульсов и констант - не проверял.

Re: Непонятное поведение сигнала INT

PostPosted: Wed, 28.01.2015 18:45:20
by Mick
Не пошло сие выражение в железке.
Попытался переложить синхрогенератор на VHDL, строка и кадры есть, растр есть, а вот треклятого инта нет.

Code: Select all
   ------------------------------------------------------------------------------------
   --                            Синхрогенератор
   ------------------------------------------------------------------------------------
   -- Clock frequency 14.000 MHz
   --       "256 x 192 Screen"
   -- Line  frequency 15625 Hz
   -- Field frequency 50 Hz
   -- Sync polarity: H negative, V negative
   -- Scan type: non interlaced.
   ------------------------------------------------------------------------------------
    -- Системные сигналы
   ------------------------------------------------------------------------------------
   Sync_system : process(CLK_14MHZ)
                  begin
          if (CLK_14MHZ'event and CLK_14MHZ = '1') then
                   Sync_count <= Sync_count + '1';
                       end if;             
            end process Sync_system;
   ------------------------------------------------------------------------------------
    -- Строчная развертка
   ------------------------------------------------------------------------------------
   Horizonal_sync : process(CLK_14MHZ, Sync_count)
                     begin
             if (CLK_14MHZ'event and CLK_14MHZ = '1') then
                        if Sync_count = 7 then
 
                                   if HSync_count < 55 then
                                      HSync_count <= HSync_count + '1';
                                   else
                                      HSync_count <= (others => '0');
                                   end if;

                                   if HSync_count >= 32 then
                                      HBorder <= '0';
                 else
                                      HBorder <= '1';
                                   end if;   

                                   if (HSync_count >= 40 and HSync_count < 44) then
                                      HSync <= '0';
               else
                                      HSync <= '1';
                                   end if;   

                                   if (HSync_count >= 40 and HSync_count < 48) then
                                      HBlank <= '0';
               else
                                      HBlank <= '1';
                                   end if;   
                              end if;
                               end if;             
               end process Horizonal_sync;
   ------------------------------------------------------------------------------------
    -- Кадровая развертка
   ------------------------------------------------------------------------------------
   Vertical_sync : process(CLK_14MHZ, Sync_count, HSync_count)
             begin
               if (CLK_14MHZ'event and CLK_14MHZ  = '1') then
                    if (HSync_count = 55 and Sync_count = 7) then
                         
                      if VSync_count < 623 then
                          VSync_count <= VSync_count + '1';
                       else
                          VSync_count <= (others => '0');
                       end if;

                       if VSync_count >= 384 then
                          VBorder <= '0';
                    else
                          VBorder <= '1';
                       end if;   

                       if (VSync_count >= 480 and VSync_count < 512) then
                         VSync  <= '0';
                         VBlank <= '0';
                    else
                         VSync  <= '1';
                         VBlank <= '1';
                       end if;   

                        if (VSync_count = 512 and HSync_count(5 downto 3) = "000") then
                      Int_sync <= '0';
                         else
                      Int_sync <= '1';
                     end if;
   
                    end if;
                 end if;
            end process Vertical_sync;
    ------------------------------------------------------------------------------------
    -- Триггер прерывания
    ------------------------------------------------------------------------------------
    C_INT <= Int_sync;
   ------------------------------------------------------------------------------------
   --  Счетчики мерцания
   ------------------------------------------------------------------------------------
   Flash_sync : process(CLK_14MHZ)
             begin
               if (CLK_14MHZ'event and CLK_14MHZ  = '1') then
                     if (VSync_count = 512 and HSync_count = 55 and Sync_count = 7) then
                        Flash_count <= Flash_count + '1';
                     end if;   
                  end if;
           end process Flash_sync;



Блин, ну зараза же этот инт

Re: Непонятное поведение сигнала INT

PostPosted: Wed, 28.01.2015 20:02:24
by TS-Labs
1. Int_sync не коротковат ли?
2. Отключать его необходимо по иорк/м1.