mirror of
https://github.com/alangarf/apple-one.git
synced 2025-02-08 20:30:38 +00:00
Added debounced PS/2 keyboard interface and A1 top-level selection between keyboard and UART RX
This commit is contained in:
parent
14743ed0de
commit
894c50ff4e
@ -360,6 +360,14 @@ set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to UART_CTS
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to UART_RXD
|
||||
set_global_assignment -name ENABLE_SIGNALTAP ON
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp1.stp
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
|
||||
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
set_global_assignment -name VERILOG_FILE ../../rtl/ps2keyboard/debounce.v
|
||||
set_global_assignment -name VERILOG_FILE ../../rtl/vga/vram.v
|
||||
set_global_assignment -name VERILOG_FILE ../../rtl/vga/vga.v
|
||||
set_global_assignment -name VERILOG_FILE ../../rtl/vga/font_rom.v
|
||||
@ -378,11 +386,4 @@ set_global_assignment -name VERILOG_FILE ../../rtl/uart/uart.v
|
||||
set_global_assignment -name VERILOG_FILE ../../rtl/uart/async_tx_rx.v
|
||||
set_global_assignment -name VERILOG_FILE ../../rtl/rom_wozmon.v
|
||||
set_global_assignment -name VERILOG_FILE ../../rtl/ram.v
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
|
||||
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
72
rtl/ps2keyboard/debounce.v
Normal file
72
rtl/ps2keyboard/debounce.v
Normal file
@ -0,0 +1,72 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
// Description: PS/2 keyboard debounce logic to be used for the
|
||||
// clock line
|
||||
//
|
||||
// Author.....: Niels A. Moseley
|
||||
// Date.......: 8-2-2018
|
||||
//
|
||||
|
||||
module debounce(
|
||||
input clk25, // 25MHz clock
|
||||
input rst, // active high reset
|
||||
|
||||
input sig_in, // input signal
|
||||
output reg sig_out // debounced output signal
|
||||
);
|
||||
|
||||
wire clk_enb; // enable triggering at clk25 divided by 64
|
||||
reg [5:0] clk_div; // clock divider counter
|
||||
|
||||
reg sig_ff1; // first input signal synchronizer
|
||||
reg sig_ff2; // second input signal synchronizer
|
||||
|
||||
assign clk_enb = (clk_div == 6'd0);
|
||||
|
||||
// clock divider
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
clk_div <= 6'd0;
|
||||
else
|
||||
clk_div <= clk_div + 6'd1;
|
||||
end
|
||||
|
||||
// debounce timer
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
sig_out <= 1'b0;
|
||||
sig_ff1 <= 1'b0;
|
||||
sig_ff2 <= 1'b0;
|
||||
end
|
||||
else if (clk_enb)
|
||||
begin
|
||||
// this runs ar approximately 391k Hz
|
||||
// giving a debounce time of around 2.5us
|
||||
sig_ff1 <= sig_in;
|
||||
sig_ff2 <= sig_ff1;
|
||||
if ((sig_ff1 ^ sig_ff2) == 1'd0)
|
||||
begin
|
||||
sig_out <= sig_ff2;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -35,21 +35,16 @@ module ps2keyboard (
|
||||
output reg [7:0] dout // 8-bit output bus.
|
||||
);
|
||||
|
||||
// ************************************************************
|
||||
// signals in the slow PS/2 clock domain
|
||||
// ************************************************************
|
||||
reg [3:0] rxcnt; // count how many bits have been shift into rxshiftbuf
|
||||
reg [10:0] rxshiftbuf; // 11 bit shift receive register
|
||||
reg rx_flag = 0; // this flag changes state (0->1 or 1->0) when
|
||||
reg rx_flag = 0; // this flag is 1 when
|
||||
// valid data is available in rxshiftbuf
|
||||
|
||||
// ************************************************************
|
||||
// signals in the high-speed clock (clk25) domain
|
||||
// ************************************************************
|
||||
reg [7:0] rx; // receive buffer
|
||||
reg rxflag_ff; // flip-flop state for clk domain xing
|
||||
reg rx_rdy; // data ready to be read
|
||||
reg [7:0] rx; // scancode receive buffer
|
||||
|
||||
wire ps2_clkdb; // debounced PS/2 clock signal
|
||||
reg prev_ps2_clkdb; // previous clock state (in clk25 domain)
|
||||
|
||||
// keyboard translation signals
|
||||
reg [7:0] ascii; // ASCII code of received character
|
||||
reg ascii_rdy; // new ASCII character received
|
||||
@ -58,53 +53,55 @@ module ps2keyboard (
|
||||
reg [2:0] next_state;
|
||||
reg [15:0] debounce_timer;
|
||||
|
||||
//
|
||||
// PS/2 data from a device changes when the clock
|
||||
// is low, so we latch when the clock transitions
|
||||
// to a high state
|
||||
//
|
||||
|
||||
always @(negedge key_clk or posedge rst)
|
||||
begin
|
||||
if (rst == 1'b1)
|
||||
debounce ps2clk_debounce
|
||||
(
|
||||
.clk25(clk25),
|
||||
.rst(rst),
|
||||
.sig_in(key_clk),
|
||||
.sig_out(ps2_clkdb)
|
||||
);
|
||||
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
// reset the serial buffer
|
||||
rxshiftbuf <= 11'b0;
|
||||
rxcnt <= 0;
|
||||
rx_flag <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// shift in LSB first from keyboard
|
||||
rxshiftbuf <= {key_din, rxshiftbuf[10:1]};
|
||||
rxcnt <= rxcnt + 4'b1;
|
||||
if (rxcnt == 4'd10)
|
||||
if (rst)
|
||||
begin
|
||||
// 10 bits have been shifted in
|
||||
// we should have a complete
|
||||
// scan code here, including
|
||||
// start, parity and stop bits.
|
||||
rxcnt <= 0;
|
||||
rx_flag <= !rx_flag; // change state to signal new data
|
||||
prev_ps2_clkdb <= 1'b0;
|
||||
rx_flag <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
rx_flag <= 1'b0; // reset the new data flag register
|
||||
|
||||
// check for negative edge of PS/2 clock
|
||||
// and sample the state of the PS/2 data line
|
||||
if ((prev_ps2_clkdb == 1'b1) && (ps2_clkdb == 1'b0))
|
||||
begin
|
||||
rxshiftbuf <= {key_din, rxshiftbuf[10:1]};
|
||||
rxcnt <= rxcnt + 4'b1;
|
||||
if (rxcnt == 4'd10)
|
||||
begin
|
||||
// 10 bits have been shifted in
|
||||
// we should have a complete
|
||||
// scan code here, including
|
||||
// start, parity and stop bits.
|
||||
rxcnt <= 0;
|
||||
|
||||
// signal new data is present
|
||||
// note: this signal will only remain high for one
|
||||
// clock cycle!
|
||||
//
|
||||
// TODO: check parity here?
|
||||
rx_flag <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// update previous clock state
|
||||
prev_ps2_clkdb <= ps2_clkdb;
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//
|
||||
// clock domain crossing from slow PS/2 clock to
|
||||
// high-speed clock domain:
|
||||
//
|
||||
// --------------| |
|
||||
// | _______ | XOR |----> rx_valid_stb
|
||||
// flag ---| D Q |----| |
|
||||
// | |
|
||||
// clk ----|> |
|
||||
// |_______|
|
||||
//
|
||||
// when flag toggles state, tx_valid_stb will become
|
||||
// '1' for exactly one (high-speed) clock cycle.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// IBM Keyboard code page translation
|
||||
// state machine for US keyboard layout
|
||||
@ -112,248 +109,225 @@ end
|
||||
// http://www.computer-engineering.org/ps2keyboard/scancodes2.html
|
||||
//
|
||||
|
||||
localparam S_KEYNORMAL = 3'b000;
|
||||
localparam S_KEYF0 = 3'b001; // regular key release state
|
||||
localparam S_KEYE0 = 3'b010; // extended key state
|
||||
localparam S_KEYE0F0 = 3'b011; // extended release state
|
||||
localparam S_KEYNORMAL = 3'b000;
|
||||
localparam S_KEYF0 = 3'b001; // regular key release state
|
||||
localparam S_KEYE0 = 3'b010; // extended key state
|
||||
localparam S_KEYE0F0 = 3'b011; // extended release state
|
||||
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
rxflag_ff <= 0;
|
||||
rx <= 0;
|
||||
rx_rdy <= 0;
|
||||
ascii_rdy <= 0;
|
||||
shift <= 0;
|
||||
cur_state <= S_KEYNORMAL;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// check for new RX data from the keyboard
|
||||
rxflag_ff <= rx_flag;
|
||||
|
||||
if ((rxflag_ff ^ rx_flag) == 1'b1)
|
||||
if (rst)
|
||||
begin
|
||||
// we detected a change in the rx_flag
|
||||
// so we have valid data in the rxshiftbuf
|
||||
|
||||
// bits 8 .. 1 contain the actual keyboard
|
||||
// scan code. The other bits are start/parity
|
||||
// and stop bits.
|
||||
//
|
||||
// TODO: do a parity check! ..
|
||||
rx <= rxshiftbuf[8:1];
|
||||
rx_rdy <= 1;
|
||||
end
|
||||
|
||||
// handle I/O from CPU
|
||||
if (cs == 1'b1)
|
||||
begin
|
||||
if (address == 1'b0)
|
||||
begin
|
||||
// RX buffer address
|
||||
dout <= {1'b1, ascii[6:0]};
|
||||
ascii_rdy <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// RX status register
|
||||
dout <= {ascii_rdy, 7'b0};
|
||||
end
|
||||
end
|
||||
|
||||
// handle the debounce timer
|
||||
if (debounce_timer != 16'd0)
|
||||
begin
|
||||
debounce_timer <= debounce_timer - 16'd1;
|
||||
end
|
||||
|
||||
// keyboard translation state machine
|
||||
if (rx_rdy == 1'b1)
|
||||
begin
|
||||
rx_rdy <= 1'b0;
|
||||
case(cur_state)
|
||||
S_KEYNORMAL:
|
||||
begin
|
||||
if (rx == 8'hF0)
|
||||
next_state = S_KEYF0;
|
||||
else if (rx == 8'hE0)
|
||||
next_state = S_KEYE0;
|
||||
else
|
||||
begin
|
||||
// check the debounce timer, if this is
|
||||
// not zero, a new key arrived too quickly
|
||||
// and we simply discard it. For better
|
||||
// debouncing, we should check if the key
|
||||
// is actually the same as the previous received/
|
||||
// key, but let's try this first to see if it works
|
||||
// ok...
|
||||
|
||||
if (debounce_timer == 16'd0)
|
||||
begin
|
||||
ascii_rdy <= 1'b1; // new key has arrived!
|
||||
debounce_timer <= 16'hFFFF; // reset the debounce timer
|
||||
end
|
||||
|
||||
// check for a SHIFT key
|
||||
if ((rx == 8'h59) || (rx == 8'h12))
|
||||
begin
|
||||
shift <= 1'b1;
|
||||
ascii_rdy <= 1'b0; // shift is not a key!
|
||||
end
|
||||
else begin
|
||||
if (!shift)
|
||||
case(rx)
|
||||
8'h1C: ascii <= "A";
|
||||
8'h32: ascii <= "B";
|
||||
8'h21: ascii <= "C";
|
||||
8'h23: ascii <= "D";
|
||||
8'h24: ascii <= "E";
|
||||
8'h2B: ascii <= "F";
|
||||
8'h34: ascii <= "G";
|
||||
8'h33: ascii <= "H";
|
||||
8'h43: ascii <= "I";
|
||||
8'h3B: ascii <= "J";
|
||||
8'h42: ascii <= "K";
|
||||
8'h4B: ascii <= "L";
|
||||
8'h3A: ascii <= "M";
|
||||
8'h31: ascii <= "N";
|
||||
8'h44: ascii <= "O";
|
||||
8'h4D: ascii <= "P";
|
||||
8'h15: ascii <= "Q";
|
||||
8'h2D: ascii <= "R";
|
||||
8'h1B: ascii <= "S";
|
||||
8'h2C: ascii <= "T";
|
||||
8'h3C: ascii <= "U";
|
||||
8'h2A: ascii <= "V";
|
||||
8'h1D: ascii <= "W";
|
||||
8'h22: ascii <= "X";
|
||||
8'h35: ascii <= "Y";
|
||||
8'h1A: ascii <= "Z";
|
||||
|
||||
8'h45: ascii <= "0";
|
||||
8'h16: ascii <= "1";
|
||||
8'h1E: ascii <= "2";
|
||||
8'h26: ascii <= "3";
|
||||
8'h25: ascii <= "4";
|
||||
8'h2E: ascii <= "5";
|
||||
8'h36: ascii <= "6";
|
||||
8'h3D: ascii <= "7";
|
||||
8'h3E: ascii <= "8";
|
||||
8'h46: ascii <= "9";
|
||||
|
||||
8'h4E: ascii <= "-";
|
||||
8'h55: ascii <= "=";
|
||||
8'h5D: ascii <= "\\ "; // extra spaced needed by Quartus
|
||||
8'h66: ascii <= 8'd8; // backspace
|
||||
8'h29: ascii <= " ";
|
||||
|
||||
8'h5A: ascii <= 8'd13; // enter
|
||||
8'h54: ascii <= "[";
|
||||
8'h5B: ascii <= "]";
|
||||
8'h4C: ascii <= ";";
|
||||
8'h52: ascii <= "'";
|
||||
8'h41: ascii <= ",";
|
||||
8'h49: ascii <= ".";
|
||||
8'h4A: ascii <= "/";
|
||||
8'h59: shift <= 1'b1; // right shfit
|
||||
8'h12: shift <= 1'b1; // left shift
|
||||
default: ascii <= ".";
|
||||
endcase
|
||||
else
|
||||
// Here, we're in a shifted state
|
||||
case(rx)
|
||||
8'h1C: ascii <= "A";
|
||||
8'h32: ascii <= "B";
|
||||
8'h21: ascii <= "C";
|
||||
8'h23: ascii <= "D";
|
||||
8'h24: ascii <= "E";
|
||||
8'h2B: ascii <= "F";
|
||||
8'h34: ascii <= "G";
|
||||
8'h33: ascii <= "H";
|
||||
8'h43: ascii <= "I";
|
||||
8'h3B: ascii <= "J";
|
||||
8'h42: ascii <= "K";
|
||||
8'h4B: ascii <= "L";
|
||||
8'h3A: ascii <= "M";
|
||||
8'h31: ascii <= "N";
|
||||
8'h44: ascii <= "O";
|
||||
8'h4D: ascii <= "P";
|
||||
8'h15: ascii <= "Q";
|
||||
8'h2D: ascii <= "R";
|
||||
8'h1B: ascii <= "S";
|
||||
8'h2C: ascii <= "T";
|
||||
8'h3C: ascii <= "U";
|
||||
8'h2A: ascii <= "V";
|
||||
8'h1D: ascii <= "W";
|
||||
8'h22: ascii <= "X";
|
||||
8'h35: ascii <= "Y";
|
||||
8'h1A: ascii <= "Z";
|
||||
|
||||
8'h45: ascii <= ")";
|
||||
8'h16: ascii <= "!";
|
||||
8'h1E: ascii <= "@";
|
||||
8'h26: ascii <= "#";
|
||||
8'h25: ascii <= "$";
|
||||
8'h2E: ascii <= "%";
|
||||
8'h36: ascii <= "^";
|
||||
8'h3D: ascii <= "&";
|
||||
8'h3E: ascii <= "*";
|
||||
8'h46: ascii <= "(";
|
||||
|
||||
8'h4E: ascii <= "_";
|
||||
8'h55: ascii <= "+";
|
||||
8'h5D: ascii <= "|";
|
||||
8'h66: ascii <= 8'd8; // backspace
|
||||
8'h29: ascii <= " ";
|
||||
|
||||
8'h5A: ascii <= 8'd13; // enter
|
||||
8'h54: ascii <= "{";
|
||||
8'h5B: ascii <= "}";
|
||||
8'h4C: ascii <= ":";
|
||||
8'h52: ascii <= "\"";
|
||||
8'h41: ascii <= "<";
|
||||
8'h49: ascii <= ">";
|
||||
8'h4A: ascii <= "?";
|
||||
default: ascii <= ".";
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
S_KEYF0:
|
||||
// when we end up here, a 0xF0 byte was received
|
||||
// which usually means a key release event
|
||||
begin
|
||||
if ((rx == 8'h59) || (rx == 8'h12))
|
||||
shift <= 1'b0;
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
S_KEYE0:
|
||||
begin
|
||||
if (rx == 8'hF0)
|
||||
next_state = S_KEYE0F0;
|
||||
else
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
S_KEYE0F0:
|
||||
begin
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
endcase;
|
||||
rx <= 0;
|
||||
ascii_rdy <= 0;
|
||||
shift <= 0;
|
||||
cur_state <= S_KEYNORMAL;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state = cur_state;
|
||||
end
|
||||
// handle I/O from CPU
|
||||
if (cs == 1'b1)
|
||||
begin
|
||||
if (address == 1'b0)
|
||||
begin
|
||||
// RX buffer address
|
||||
dout <= {1'b1, ascii[6:0]};
|
||||
ascii_rdy <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// RX status register
|
||||
dout <= {ascii_rdy, 7'b0};
|
||||
end
|
||||
end
|
||||
|
||||
// keyboard translation state machine
|
||||
if (rx_flag == 1'b1)
|
||||
begin
|
||||
// latch data from the serial buffer into
|
||||
// the rx scancode buffer.
|
||||
rx <= rxshiftbuf[8:1];
|
||||
case(cur_state)
|
||||
S_KEYNORMAL:
|
||||
begin
|
||||
if (rx == 8'hF0)
|
||||
next_state = S_KEYF0;
|
||||
else if (rx == 8'hE0)
|
||||
next_state = S_KEYE0;
|
||||
else
|
||||
begin
|
||||
// check the debounce timer, if this is
|
||||
// not zero, a new key arrived too quickly
|
||||
// and we simply discard it. For better
|
||||
// debouncing, we should check if the key
|
||||
// is actually the same as the previous received/
|
||||
// key, but let's try this first to see if it works
|
||||
// ok...
|
||||
|
||||
//if (debounce_timer == 16'd0)
|
||||
//begin
|
||||
ascii_rdy <= 1'b1; // new key has arrived!
|
||||
//debounce_timer <= 16'hFFFF; // reset the debounce timer
|
||||
//end
|
||||
|
||||
// check for a SHIFT key
|
||||
if ((rx == 8'h59) || (rx == 8'h12))
|
||||
begin
|
||||
shift <= 1'b1;
|
||||
ascii_rdy <= 1'b0; // shift is not a key!
|
||||
end
|
||||
else begin
|
||||
if (!shift)
|
||||
case(rx)
|
||||
8'h1C: ascii <= "A";
|
||||
8'h32: ascii <= "B";
|
||||
8'h21: ascii <= "C";
|
||||
8'h23: ascii <= "D";
|
||||
8'h24: ascii <= "E";
|
||||
8'h2B: ascii <= "F";
|
||||
8'h34: ascii <= "G";
|
||||
8'h33: ascii <= "H";
|
||||
8'h43: ascii <= "I";
|
||||
8'h3B: ascii <= "J";
|
||||
8'h42: ascii <= "K";
|
||||
8'h4B: ascii <= "L";
|
||||
8'h3A: ascii <= "M";
|
||||
8'h31: ascii <= "N";
|
||||
8'h44: ascii <= "O";
|
||||
8'h4D: ascii <= "P";
|
||||
8'h15: ascii <= "Q";
|
||||
8'h2D: ascii <= "R";
|
||||
8'h1B: ascii <= "S";
|
||||
8'h2C: ascii <= "T";
|
||||
8'h3C: ascii <= "U";
|
||||
8'h2A: ascii <= "V";
|
||||
8'h1D: ascii <= "W";
|
||||
8'h22: ascii <= "X";
|
||||
8'h35: ascii <= "Y";
|
||||
8'h1A: ascii <= "Z";
|
||||
|
||||
cur_state <= next_state;
|
||||
8'h45: ascii <= "0";
|
||||
8'h16: ascii <= "1";
|
||||
8'h1E: ascii <= "2";
|
||||
8'h26: ascii <= "3";
|
||||
8'h25: ascii <= "4";
|
||||
8'h2E: ascii <= "5";
|
||||
8'h36: ascii <= "6";
|
||||
8'h3D: ascii <= "7";
|
||||
8'h3E: ascii <= "8";
|
||||
8'h46: ascii <= "9";
|
||||
|
||||
8'h4E: ascii <= "-";
|
||||
8'h55: ascii <= "=";
|
||||
8'h5D: ascii <= 8'h34; // backslash
|
||||
8'h66: ascii <= 8'd8; // backspace
|
||||
8'h29: ascii <= " ";
|
||||
|
||||
8'h5A: ascii <= 8'd13; // enter
|
||||
8'h54: ascii <= "[";
|
||||
8'h5B: ascii <= "]";
|
||||
8'h4C: ascii <= ";";
|
||||
8'h52: ascii <= "'";
|
||||
8'h41: ascii <= ",";
|
||||
8'h49: ascii <= ".";
|
||||
8'h4A: ascii <= "/";
|
||||
8'h59: shift <= 1'b1; // right shfit
|
||||
8'h12: shift <= 1'b1; // left shift
|
||||
default: ascii <= ".";
|
||||
endcase
|
||||
else
|
||||
// Here, we're in a shifted state
|
||||
case(rx)
|
||||
8'h1C: ascii <= "A";
|
||||
8'h32: ascii <= "B";
|
||||
8'h21: ascii <= "C";
|
||||
8'h23: ascii <= "D";
|
||||
8'h24: ascii <= "E";
|
||||
8'h2B: ascii <= "F";
|
||||
8'h34: ascii <= "G";
|
||||
8'h33: ascii <= "H";
|
||||
8'h43: ascii <= "I";
|
||||
8'h3B: ascii <= "J";
|
||||
8'h42: ascii <= "K";
|
||||
8'h4B: ascii <= "L";
|
||||
8'h3A: ascii <= "M";
|
||||
8'h31: ascii <= "N";
|
||||
8'h44: ascii <= "O";
|
||||
8'h4D: ascii <= "P";
|
||||
8'h15: ascii <= "Q";
|
||||
8'h2D: ascii <= "R";
|
||||
8'h1B: ascii <= "S";
|
||||
8'h2C: ascii <= "T";
|
||||
8'h3C: ascii <= "U";
|
||||
8'h2A: ascii <= "V";
|
||||
8'h1D: ascii <= "W";
|
||||
8'h22: ascii <= "X";
|
||||
8'h35: ascii <= "Y";
|
||||
8'h1A: ascii <= "Z";
|
||||
|
||||
8'h45: ascii <= ")";
|
||||
8'h16: ascii <= "!";
|
||||
8'h1E: ascii <= "@";
|
||||
8'h26: ascii <= "#";
|
||||
8'h25: ascii <= "$";
|
||||
8'h2E: ascii <= "%";
|
||||
8'h36: ascii <= "^";
|
||||
8'h3D: ascii <= "&";
|
||||
8'h3E: ascii <= "*";
|
||||
8'h46: ascii <= "(";
|
||||
|
||||
8'h4E: ascii <= "_";
|
||||
8'h55: ascii <= "+";
|
||||
8'h5D: ascii <= "|";
|
||||
8'h66: ascii <= 8'd8; // backspace
|
||||
8'h29: ascii <= " ";
|
||||
|
||||
8'h5A: ascii <= 8'd13; // enter
|
||||
8'h54: ascii <= "{";
|
||||
8'h5B: ascii <= "}";
|
||||
8'h4C: ascii <= ":";
|
||||
8'h52: ascii <= "\"";
|
||||
8'h41: ascii <= "<";
|
||||
8'h49: ascii <= ">";
|
||||
8'h4A: ascii <= "?";
|
||||
default: ascii <= ".";
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
S_KEYF0:
|
||||
// when we end up here, a 0xF0 byte was received
|
||||
// which usually means a key release event
|
||||
begin
|
||||
if ((rx == 8'h59) || (rx == 8'h12))
|
||||
shift <= 1'b0;
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
S_KEYE0:
|
||||
begin
|
||||
if (rx == 8'hF0)
|
||||
next_state = S_KEYE0F0;
|
||||
else
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
S_KEYE0F0:
|
||||
begin
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
next_state = S_KEYNORMAL;
|
||||
end
|
||||
endcase;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state = cur_state; // deliberate blocking assingment!
|
||||
end
|
||||
|
||||
cur_state <= next_state;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Converts vga_font.bin into vga_font.hex
|
||||
|
||||
/* Converts vga_font.bin into vga_font.hex
|
||||
|
||||
Author: Niels A. Moseley
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include<stdio.h>
|
||||
@ -12,22 +12,22 @@ const char hextbl[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("VGAROMGEN v1.0\n");
|
||||
|
||||
|
||||
FILE *fin = fopen("../../roms/vga_font.bin","rt");
|
||||
if (fin == NULL)
|
||||
{
|
||||
printf("Error: cannot open vga_font.bin!\n");
|
||||
printf("Error: cannot open vga_font.bin!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
FILE *fout = fopen("../../roms/vga_font_bitreversed.hex","wt");
|
||||
if (fout == NULL)
|
||||
{
|
||||
printf("Error: cannot open vga_font_bitreversed.hex for writing!\n");
|
||||
printf("Error: cannot open vga_font_bitreversed.hex for writing!\n");
|
||||
fclose(fin);
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint8_t count = 0;
|
||||
uint8_t byte = 0;
|
||||
uint32_t bytecount = 0;
|
||||
@ -39,7 +39,7 @@ int main(int argc, char *argv[])
|
||||
byte >>= 1;
|
||||
if (c == '1')
|
||||
byte |= 0x80;
|
||||
|
||||
|
||||
count++;
|
||||
if (count == 8)
|
||||
{
|
||||
@ -52,9 +52,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("Done: converted %d bytes\n", bytecount);
|
||||
|
||||
|
||||
fclose(fout);
|
||||
fclose(fin);
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user