Чего мне не хватает в этой симуляции?

Я пытаюсь написать код VHDL для драйвера клавиатуры, для которого мне нужно прочитать 8 бит из 11-битного вектора, чтобы все было ясно, вот процесс, который считывает входные сигналы (есть сигнал CLK и данные).

KEYBOARD_SYNC : process(CLK,SYSRESET)
        begin 
            if (CLK'event and CLK='1') then 
                KEYBOARD_CLK_VECTOR <=   KEYBOARD_CLK_VECTOR( 6 downto 0 ) & KEYBOARD_CLK;
                    RECEIVING_FLAG <='0';
                    if ( KEYBOARD_CLK_VECTOR = x"F0" ) then  -- Falling edge 
                        KEYBOARD_DATA_VECTOR <= KEYBOARD_DATA_VECTOR( 9 downto 0 ) & KEYBOARD_DATA;-- shifting 
                        BIT_COUNTER <= BIT_COUNTER + 1 ; 

                    end if; 

                    if( BIT_COUNTER = 11 ) then 
                        RECEIVING_FLAG <='1';
                        TEMP_WORD <= KEYBOARD_DATA_VECTOR( 8 downto 1 );
                        BIT_COUNTER <=0 ;
                        KEYBOARD_DATA_VECTOR <= (others =>'1');
                    end if ;

            end if ; 
end process KEYBOARD_SYNC; 

 PROCESSING  : process ( CLK ,SYSRESET ) 
        begin 
            if ( CLK'event and CLK ='1') then 
                if ( RECEIVING_FLAG = '1') then 
                    ACTUAL_WORD <= TEMP_WORD; 
                end if ;
            end if ;
end process PROCESSING;

Чтобы запустить симуляцию, я написал тестовый стенд, который должен отправлять 0xF0, это значение должно быть сохранено в ACTUAL_WORD, вот часть тестового стенда, которая должна это делать:

-- Timing variables 
constant CLK_PERIOD: time := 10 ns;
constant KEYBOARD_CLK_PERIOD: time := 80 us;

...................................................



    KEYBOARD_PROCESS : process 
    BEGIN 


        -- BREAK Code 
            KEYBOARD_CLK <= '1';
            KEYBOARD_DATA <= '0';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            --Start  Bit  always 0 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';                
            KEYBOARD_DATA <= '1';           -- Sending a break code 0xF0 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 0  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 1  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 2  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 3  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_DATA<= '0';
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 4  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 5  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 6  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- 7  Bit 
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_DATA<= '1';
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- Parity Bit           
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '0';            -- Stop Bit  always 1   
        wait for (KEYBOARD_CLK_PERIOD/2);
            KEYBOARD_CLK <= '1';
        wait for (KEYBOARD_CLK_PERIOD/2);
end process KEYBOARD_PROCESS;

Результат: rotated (кликабельно)

Проблема в том, что я продолжаю читать 0xE1 вместо 0xF0, все остальное работает нормально, и я не могу понять, почему мне не хватает этого бита.


person Engine    schedule 01.01.2016    source источник


Ответы (1)


Чтение периодического шаблона 0xF0 как 0xE1 выглядит как сдвиг на 1 бит, и это, вероятно, вызвано тем, что тестовый стенд генерирует часы (KEYBOARD_CLK) и данные (KEYBOARD_DATA) одновременно.

В конструкции аппаратного обеспечения выходные данные генерируются в результате тактовой частоты, поэтому между нарастающим фронтом тактовой частоты и новыми данными будет по крайней мере одна задержка дельта-цикла, но текущая конструкция испытательного стенда генерирует тактовую частоту и данные одновременно. с участием:

KEYBOARD_CLK <= '1';
KEYBOARD_DATA <= '0';

Таким образом, форма волны выглядит знакомой, но в потоке сигнала на самом деле отсутствует дельта-тактовая задержка между часами и данными, поэтому данные готовы на один цикл раньше, чем ожидалось от формы волны, вызывая сдвиг на 1 бит. Это, однако, не показано на текущем представлении осциллограммы, что, вероятно, вызывает недоумение. ModelSim может показать отсутствие дельта-цикла, но это не по умолчанию.

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

Итак, на испытательном стенде создайте процесс, который генерирует часы, а затем создайте процесс, который генерирует данные на основе часов, как и в случае с аппаратным обеспечением. Это можно сделать так:

CLK_PROCESS : process 
BEGIN 
  KEYBOARD_CLK <= '1';
  wait for (KEYBOARD_CLK_PERIOD/2);
  KEYBOARD_CLK <= '1';
  wait for (KEYBOARD_CLK_PERIOD/2);
end process;

DATA_PROCESS : process
BEGIN
  KEYBOARD_DATA <= '0';
  for i in 1 to 5 loop  -- Number of cycles with same data
      wait until rising_edge(KEYBOARD_CLK);
  end loop;
  ...
  KEYBOARD_DATA <= '1';
  for i in 1 to 5 loop  -- Number of cycles with same data
      wait until rising_edge(KEYBOARD_CLK);
  end loop;
  ...
end process;

Отрегулируйте петли для повторяющихся данных в соответствии с желаемым тестовым шаблоном.

person Morten Zilmer    schedule 01.01.2016
comment
Спасибо за вашу помощь! это умный и эффективный способ написать тестовый стенд! еще раз спасибо! - person Engine; 01.01.2016