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

Вы находитесь на русскоязычном форуме 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: 47
Joined: Sun Dec 29, 2024 2:48 pm
Has thanked: 24 times
Been thanked: 37 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

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