Чего мне не хватает в этой симуляции?
Я пытаюсь написать VHDL-код для драйвера клавиатуры, для которого мне нужно прочитать 8-битный из 11-битного вектора, чтобы не усложнять ситуацию, это процесс, который считывает входные сигналы (есть сигналы CLK и Data).
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;
Проблема в том, что я продолжаю читать 0xE1
вместо 0xF0
все остальное работает нормально, и я не могу понять, почему мне не хватает этого Бита.
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;
Отрегулируйте циклы для повторяющихся данных в соответствии с желаемой тестовой таблицей.