Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USB keyboard support #23

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions boards/ice40hx8k-b-evn/ice40hx8k.pcf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ set_io led[0] C3
set_io ps2_clk N3
set_io ps2_din N2

### USB Keyboard
set_io usb_dp P15
set_io usb_dm R15

### VGA Display
set_io vga_h_sync C2
set_io vga_v_sync D1
Expand Down
4 changes: 4 additions & 0 deletions boards/ice40hx8k-b-evn/yosys/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ $(BUILDDIR)/apple1.blif: $(SOURCEDIR)/apple1.v \
$(SOURCEDIR)/vga/font_rom.v \
$(SOURCEDIR)/ps2keyboard/debounce.v \
$(SOURCEDIR)/ps2keyboard/ps2keyboard.v \
$(SOURCEDIR)/ukp/ukp.v \
$(SOURCEDIR)/ukp/ukpram.v \
$(SOURCEDIR)/ukp/ukprom.v \
$(SOURCEDIR)/ukp/keymap.v \
$(SOURCEDIR)/boards/ice40hx8k-b-evn/apple1_hx8k.v \
$(BUILDDIR)/pll.sv

Expand Down
37 changes: 37 additions & 0 deletions rtl/apple1.v
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module apple1 #(
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
) (
input clk25, // 25 MHz master clock
input clkusb, // 12 MHz usb clock
input rst_n, // active low synchronous reset (needed for simulation)

// I/O interface to computer
Expand All @@ -42,6 +43,13 @@ module apple1 #(
input ps2_din, // PS/2 keyboard serial data input
input ps2_select, // Input to select the PS/2 keyboard instead of the UART

// I/O interface to USB keyboard
input usb_dm_in, // USB keyboard minus pin
input usb_dp_in, // USB keyboard plus pin
output usb_en,
output usb_dm_out, // USB keyboard minus pin
output usb_dp_out, // USB keyboard plus pin

// Outputs to VGA display
output vga_h_sync, // hozizontal VGA sync pulse
output vga_v_sync, // vertical VGA sync pulse
Expand Down Expand Up @@ -104,6 +112,9 @@ module apple1 #(

wire ram_cs = (ab[15:13] == 3'b000); // 0x0000 -> 0x1FFF

// ukp
wire ukp_cs = (ab[15:12] == 4'b1011); // 0xB000 -> 0xBFFF

// font mode, background and foreground colour
wire vga_mode_cs = (ab[15:2] == 14'b11000000000000); // 0xC000 -> 0xC003

Expand Down Expand Up @@ -226,6 +237,31 @@ module apple1 #(
.clr_screen(vga_cls)
);

// USB keyboard interface
reg [7:0] ukp_dout;
wire [7:0] ukp_d;
wire usb_int;
ukp my_ukp(
.clk25(clk25),
.clkusb(clkusb),
.rst(rst),
.usb_en(usb_en),
.usb_dm_in(usb_dm_in),
.usb_dp_in(usb_dp_in),
.usb_dm_out(usb_dm_out),
.usb_dp_out(usb_dp_out),
.record_n(usb_int),
.kbd_adr(ab[3:0]),
.kbd_data(ukp_d),
.debug(debug)
);

always @(posedge clk25)
begin
if (usb_int)
ukp_dout <= ukp_d;
end

// Handle font mode and foreground and background
// colours. This so isn't Apple One authentic, but
// it can't hurt to have some fun. :D
Expand Down Expand Up @@ -274,5 +310,6 @@ module apple1 #(
uart_cs ? uart_dout :
ps2kb_cs ? ps2_dout :
vga_mode_cs ? vga_mode_dout :
ukp_cs ? ukp_dout :
8'hFF;
endmodule
32 changes: 32 additions & 0 deletions rtl/boards/ice40hx8k-b-evn/apple1_hx8k.v
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ module apple1_top #(
input ps2_clk, // PS/2 keyboard serial clock input
input ps2_din, // PS/2 keyboard serial data input

// I/O interface to USB keyboard
inout usb_dm, // USB keyboard minus pin
inout usb_dp, // USB keyboard plus pin

// Outputs to VGA display
output vga_h_sync, // hozizontal VGA sync pulse
output vga_v_sync, // vertical VGA sync pulse
Expand Down Expand Up @@ -126,6 +130,28 @@ module apple1_top #(
always @(posedge ps2_toggle)
ps2_select <= ~ps2_select;

wire usb_en;
wire usb_dm_in, usb_dp_in;
wire usb_dm_out, usb_dp_out;
SB_IO #(
.PIN_TYPE(6'b101001),
.PULLUP(1'b1)
) tm_dm_io (
.PACKAGE_PIN(usb_dm),
.OUTPUT_ENABLE(usb_en),
.D_IN_0(usb_dm_in),
.D_OUT_0(usb_dm_out)
);
SB_IO #(
.PIN_TYPE(6'b101001),
.PULLUP(1'b1)
) tm_dp_io (
.PACKAGE_PIN(usb_dp),
.OUTPUT_ENABLE(usb_en),
.D_IN_0(usb_dp_in),
.D_OUT_0(usb_dp_out)
);

//////////////////////////////////////////////////////////////////////////
// Core of system

Expand All @@ -138,13 +164,19 @@ module apple1_top #(
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
) my_apple1(
.clk25(clk25),
.clkusb(clk),
.rst_n(reset_n),
.uart_rx(uart_rx),
.uart_tx(uart_tx),
.uart_cts(uart_cts),
.ps2_clk(ps2__clk),
.ps2_din(ps2__din),
.ps2_select(ps2_select),
.usb_en(usb_en),
.usb_dm_in(usb_dm_in),
.usb_dp_in(usb_dp_in),
.usb_dm_out(usb_dm_out),
.usb_dp_out(usb_dp_out),
.vga_h_sync(vga_h_sync),
.vga_v_sync(vga_v_sync),
.vga_red(vga_red),
Expand Down
154 changes: 154 additions & 0 deletions rtl/ukp/keymap.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
module keymap(
clk,
adr,
data
);
input clk;
input [7:0] adr;
output [7:0] data;

reg [7:0] data;

always @(posedge clk)
begin
case (adr)
8'h00: data <= 8'b00000000;
8'h01: data <= 8'b00000000;
8'h02: data <= 8'b00000000;
8'h03: data <= 8'b00000000;
8'h04: data <= 8'b10010001;
8'h05: data <= 8'b10010010;
8'h06: data <= 8'b10010011;
8'h07: data <= 8'b10010100;
8'h08: data <= 8'b10010101;
8'h09: data <= 8'b10010110;
8'h0a: data <= 8'b10010111;
8'h0b: data <= 8'b10011000;
8'h0c: data <= 8'b10011001;
8'h0d: data <= 8'b10011010;
8'h0e: data <= 8'b10011011;
8'h0f: data <= 8'b10011100;
8'h10: data <= 8'b10011101;
8'h11: data <= 8'b10011110;
8'h12: data <= 8'b10011111;
8'h13: data <= 8'b10100000;
8'h14: data <= 8'b10100001;
8'h15: data <= 8'b10100010;
8'h16: data <= 8'b10100011;
8'h17: data <= 8'b10100100;
8'h18: data <= 8'b10100101;
8'h19: data <= 8'b10100110;
8'h1a: data <= 8'b10100111;
8'h1b: data <= 8'b10101000;
8'h1c: data <= 8'b10101001;
8'h1d: data <= 8'b10101010;
8'h1e: data <= 8'b10110001;
8'h1f: data <= 8'b10110010;
8'h20: data <= 8'b10110011;
8'h21: data <= 8'b10110100;
8'h22: data <= 8'b10110101;
8'h23: data <= 8'b10110110;
8'h24: data <= 8'b10110111;
8'h25: data <= 8'b10111000;
8'h26: data <= 8'b10111001;
8'h27: data <= 8'b10110000;
8'h28: data <= 8'b10001111;
8'h29: data <= 8'b11001111;
8'h2a: data <= 8'b11000011;
8'h2b: data <= 8'b00000000;
8'h2c: data <= 8'b11001110;
8'h2d: data <= 8'b10101111;
8'h2e: data <= 8'b10101110;
8'h2f: data <= 8'b10010000;
8'h30: data <= 8'b10101011;
8'h31: data <= 8'b10101100;
8'h32: data <= 8'b00000000;
8'h33: data <= 8'b10111011;
8'h34: data <= 8'b10111010;
8'h35: data <= 8'b00000000;
8'h36: data <= 8'b10111100;
8'h37: data <= 8'b10111101;
8'h38: data <= 8'b10111110;
8'h39: data <= 8'b00000001;
8'h3a: data <= 8'b11001001;
8'h3b: data <= 8'b11001010;
8'h3c: data <= 8'b11001011;
8'h3d: data <= 8'b11001100;
8'h3e: data <= 8'b11001101;
8'h3f: data <= 8'b00000000;
8'h40: data <= 8'b00000000;
8'h41: data <= 8'b00000000;
8'h42: data <= 8'b00000000;
8'h43: data <= 8'b00000000;
8'h44: data <= 8'b00000000;
8'h45: data <= 8'b11001000;
8'h46: data <= 8'b00000000;
8'h47: data <= 8'b00000000;
8'h48: data <= 8'b00000000;
8'h49: data <= 8'b00000000;
8'h4a: data <= 8'b00000000;
8'h4b: data <= 8'b00000000;
8'h4c: data <= 8'b00000000;
8'h4d: data <= 8'b00000000;
8'h4e: data <= 8'b00000000;
8'h4f: data <= 8'b11000010;
8'h50: data <= 8'b00000000;
8'h51: data <= 8'b00000000;
8'h52: data <= 8'b11000001;
8'h53: data <= 8'b11000000;
8'h54: data <= 8'b00000000;
8'h55: data <= 8'b10001010;
8'h56: data <= 8'b00000000;
8'h57: data <= 8'b10001011;
8'h58: data <= 8'b10001111;
8'h59: data <= 8'b10000001;
8'h5a: data <= 8'b10000010;
8'h5b: data <= 8'b10000011;
8'h5c: data <= 8'b10000100;
8'h5d: data <= 8'b10000101;
8'h5e: data <= 8'b10000110;
8'h5f: data <= 8'b10000111;
8'h60: data <= 8'b10001000;
8'h61: data <= 8'b10001001;
8'h62: data <= 8'b10000000;
8'h63: data <= 8'b10001110;
8'h64: data <= 8'b00000000;
8'h65: data <= 8'b00000000;
8'h66: data <= 8'b00000000;
8'h67: data <= 8'b10001100;
8'h68: data <= 8'b00000000;
8'h69: data <= 8'b00000000;
8'h6a: data <= 8'b00000000;
8'h6b: data <= 8'b00000000;
8'h6c: data <= 8'b00000000;
8'h6d: data <= 8'b00000000;
8'h6e: data <= 8'b00000000;
8'h6f: data <= 8'b00000000;
8'h70: data <= 8'b00000000;
8'h71: data <= 8'b00000000;
8'h72: data <= 8'b00000000;
8'h73: data <= 8'b00000000;
8'h74: data <= 8'b00000000;
8'h75: data <= 8'b00000000;
8'h76: data <= 8'b00000000;
8'h77: data <= 8'b00000000;
8'h78: data <= 8'b00000000;
8'h79: data <= 8'b00000000;
8'h7a: data <= 8'b00000000;
8'h7b: data <= 8'b00000000;
8'h7c: data <= 8'b00000000;
8'h7d: data <= 8'b00000000;
8'h7e: data <= 8'b00000000;
8'h7f: data <= 8'b00000000;
8'h80: data <= 8'b00000000;
8'h81: data <= 8'b00000000;
8'h9b: data <= 8'b11111111;
8'h9d: data <= 8'b11111000;
8'hda: data <= 8'b11111110;
8'hdc: data <= 8'b11111011;
8'hde: data <= 8'b11111101;
8'he0: data <= 8'b11111100;
default: data <= 8'bXXXXXXXX;
endcase
end
endmodule
Loading