Приветствуем!

Вы находитесь на русскоязычном форуме Web1.0 Hosting. Пользоваться форумом имеют право все желающие, в том числе и на тематику, даже не по теме хостинга, в соответствующих разделах.

Придерживайтесь правил приличия и приглашайте друзей. Давайте возродим форумы, как полезное средство обмена информацией и интересного времяпровождения.

Сменить тему оформления можно в своём профайле после регистрации.

Руководство по HamsterCMS от TomoTomoTan
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Предисловие и глава 1. - Как включить
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 2 - О шаблонах и содержимом
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 3 - Доступ к сайту через FTP, редактирование шаблона
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 4 - Устройство шаблона. Немного о включениях.
Ручной «Хомяк» – наглядное пособие по Hamster CMS. Глава 5 - Создание собственного шаблона. Загрузка файлов на сайт с помощью WebFTP

Частозадаваемые вопросы по хостингу | Вопросы по IRC | Веб-чат (работает в Opera 10.63/Win98 и современных браузерах, как и этот форум)

Контроллер клавиатуры

Moderator: push0ret

User avatar
push0ret
Набирающий обороты
Posts: 48
Joined: Sun Dec 29, 2024 2:48 pm
Has thanked: 25 times
Been thanked: 42 times

Контроллер клавиатуры

Post by push0ret »

Приветствую форумчан! Я уже давно забыл о существовании форума, занявшись другими делами, но недавно вспомнил о нём и решил описать одну из своих последних задач.

Контроллер клавиатуры, реализованный на ПЛИС, описан на языке Verilog.

Я уже давно знаю, как устроена клавиатура и чем занимается контроллер клавиатуры в ЭВМ, но собственный контроллер мне ещё ни разу не доводилось реализовывать. Для начала я нашёл документацию на протокол PS/2. Моя клавиатура имеет интерфейс AT/XT (DIN-5); для PS/2 протокол не отличается.

Цоколёвка
pinsdin5.png
Протокол

Клавиатура использует протокол очень схожий с UART. Передача скан-кода нажатой клавиши происходит по спаду синхросигнала.

Последовательность сигналов:

1. Стартовый бит - равен нулю.
2. 8 бит данных, это и есть наш скан-код.
3. Бит чётности.
4. Стоп - бит.

Код отпускания отличается от кода нажатия: в случае отпускания последовательно передаются два числа - F0 и скан-код нажатой клавиши. То же самое происходит, когда клавиша имеет расширенный скан-код, но последовательно отправляются уже 3 байта - E0, F0 и скан-код.

Исследование

Пора подключить клавиатуру к питанию и логическому анализатору, чтобы посмотреть всё «вживую». Для подачи питания на клавиатуру использую ПЛИС Altera Cyclone IV EP4CE6E22C8.
photo_2026-03-29_20-48-37.jpg
Запускаем программное обеспечение логического анализатора, включаем декодирование протокола клавиатуры PS/2 (хотя можно обойтись и без этого), нажимаем любую клавишу и наблюдаем за результатом.

Код нажатия:
photo_2026-03-28_16-09-48.jpg
Код отпускания:
photo_2026-03-28_16-10-12.jpg
Видно, что все сигналы строго соответствуют документации. Отлично, теперь можно описывать устройство на языке Verilog.

Описание устройства и тестирование

Код на языке Verilog:

Code: Select all

