1
0
mirror of synced 2026-01-11 23:53:00 +00:00
lisper.cpus-pdp8/v/scancode2.v
2007-01-02 16:24:48 +00:00

252 lines
4.8 KiB
Verilog

// scancode2.v
//
// simple AT style keyboard scancode to ascii convertion
// keeps track of shift, capslock and control keys
// inputs scancodes and outputs ascii
//
// implicit state machine version
//
`include "scancode_rom.v"
module scancode_convert(clock,
reset_n,
scancode,
ascii,
key_up,
strobe_in,
strobe_out);
input clock;
input reset_n;
input [7:0] scancode;
output reg [7:0] ascii;
output reg key_up;
input strobe_in;
output reg strobe_out;
reg release_prefix;
reg shift;
reg ctrl;
reg capslock;
reg [6:0] sc;
wire [7:0] rom_data;
wire raise;
scancode_rom scancode_rom(.addr({raise,sc}),
.data(rom_data));
assign raise = shift | capslock | ctrl;
always @(posedge clock or negedge reset_n)
if (~reset_n)
begin
shift <= 0;
ctrl <= 0;
capslock <= 0;
release_prefix <= 0;
key_up <= 0;
strobe_out <= 0;
end
else
begin
if (strobe_in)
begin
strobe_out <= 0;
sc = scancode[6:0];
case (scancode)
8'hf0: /* release prefix */
begin
@(posedge clock) release_prefix <= 1;
end
8'h58: /* caps lock */
begin
if (~release_prefix)
@(posedge clock) capslock = ~capslock;
end
8'h12, /* left shift */
8'h59: /* right shift */
begin
@(posedge clock) shift = release_prefix ? 0 : 1;
end
8'h14: /* left ctrl */
begin
@(posedge clock) ctrl = release_prefix ? 0 : 1;
end
default:
begin
if (release_prefix)
begin
@(posedge clock)
begin
ascii = ctrl ? (rom_data - 8'h40) : rom_data;
strobe_out <= 1;
end
@(posedge clock) strobe_out <= 1;
@(posedge clock)
begin
strobe_out <= 0;
release_prefix <= 0;
end
end
else
begin
@(posedge clock)
begin
/*
ascii = ctrl ? (rom_data - 8'h40) : rom_data;
strobe_out <= 1;
*/
key_up <= 1;
end
@(posedge clock) strobe_out <= 0;
@(posedge clock)
begin
strobe_out <= 0;
release_prefix <= 0;
end
end
end
endcase // case(scancode)
end // if (strobe_in)
end // else: !if(~reset_n)
endmodule
///*
// ------------------
`timescale 1ns / 1ns
module test;
reg clk, reset_n;
reg [7:0] testcode;
wire [7:0] kb_ascii;
reg kb_rdy;
wire kb_release;
wire kb_ascii_rdy;
scancode_convert scancode_convert(.clock(clk),
.reset_n(reset_n),
.scancode(testcode),
.ascii(kb_ascii),
.key_up(kb_release),
.strobe_in(kb_rdy),
.strobe_out(kb_ascii_rdy));
initial
begin
$timeformat(-9, 0, "ns", 7);
$dumpfile("scancode.vcd");
$dumpvars(0, test.scancode_convert);
end
initial
begin
clk = 0;
reset_n = 0;
kb_rdy = 0;
#200 begin
reset_n = 1;
end
// press "a"
#10 begin kb_rdy = 1; testcode = 8'h1c; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h1c; end
#80 kb_rdy = 0;
// press "b"
#1000 begin kb_rdy = 1; testcode = 8'h32; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h32; end
#80 kb_rdy = 0;
// enter
#1000 begin kb_rdy = 1; testcode = 8'h5a; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h5a; end
#80 kb_rdy = 0;
// shift "a"
#1000 begin kb_rdy = 1; testcode = 8'h12; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h1c; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h1c; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h12; end
#80 kb_rdy = 0;
// press "c"
#1000 begin kb_rdy = 1; testcode = 8'h21; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h21; end
#80 kb_rdy = 0;
// ctrl "a"
#1000 begin kb_rdy = 1; testcode = 8'h14; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h1c; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h1c; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h14; end
#80 kb_rdy = 0;
// press "d"
#1000 begin kb_rdy = 1; testcode = 8'h23; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'hf0; end
#80 kb_rdy = 0;
#1000 begin kb_rdy = 1; testcode = 8'h23; end
#80 kb_rdy = 0;
#5000 $finish;
end
always
begin
#40 clk = 0;
#40 clk = 1;
end
endmodule
//*/