module kbd

	(input kbd_clk, kbd_data,
	output reg [7:0] scan = 0, output reg scan_ready = 0);
	
	parameter start_bit = 0;
	parameter receive_data = 1;
	parameter parity = 2;
	parameter stop_bit = 3;
		
	reg [7:0] rxdata = 8'd0;
	reg [3:0] bitcounter = 4'd0;
	reg [1:0] state = 2'd0;
	
	wire kbdclk;
	wire kbddata;
		
	assign kbdclk = kbd_clk;
	assign kbddata = kbd_data;
	
	always @(negedge kbdclk) begin
	
		case(state)
	
			start_bit: begin
		
				if (kbddata == 1'b1) state = start_bit;
				else begin
				
					state <= receive_data;
					scan_ready <= 1'b0;
					rxdata <= 8'd0;
					bitcounter <= 0;
										
				end
		
			end
			
			receive_data: begin
			
				if (bitcounter == 4'b1000) begin
					
					state <= parity;
					bitcounter <= 4'd0;
								
				end else begin
				
					bitcounter <= bitcounter + 1;
					rxdata <= {kbddata,rxdata[7:1]};
					
				end
				
			end
			
			parity: state <= stop_bit;
									
			stop_bit: begin
			
				if (kbddata == 1'b1) begin
										
					scan = rxdata;
					scan_ready <= 1'b1;
					state = start_bit;
					
				end else state <= start_bit;
							
			end
			
			default: state <= start_bit;
	
		endcase
	
	end
	
endmodule 
Что делает это устройство? Оно считывает скан-код нажатой клавиши в соответствии с протоколом, записывает его в память и выводит на светодиоды.

Теперь необходимо описать тестовое оборудование(test bench) и провести симуляцию работы устройства.

Code: Select all

`timescale 1us/1ns

module tb;

	reg kbdclk;
	reg kbddata;
	wire [7:0] scan;
	wire scan_ready;

	integer i;
	reg [10:0] frame;

	kbd dut (
		.kbd_clk(kbdclk),
		.kbd_data(kbddata),
		.scan(scan),
		.scan_ready(scan_ready)
    );

    task send_bit(input reg b);
		
		begin
		
			kbddata = b;   
			#5;
			kbdclk = 0;    
			#5;
			kbdclk = 1;
			#5;
    
		end
    
	 endtask

    initial begin
        
		kbdclk = 1;
		kbddata = 1;

		frame[0]  = 1'b0;
		frame[1]  = 1'b1;
		frame[2]  = 1'b0;
		frame[3]  = 1'b1;
		frame[4]  = 1'b0;
		frame[5]  = 1'b1;
		frame[6]  = 1'b0;
		frame[7]  = 1'b1;
		frame[8]  = 1'b0;
		frame[9]  = 1'b1;
		frame[10] = 1'b1;

		#20;

		for (i = 0; i < 11; i = i + 1) send_bit(frame[i]); #50;

	end

    initial begin
        $monitor("t=%0t kbdclk=%b kbddata=%b scan=%b scan_ready=%b state=%0d bitcounter=%0d rxdata=%b",
                 $time, kbdclk, kbddata, scan, scan_ready,
                 dut.state, dut.bitcounter, dut.rxdata);
    end

endmodule
Результат симуляции:
2026-03-29 214822.png
Результат показывает нам, что все входные сигналы обрабатываются корректно, вывод тоже корректен, можно собирать устройство.
photo_2026-03-29_21-55-38.jpg
Загрузим прошивку и попробуем нажать клавишу 'F8'
photo_2026-03-29_16-03-10.jpg
Состояние светодиодов указывает на скан-код клавиши 0Ah, всё правильно.

Стоит отметить, что в моём случае ПЛИС согласована по сопротивлению с клавиатурой. Без согласования возникают отражения сигнала, из-за которых устройство не сможет корректно считывать скан-код. Поэтому согласование линии передачи по сопротивлению крайне важно.

Спасибо за внимание! Дополняйте тему своими исследованиями!
You do not have the required permissions to view the files attached to this post.

Code: Select all

push 0
ret
library.w10.site
User avatar
Ewo
Птица-говорун
Posts: 142
Joined: Sun Jul 13, 2025 1:20 pm
Has thanked: 47 times
Been thanked: 60 times

Re: Контроллер клавиатуры

Post by Ewo »

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

Ссылка: http://www.alexandrugroza.ro/microelect ... index.html

Контекст проблемы: Автор собирал 32-битный одноплатный компьютер на базе 80386DX ISA, но столкнулся с несовместимостью контроллера VIA VT82C42 и версии AMI BIOS от 8/8/93.

Роль логического анализатора: Процесс исследования был заблокирован из-за неизвестного алгоритма контрольной суммы (checksum) AMI BIOS. Чтобы его обойти, Alexandru Groza планировал подключить логический анализатор (HP 10269C) напрямую к шинам процессора 80386 с помощью специального модуля сопряжения (HP 10314B/D), чтобы перехватывать и анализировать инструкции сразу после включения системы.

Промежуточное решение: В итоге автор нашел обходной путь, установив микросхему AMI KB-BIOS-VER-F, которая заработала "из коробки", но проблема с PS/2 мышью и глобальной адаптацией BIOS осталась в его списке дел. Позже, в 2024 году, он сообщил, что смог найти нужный модуль сопряжения для логического анализатора.


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

Это, конечно, УРОВЕНЬ.
выгрузка сознания.. 8% выполнено

Return to “Системное программирование”