mirror of
https://github.com/alangarf/apple-one.git
synced 2026-10-22 02:02:34 +00:00
Merge pull request #47 from alangarf/tang_primer_25k
Added tang primer 25k with ukp usb keyboard
This commit is contained in:
28 files changed
+2950
-892
No files matched your search
@@ -8,3 +8,6 @@ synlog.tcl
|
||||
*_tb
|
||||
*.vcd
|
||||
build
|
||||
gwsynthesis
|
||||
pnr
|
||||
temp
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1" encoding="UTF-8"?>
|
||||
<!DOCTYPE gowin-fpga-project>
|
||||
<Project>
|
||||
<Template>FPGA</Template>
|
||||
<Version>5</Version>
|
||||
<Device name="GW5A-25A" pn="GW5A-LV25MG121NES">gw5a25a-000</Device>
|
||||
<FileList>
|
||||
<File path="../../rtl/apple1.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/clock.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/cpu/arlet/ALU.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/cpu/arlet/cpu.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/cpu/arlet_6502.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/ps2keyboard/debounce.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/ps2keyboard/ps2keyboard.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/pwr_reset.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/ram.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/rom_basic.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/rom_wozmon.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/uart/async_tx_rx.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/uart/uart.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/usbkeyboard/usb_hid_host.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/usbkeyboard/usb_keyboard.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/usbkeyboard/usb_hid_host_rom.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/vga/font_rom.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/vga/vga.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/vga/vram.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/boards/tang_primer_25k/apple1_primer.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/boards/tang_primer_25k/pll/gowin_pll.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/boards/tang_primer_25k/pll/pll_init.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/boards/tang_primer_25k/pll/gowin_pll_mod.v" type="file.verilog" enable="1"/>
|
||||
<File path="../../rtl/boards/tang_primer_25k/apple1.cst" type="file.cst" enable="1"/>
|
||||
<File path="../../rtl/boards/tang_primer_25k/apple1.sdc" type="file.sdc" enable="1"/>
|
||||
</FileList>
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1" encoding="UTF-8"?>
|
||||
<!DOCTYPE ProjectUserData>
|
||||
<UserConfig>
|
||||
<Version>1.0</Version>
|
||||
<FlowState>
|
||||
<Process ID="Synthesis" State="2"/>
|
||||
<Process ID="Pnr" State="2"/>
|
||||
<Process ID="Gao" State="2"/>
|
||||
<Process ID="Rtl_Gao" State="2"/>
|
||||
<Process ID="Gvio" State="0"/>
|
||||
<Process ID="Place" State="2"/>
|
||||
</FlowState>
|
||||
<ResultFileList>
|
||||
<ResultFile ResultFileType="RES.netlist" ResultFilePath="impl/gwsynthesis/apple-one.vg"/>
|
||||
<ResultFile ResultFileType="RES.pnr.bitstream" ResultFilePath="impl/pnr/apple-one.fs"/>
|
||||
<ResultFile ResultFileType="RES.pnr.pin.rpt" ResultFilePath="impl/pnr/apple-one.pin.html"/>
|
||||
<ResultFile ResultFileType="RES.pnr.posp.bin" ResultFilePath="impl/pnr/apple-one.db"/>
|
||||
<ResultFile ResultFileType="RES.pnr.pwr.rpt" ResultFilePath="impl/pnr/apple-one.power.html"/>
|
||||
<ResultFile ResultFileType="RES.pnr.report" ResultFilePath="impl/pnr/apple-one.rpt.html"/>
|
||||
<ResultFile ResultFileType="RES.pnr.timing.paths" ResultFilePath="impl/pnr/apple-one.timing_paths"/>
|
||||
<ResultFile ResultFileType="RES.pnr.timing.rpt" ResultFilePath="impl/pnr/apple-one.tr.html"/>
|
||||
<ResultFile ResultFileType="RES.syn.report" ResultFilePath="impl/gwsynthesis/apple-one_syn.rpt.html"/>
|
||||
<ResultFile ResultFileType="RES.syn.resource" ResultFilePath="impl/gwsynthesis/apple-one_syn_rsc.xml"/>
|
||||
</ResultFileList>
|
||||
<Ui></Ui>
|
||||
<FpUi>312e30313131000000ff00000000fd000000020000000000000100000000b5fc0200000001fc0000003f000000b5000000a40100001efa000000010200000002fb0000001c0044006f0063006b00650072002e00530075006d006d0061007200790100000000ffffffff0000008500fffffffb0000001c0044006f0063006b00650072002e004e00650074006c0069007300740100000000ffffffff0000005b00ffffff0000000300000500000002c6fc0100000001fc00000000000005000000007b00fffffffa00000002010000000bfb0000001c0044006f0063006b00650072002e004d0065007300730061006700650100000000ffffffff0000005800fffffffb0000002c0044006f0063006b00650072002e0049002f004f002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004600fffffffb000000380044006f0063006b00650072002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004600fffffffb000000300044006f0063006b00650072002e00470072006f00750070002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004600fffffffb000000360044006f0063006b00650072002e005200650073006f0075007200630065002e005200650073006500720076006100740069006f006e0100000000ffffffff0000004600fffffffb000000380044006f0063006b00650072002e0043006c006f0063006b002e004e00650074002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004600fffffffb000000420044006f0063006b00650072002e00470043004c004b002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004600fffffffb000000420044006f0063006b00650072002e00480043004c004b002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730000000000ffffffff0000004600fffffffb000000440044006f0063006b00650072002e00470043004c004b0032002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730000000000ffffffff0000004600fffffffb000000460044006f0063006b00650072002e00480043004c004b00350041002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004600fffffffb0000002e0044006f0063006b00650072002e0056007200650066002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004600ffffff000003fa000000b500000004000000040000000800000008fc000000010000000200000001000000180054006f006f006c004200610072002e00460069006c00650100000000ffffffff0000000000000000</FpUi>
|
||||
</UserConfig>
|
||||
@@ -0,0 +1,4 @@
|
||||
open_project "apple-one.gprj"
|
||||
|
||||
# The "all" target will run synthesis, place-and-route, and bitstream generation
|
||||
run all
|
||||
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"BACKGROUND_PROGRAMMING" : "off",
|
||||
"COMPRESS" : false,
|
||||
"CPU" : true,
|
||||
"CRC_CHECK" : true,
|
||||
"Clock_Route_Order" : 0,
|
||||
"Convert_SDP32_36_to_SDP16_18" : true,
|
||||
"Correct_Hold_Violation" : true,
|
||||
"DONE" : true,
|
||||
"DOWNLOAD_SPEED" : "default",
|
||||
"Disable_Insert_Pad" : false,
|
||||
"ENABLE_CTP" : false,
|
||||
"ENABLE_MERGE_MODE" : false,
|
||||
"ENCRYPTION_KEY" : false,
|
||||
"ENCRYPTION_KEY_TEXT" : "00000000000000000000000000000000",
|
||||
"ERROR_DECTION_AND_CORRECTION" : false,
|
||||
"ERROR_DECTION_ONLY" : false,
|
||||
"ERROR_INJECTION" : false,
|
||||
"EXTERNAL_MASTER_CONFIG_CLOCK" : false,
|
||||
"Enable_DSRM" : false,
|
||||
"FORMAT" : "binary",
|
||||
"FREQUENCY_DIVIDER" : "1",
|
||||
"Generate_Constraint_File_of_Ports" : false,
|
||||
"Generate_IBIS_File" : false,
|
||||
"Generate_Plain_Text_Timing_Report" : false,
|
||||
"Generate_Post_PNR_Simulation_Model_File" : false,
|
||||
"Generate_Post_Place_File" : false,
|
||||
"Generate_SDF_File" : false,
|
||||
"Generate_VHDL_Post_PNR_Simulation_Model_File" : false,
|
||||
"Global_Freq" : "default",
|
||||
"GwSyn_Loop_Limit" : 2000,
|
||||
"HOTBOOT" : false,
|
||||
"I2C" : false,
|
||||
"I2C_SLAVE_ADDR" : "00",
|
||||
"INCREMENTAL_PLACE_AND_ROUTING" : "0",
|
||||
"INCREMENTAL_PLACE_ONLY" : "0",
|
||||
"IncludePath" : [
|
||||
|
||||
],
|
||||
"Incremental_Compile" : "",
|
||||
"Initialize_Primitives" : false,
|
||||
"JTAG" : false,
|
||||
"MODE_IO" : false,
|
||||
"MSPI" : false,
|
||||
"MSPI_JUMP" : false,
|
||||
"MULTIBOOT_ADDRESS_WIDTH" : "24",
|
||||
"MULTIBOOT_MODE" : "Single",
|
||||
"MULTIBOOT_SPI_FLASH_ADDRESS" : "000000",
|
||||
"MULTIJUMP_ADDRESS_WIDTH" : "24",
|
||||
"MULTIJUMP_MODE" : "Single",
|
||||
"MULTIJUMP_SPI_FLASH_ADDRESS" : "000000",
|
||||
"Multi_Boot" : false,
|
||||
"OUTPUT_BASE_NAME" : "apple-one",
|
||||
"POWER_ON_RESET_MONITOR" : true,
|
||||
"PRINT_BSRAM_VALUE" : true,
|
||||
"PROGRAM_DONE_BYPASS" : false,
|
||||
"PlaceInRegToIob" : true,
|
||||
"PlaceIoRegToIob" : true,
|
||||
"PlaceOutRegToIob" : true,
|
||||
"Place_Option" : "0",
|
||||
"Process_Configuration_Verion" : "1.0",
|
||||
"Promote_Physical_Constraint_Warning_to_Error" : true,
|
||||
"READY" : true,
|
||||
"RECONFIG_N" : false,
|
||||
"Ram_RW_Check" : false,
|
||||
"Replicate_Resources" : false,
|
||||
"Report_Auto-Placed_Io_Information" : false,
|
||||
"Route_Maxfan" : "23",
|
||||
"Route_Option" : "0",
|
||||
"Run_Timing_Driven" : true,
|
||||
"SECURE_MODE" : false,
|
||||
"SECURITY_BIT" : true,
|
||||
"SEU_HANDLER" : false,
|
||||
"SEU_HANDLER_CHECKSUM" : false,
|
||||
"SEU_HANDLER_MODE" : "auto",
|
||||
"SSPI" : true,
|
||||
"STOP_SEU_HANDLER" : false,
|
||||
"SerDes_retiming" : false,
|
||||
"Show_All_Warnings" : false,
|
||||
"Synthesize_tool" : "GowinSyn",
|
||||
"TclPre" : "",
|
||||
"TopModule" : "apple1_primer",
|
||||
"USERCODE" : "default",
|
||||
"Unused_Pin" : "As_input_tri_stated_with_pull_up",
|
||||
"VCC" : "0.9",
|
||||
"VCCAUX" : "3.3",
|
||||
"VCCX" : "3.3",
|
||||
"VHDL_Standard" : "VHDL_Std_1993",
|
||||
"Verilog_Standard" : "Vlg_Std_Sysv2017",
|
||||
"WAKE_UP" : "0",
|
||||
"show_all_warnings" : false,
|
||||
"turn_off_bg" : false
|
||||
}
|
||||
+266
-225
@@ -23,258 +23,299 @@
|
||||
//
|
||||
|
||||
module apple1 #(
|
||||
parameter BASIC_FILENAME = "../../../roms/basic.hex",
|
||||
parameter FONT_ROM_FILENAME = "../../../roms/vga_font_bitreversed.hex",
|
||||
parameter RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
parameter string BASIC_FILENAME = "../../../roms/basic.hex",
|
||||
parameter string FONT_ROM_FILENAME = "../../../roms/vga_font_bitreversed.hex",
|
||||
parameter string RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter string VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter string WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk25, // 25 MHz master clock
|
||||
input rst_n, // active low synchronous reset (needed for simulation)
|
||||
input clk25, // 25 MHz master clock
|
||||
input rst_n, // active low synchronous reset (needed for simulation)
|
||||
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
|
||||
// I/O interface to keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
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 PS/2 keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// I/O interface to USB keyboard
|
||||
input usb_clk, // 12MHz USB clock
|
||||
inout usb_dm, // USB data minus signal
|
||||
inout usb_dp, // USB data plus signal
|
||||
output usb_led_err, // USB connection error LED
|
||||
output usb_led_act, // USB activity LED
|
||||
|
||||
input [1:0] key_select, // Select the Apple 1 keyboard input
|
||||
// 2'b00 - UART RX
|
||||
// 2'b01 - USB Keyboard
|
||||
// 2'b10 - P/S Keyboard
|
||||
// 2'b11 - None / Other
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output vga_red, // red VGA signal
|
||||
output vga_grn, // green VGA signal
|
||||
output vga_blu, // blue VGA signal
|
||||
input vga_cls, // clear screen button
|
||||
output vga_de, // display enable
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output vga_red, // red VGA signal
|
||||
output vga_grn, // green VGA signal
|
||||
output vga_blu, // blue VGA signal
|
||||
input vga_cls, // clear screen button
|
||||
output vga_de, // display enable
|
||||
|
||||
// Debugging ports
|
||||
output [15:0] pc_monitor // spy for program counter / debugging
|
||||
output [15:0] pc_monitor // spy for program counter / debugging
|
||||
);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
|
||||
wire [15:0] ab;
|
||||
wire [7:0] dbi;
|
||||
wire [7:0] dbo;
|
||||
wire we;
|
||||
wire [15:0] ab;
|
||||
wire [7:0] dbi;
|
||||
wire [7:0] dbo;
|
||||
wire we;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Clocks
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Clocks
|
||||
|
||||
wire cpu_clken;
|
||||
clock my_clock(
|
||||
.clk25(clk25),
|
||||
.rst_n(rst_n),
|
||||
.cpu_clken(cpu_clken)
|
||||
);
|
||||
wire cpu_clken;
|
||||
clock my_clock (
|
||||
.clk25(clk25),
|
||||
.rst_n(rst_n),
|
||||
.cpu_clken(cpu_clken)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Reset
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Reset
|
||||
|
||||
wire rst;
|
||||
pwr_reset my_reset(
|
||||
.clk25(clk25),
|
||||
.rst_n(rst_n),
|
||||
.enable(cpu_clken),
|
||||
.rst(rst)
|
||||
);
|
||||
wire rst;
|
||||
pwr_reset my_reset (
|
||||
.clk25(clk25),
|
||||
.rst_n(rst_n),
|
||||
.enable(cpu_clken),
|
||||
.rst(rst)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 6502
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 6502
|
||||
|
||||
arlet_6502 my_cpu(
|
||||
.clk (clk25),
|
||||
.enable (cpu_clken),
|
||||
.rst (rst),
|
||||
.ab (ab),
|
||||
.dbi (dbi),
|
||||
.dbo (dbo),
|
||||
.we (we),
|
||||
.irq_n (1'b1),
|
||||
.nmi_n (1'b1),
|
||||
.ready (cpu_clken),
|
||||
.pc_monitor (pc_monitor)
|
||||
);
|
||||
arlet_6502 my_cpu (
|
||||
.clk (clk25),
|
||||
.enable (cpu_clken),
|
||||
.rst (rst),
|
||||
.ab (ab),
|
||||
.dbi (dbi),
|
||||
.dbo (dbo),
|
||||
.we (we),
|
||||
.irq_n (1'b1),
|
||||
.nmi_n (1'b1),
|
||||
.ready (cpu_clken),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Address Decoding
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Address Decoding
|
||||
|
||||
wire ram_cs = (ab[15:13] == 3'b000); // 0x0000 -> 0x1FFF
|
||||
reg ram_cs, vga_cs, vga_mode_cs, rx_cs, tx_cs, uart_cs, usb_cs, ps2kb_cs, basic_cs, rom_cs;
|
||||
|
||||
// font mode, background and foreground colour
|
||||
wire vga_mode_cs = (ab[15:2] == 14'b11000000000000); // 0xC000 -> 0xC003
|
||||
always @(posedge clk25 or posedge rst) begin
|
||||
if (rst) begin
|
||||
ram_cs <= 1'd0;
|
||||
vga_mode_cs <= 1'd0;
|
||||
rx_cs <= 1'd0;
|
||||
tx_cs <= 1'd0;
|
||||
uart_cs <= 1'd0;
|
||||
usb_cs <= 1'd0;
|
||||
ps2kb_cs <= 1'd0;
|
||||
basic_cs <= 1'd0;
|
||||
rom_cs <= 1'd0;
|
||||
end else begin
|
||||
// RAM selection
|
||||
ram_cs <= (ab[15:13] == 3'b000); // 0x0000 -> 0x1FFF
|
||||
|
||||
// RX: Either keyboard or UART input
|
||||
// TX: Always VGA and UART output
|
||||
wire rx_cs = (ab[15:1] == 15'b110100000001000); // 0xD010 -> 0xD011
|
||||
wire tx_cs = (ab[15:1] == 15'b110100000001001); // 0xD012 -> 0xD013
|
||||
// font mode, background and foreground colour
|
||||
vga_mode_cs <= (ab[15:2] == 14'b11000000000000); // 0xC000 -> 0xC003
|
||||
|
||||
// select UART on transmit but only receive when PS/2 is not selected.
|
||||
wire uart_cs = tx_cs | ((~ps2_select) & rx_cs);
|
||||
// RX: Either keyboard or UART input
|
||||
// TX: Always VGA and UART output
|
||||
rx_cs <= (ab[15:1] == 15'b110100000001000); // 0xD010 -> 0xD011
|
||||
tx_cs <= (ab[15:1] == 15'b110100000001001); // 0xD012 -> 0xD013
|
||||
|
||||
// select PS/2 keyboard input when selected.
|
||||
wire ps2kb_cs = ps2_select & rx_cs;
|
||||
// select UART on transmit and only receive if key_select is UART
|
||||
uart_cs <= tx_cs | (rx_cs & (key_select == 2'b00));
|
||||
|
||||
// VGA always get characters when they are sent.
|
||||
wire vga_cs = tx_cs;
|
||||
// select USB keyboard input when selected.
|
||||
usb_cs <= rx_cs & (key_select == 2'b01);
|
||||
|
||||
wire basic_cs = (ab[15:12] == 4'b1110); // 0xE000 -> 0xEFFF
|
||||
wire rom_cs = (ab[15:8] == 8'b11111111); // 0xFF00 -> 0xFFFF
|
||||
// select PS/2 keyboard input when selected.
|
||||
ps2kb_cs <= rx_cs & (key_select == 2'b10);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RAM and ROM
|
||||
// VGA always get characters when they are sent.
|
||||
vga_cs <= tx_cs;
|
||||
|
||||
// RAM
|
||||
wire [7:0] ram_dout;
|
||||
ram #(
|
||||
.RAM_FILENAME (RAM_FILENAME)
|
||||
) my_ram(
|
||||
.clk(clk25),
|
||||
.address(ab[12:0]),
|
||||
.w_en(we & ram_cs),
|
||||
.din(dbo),
|
||||
.dout(ram_dout)
|
||||
);
|
||||
|
||||
// WozMon ROM
|
||||
wire [7:0] rom_dout;
|
||||
rom_wozmon #(
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_rom_wozmon(
|
||||
.clk(clk25),
|
||||
.address(ab[7:0]),
|
||||
.dout(rom_dout)
|
||||
);
|
||||
|
||||
// Basic ROM
|
||||
wire [7:0] basic_dout;
|
||||
rom_basic #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME)
|
||||
) my_rom_basic(
|
||||
.clk(clk25),
|
||||
.address(ab[11:0]),
|
||||
.dout(basic_dout)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Peripherals
|
||||
|
||||
// UART
|
||||
wire [7:0] uart_dout;
|
||||
uart #(
|
||||
`ifdef SIM
|
||||
100, 10, 2 // for simulation don't need real baud rates
|
||||
`else
|
||||
25000000, 115200, 8 // 25MHz, 115200 baud, 8 times RX oversampling
|
||||
`endif
|
||||
) my_uart(
|
||||
.clk(clk25),
|
||||
.enable(uart_cs & cpu_clken),
|
||||
.rst(rst),
|
||||
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.address(ab[1:0]), // for uart
|
||||
.w_en(we & uart_cs),
|
||||
.din(dbo),
|
||||
.dout(uart_dout)
|
||||
);
|
||||
|
||||
// PS/2 keyboard interface
|
||||
wire [7:0] ps2_dout;
|
||||
ps2keyboard keyboard(
|
||||
.clk25(clk25),
|
||||
.rst(rst),
|
||||
.key_clk(ps2_clk),
|
||||
.key_din(ps2_din),
|
||||
.cs(ps2kb_cs),
|
||||
.address(ab[0]),
|
||||
.dout(ps2_dout)
|
||||
);
|
||||
|
||||
// VGA Display interface
|
||||
reg [2:0] fg_colour;
|
||||
reg [2:0] bg_colour;
|
||||
reg [1:0] font_mode;
|
||||
reg [7:0] vga_mode_dout;
|
||||
|
||||
vga #(
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME)
|
||||
) my_vga(
|
||||
.clk25(clk25),
|
||||
.enable(vga_cs & cpu_clken),
|
||||
.rst(rst),
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.vga_de(vga_de),
|
||||
|
||||
.address(ab[0]),
|
||||
.w_en(we & vga_cs),
|
||||
.din(dbo),
|
||||
.mode(font_mode),
|
||||
.fg_colour(fg_colour),
|
||||
.bg_colour(bg_colour),
|
||||
.clr_screen(vga_cls)
|
||||
);
|
||||
|
||||
// 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
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
font_mode <= 2'b0;
|
||||
fg_colour <= 3'd7;
|
||||
bg_colour <= 3'd0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case (ab[1:0])
|
||||
2'b00:
|
||||
begin
|
||||
vga_mode_dout = {6'b0, font_mode};
|
||||
if (vga_mode_cs & we & cpu_clken)
|
||||
font_mode <= dbo[1:0];
|
||||
end
|
||||
2'b01:
|
||||
begin
|
||||
vga_mode_dout = {5'b0, fg_colour};
|
||||
if (vga_mode_cs & we & cpu_clken)
|
||||
fg_colour <= dbo[2:0];
|
||||
end
|
||||
2'b10:
|
||||
begin
|
||||
vga_mode_dout = {5'b0, bg_colour};
|
||||
if (vga_mode_cs & we & cpu_clken)
|
||||
bg_colour <= dbo[2:0];
|
||||
end
|
||||
default:
|
||||
vga_mode_dout = 8'b0;
|
||||
endcase
|
||||
end
|
||||
// ROM selection
|
||||
basic_cs <= (ab[15:12] == 4'b1110); // 0xE000 -> 0xEFFF
|
||||
rom_cs <= (ab[15:8] == 8'b11111111); // 0xFF00 -> 0xFFFF
|
||||
end
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPU Data In MUX
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RAM and ROM
|
||||
|
||||
// link up chip selected device to cpu input
|
||||
assign dbi = ram_cs ? ram_dout :
|
||||
rom_cs ? rom_dout :
|
||||
basic_cs ? basic_dout :
|
||||
uart_cs ? uart_dout :
|
||||
ps2kb_cs ? ps2_dout :
|
||||
vga_mode_cs ? vga_mode_dout :
|
||||
8'hFF;
|
||||
// RAM
|
||||
wire [7:0] ram_dout;
|
||||
ram #(
|
||||
.RAM_FILENAME(RAM_FILENAME)
|
||||
) my_ram (
|
||||
.clk(clk25),
|
||||
.address(ab[12:0]),
|
||||
.w_en(we & ram_cs),
|
||||
.din(dbo),
|
||||
.dout(ram_dout)
|
||||
);
|
||||
|
||||
// WozMon ROM
|
||||
wire [7:0] rom_dout;
|
||||
rom_wozmon #(
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_rom_wozmon (
|
||||
.clk(clk25),
|
||||
.address(ab[7:0]),
|
||||
.dout(rom_dout)
|
||||
);
|
||||
|
||||
// Basic ROM
|
||||
wire [7:0] basic_dout;
|
||||
rom_basic #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME)
|
||||
) my_rom_basic (
|
||||
.clk(clk25),
|
||||
.address(ab[11:0]),
|
||||
.dout(basic_dout)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Peripherals
|
||||
|
||||
// UART
|
||||
wire [7:0] uart_dout;
|
||||
uart #(
|
||||
`ifdef SIM
|
||||
.ClkFrequency(100),
|
||||
.Baud(10),
|
||||
.Oversampling(2) // for simulation don't need real baud rates
|
||||
`else
|
||||
.ClkFrequency(25000000),
|
||||
.Baud(115200),
|
||||
.Oversampling(8) // 25MHz, 115200 baud, 8 times RX oversampling
|
||||
`endif
|
||||
) my_uart (
|
||||
.clk(clk25),
|
||||
.enable(uart_cs & cpu_clken),
|
||||
.rst(rst),
|
||||
|
||||
.uart_rx (uart_rx),
|
||||
.uart_tx (uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.address(ab[1:0]), // for uart
|
||||
.w_en (we & uart_cs),
|
||||
.din (dbo),
|
||||
.dout (uart_dout)
|
||||
);
|
||||
|
||||
// USB Keyboard
|
||||
wire [7:0] usb_dout;
|
||||
usb_keyboard my_usb_keyboard (
|
||||
.usb_clk(usb_clk),
|
||||
.rst(rst),
|
||||
.usb_dm(usb_dm),
|
||||
.usb_dp(usb_dp),
|
||||
.cs(usb_cs),
|
||||
.address(ab[0]),
|
||||
.dout(usb_dout),
|
||||
.led_connerr(usb_led_err),
|
||||
.led_activity(usb_led_act)
|
||||
);
|
||||
|
||||
// PS/2 keyboard interface
|
||||
wire [7:0] ps2_dout;
|
||||
ps2keyboard my_ps2_keyboard (
|
||||
.clk25(clk25),
|
||||
.rst(rst),
|
||||
.key_clk(ps2_clk),
|
||||
.key_din(ps2_din),
|
||||
.cs(ps2kb_cs),
|
||||
.address(ab[0]),
|
||||
.dout(ps2_dout)
|
||||
);
|
||||
|
||||
// VGA Display interface
|
||||
reg [2:0] fg_colour;
|
||||
reg [2:0] bg_colour;
|
||||
reg [1:0] font_mode;
|
||||
reg [7:0] vga_mode_dout;
|
||||
|
||||
vga #(
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME)
|
||||
) my_vga (
|
||||
.clk25(clk25),
|
||||
.enable(vga_cs & cpu_clken),
|
||||
.rst(rst),
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.vga_de(vga_de),
|
||||
|
||||
.address(ab[0]),
|
||||
.w_en(we & vga_cs),
|
||||
.din(dbo),
|
||||
.mode(font_mode),
|
||||
.fg_colour(fg_colour),
|
||||
.bg_colour(bg_colour),
|
||||
.clr_screen(vga_cls)
|
||||
);
|
||||
|
||||
// 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
|
||||
always @(posedge clk25 or posedge rst) begin
|
||||
if (rst) begin
|
||||
font_mode <= 2'b0;
|
||||
fg_colour <= 3'd7;
|
||||
bg_colour <= 3'd0;
|
||||
end else begin
|
||||
case (ab[1:0])
|
||||
2'b00: begin
|
||||
vga_mode_dout = {6'b0, font_mode};
|
||||
if (vga_mode_cs & we & cpu_clken) font_mode <= dbo[1:0];
|
||||
end
|
||||
2'b01: begin
|
||||
vga_mode_dout = {5'b0, fg_colour};
|
||||
if (vga_mode_cs & we & cpu_clken) fg_colour <= dbo[2:0];
|
||||
end
|
||||
2'b10: begin
|
||||
vga_mode_dout = {5'b0, bg_colour};
|
||||
if (vga_mode_cs & we & cpu_clken) bg_colour <= dbo[2:0];
|
||||
end
|
||||
default: vga_mode_dout = 8'b0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CPU Data In MUX
|
||||
|
||||
// link up chip selected device to cpu input
|
||||
assign dbi = ram_cs ? ram_dout :
|
||||
rom_cs ? rom_dout :
|
||||
basic_cs ? basic_dout :
|
||||
uart_cs ? uart_dout :
|
||||
ps2kb_cs ? ps2_dout :
|
||||
usb_cs ? usb_dout :
|
||||
vga_mode_cs ? vga_mode_dout :
|
||||
8'hFF;
|
||||
endmodule
|
||||
@@ -28,99 +28,99 @@ module apple1_top #(
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk, // 100 MHz board clock
|
||||
input clk, // 100 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer - not used
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer - not used
|
||||
|
||||
// I/O interface to keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
|
||||
output [3:0] vga_r, // red VGA signal
|
||||
output [3:0] vga_g, // green VGA signal
|
||||
output [3:0] vga_b, // blue VGA signal
|
||||
output [3:0] vga_r, // red VGA signal
|
||||
output [3:0] vga_g, // green VGA signal
|
||||
output [3:0] vga_b, // blue VGA signal
|
||||
|
||||
// Debugging ports
|
||||
output [3:0] led,
|
||||
input [1:0] button // 2 buttons on board
|
||||
input [1:0] button // 2 buttons on board
|
||||
);
|
||||
|
||||
assign led[0] = 1;
|
||||
assign led[1] = reset_n;
|
||||
assign led[2] = clr_screen_n;
|
||||
assign led[3] = 0;
|
||||
assign led[0] = 1;
|
||||
assign led[1] = reset_n;
|
||||
assign led[2] = clr_screen_n;
|
||||
assign led[3] = 0;
|
||||
|
||||
wire clk25;
|
||||
wire clk25;
|
||||
|
||||
// ===============================================================
|
||||
// System Clock generation (25MHz)
|
||||
// ===============================================================
|
||||
// ===============================================================
|
||||
// System Clock generation (25MHz)
|
||||
// ===============================================================
|
||||
|
||||
reg [1:0] clkpre = 2'b00; // prescaler, from 100MHz to 25MHz
|
||||
reg [1:0] clkpre = 2'b00; // prescaler, from 100MHz to 25MHz
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
clkpre <= clkpre + 1;
|
||||
end
|
||||
wire clk25 = clkpre[1];
|
||||
always @(posedge clk) begin
|
||||
clkpre <= clkpre + 1;
|
||||
end
|
||||
wire clk25 = clkpre[1];
|
||||
|
||||
wire vga_bit;
|
||||
wire vga_bit;
|
||||
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
assign vga_g[3:0] = vga_bit ? 4'b1111 : 4'b0000;
|
||||
assign vga_b[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
assign vga_g[3:0] = vga_bit ? 4'b1111 : 4'b0000;
|
||||
assign vga_b[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[1]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[1]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.uart_rx (uart_rx),
|
||||
.uart_tx (uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
|
||||
//.ps2_select(1'b0), // PS/2 disabled, UART TX enabled
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
//.vga_grn(vga_bit),
|
||||
//.vga_blu(vga_bit),
|
||||
.vga_cls(~clr_screen_n),
|
||||
);
|
||||
// .key_select(2'b00), // UART enabled
|
||||
.key_select(2'b10), // PS/2 keyboard enabled
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
//.vga_grn(vga_bit),
|
||||
//.vga_blu(vga_bit),
|
||||
.vga_cls(~clr_screen_n),
|
||||
);
|
||||
endmodule
|
||||
@@ -23,135 +23,134 @@
|
||||
//
|
||||
|
||||
module apple1_top #(
|
||||
parameter BASIC_FILENAME = "../../../roms/basic.hex",
|
||||
parameter FONT_ROM_FILENAME = "../../../roms/vga_font_bitreversed.hex",
|
||||
parameter RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
parameter string BASIC_FILENAME = "../../../roms/basic.hex",
|
||||
parameter string FONT_ROM_FILENAME = "../../../roms/vga_font_bitreversed.hex",
|
||||
parameter string RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter string VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter string WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk, // 12 MHz board clock
|
||||
input clk, // 12 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
|
||||
// I/O interface to keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output reg vga_red, // red VGA signal
|
||||
output reg vga_grn, // green VGA signal
|
||||
output reg vga_blu, // blue VGA signal
|
||||
|
||||
// Debugging ports
|
||||
output [7:0] led, // 8 LEDs on the iCE40HX8K board
|
||||
output [7:0] ledx, // 8 LEDs on optionally attached YL-4 board
|
||||
input [3:0] button // 4 buttons on optionally attached YL-4 board
|
||||
output [7:0] led, // 8 LEDs on the iCE40HX8K board
|
||||
output [7:0] ledx, // 8 LEDs on optionally attached YL-4 board
|
||||
input [3:0] button // 4 buttons on optionally attached YL-4 board
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
wire clk25;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
wire clk25;
|
||||
|
||||
wire [15:0] pc_monitor;
|
||||
assign led[7:0] = pc_monitor[7:0];
|
||||
assign ledx[7:0] = ~pc_monitor[15:8];
|
||||
wire [15:0] pc_monitor;
|
||||
assign led[7:0] = pc_monitor[7:0];
|
||||
assign ledx[7:0] = ~pc_monitor[15:8];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Clocks
|
||||
// 12MHz up to 25MHz
|
||||
pll my_pll(
|
||||
.clock_in(clk),
|
||||
.clock_out(clk25)
|
||||
);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Clocks
|
||||
// 12MHz up to 25MHz
|
||||
pll my_pll (
|
||||
.clock_in (clk),
|
||||
.clock_out(clk25)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PS/2 Keyboard
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PS/2 Keyboard
|
||||
|
||||
// PS2 Pullups
|
||||
wire ps2__clk, ps2__din;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b000001),
|
||||
.PULLUP(1'b1)
|
||||
) my_ps2_clk (
|
||||
.PACKAGE_PIN(ps2_clk),
|
||||
.D_IN_0(ps2__clk),
|
||||
);
|
||||
// PS2 Pullups
|
||||
wire ps2__clk, ps2__din;
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b000001),
|
||||
.PULLUP (1'b1)
|
||||
) my_ps2_clk (
|
||||
.PACKAGE_PIN(ps2_clk),
|
||||
.D_IN_0(ps2__clk),
|
||||
);
|
||||
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b000001),
|
||||
.PULLUP(1'b1)
|
||||
) my_ps2_din (
|
||||
.PACKAGE_PIN(ps2_din),
|
||||
.D_IN_0(ps2__din),
|
||||
);
|
||||
SB_IO #(
|
||||
.PIN_TYPE(6'b000001),
|
||||
.PULLUP (1'b1)
|
||||
) my_ps2_din (
|
||||
.PACKAGE_PIN(ps2_din),
|
||||
.D_IN_0(ps2__din),
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Reset, Clear Screen and PS/2 mode selection toggle
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Reset, Clear Screen and PS/2 mode selection toggle
|
||||
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[1]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[1]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
|
||||
// debounce toggle button on PS2 select
|
||||
wire ps2_toggle;
|
||||
reg ps2_select;
|
||||
debounce ps2_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[2]),
|
||||
.sig_out(ps2_toggle)
|
||||
);
|
||||
// debounce toggle button on PS2 select
|
||||
wire ps2_toggle;
|
||||
reg ps2_select;
|
||||
debounce ps2_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[2]),
|
||||
.sig_out(ps2_toggle)
|
||||
);
|
||||
|
||||
// defaults to PS2 mode, but can toggle between
|
||||
// UART and PS2 per button press
|
||||
always @(posedge ps2_toggle)
|
||||
ps2_select <= ~ps2_select;
|
||||
// defaults to PS2 mode, but can toggle between
|
||||
// UART and PS2 per button press
|
||||
always @(posedge ps2_toggle) ps2_select <= ~ps2_select;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Core of system
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Core of system
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk25),
|
||||
.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),
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.vga_cls(~clr_screen_n),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.ps2_clk(ps2__clk),
|
||||
.ps2_din(ps2__din),
|
||||
.key_select(ps2_select ? 2'b10 : 2'b00), // switch between PS/2 or UART
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.vga_cls(~clr_screen_n),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -28,93 +28,93 @@ module apple1_top #(
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk, // 50 MHz board clock
|
||||
input clk, // 50 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer - not used
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer - not used
|
||||
|
||||
// I/O interface to keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
|
||||
// Outputs to the ADV7123 RGB DAC IC
|
||||
output vga_clk,
|
||||
output vga_blank_n,
|
||||
|
||||
output [3:0] vga_r, // red VGA signal
|
||||
output [3:0] vga_g, // green VGA signal
|
||||
output [3:0] vga_b, // blue VGA signal
|
||||
output [3:0] vga_r, // red VGA signal
|
||||
output [3:0] vga_g, // green VGA signal
|
||||
output [3:0] vga_b, // blue VGA signal
|
||||
|
||||
// Debugging ports
|
||||
output [2:0] led,
|
||||
input button, // 1 button on board
|
||||
input button // 1 button on board
|
||||
);
|
||||
|
||||
assign vga_clk = clk25;
|
||||
assign vga_blank_n = 1;
|
||||
assign vga_clk = clk25;
|
||||
assign vga_blank_n = 1;
|
||||
|
||||
// Active low
|
||||
assign led[0] = reset_n;
|
||||
assign led[1] = 1;
|
||||
assign led[2] = 1;
|
||||
// Active low
|
||||
assign led[0] = reset_n;
|
||||
assign led[1] = 1;
|
||||
assign led[2] = 1;
|
||||
|
||||
// ===============================================================
|
||||
// System Clock generation (25MHz)
|
||||
// ===============================================================
|
||||
// ===============================================================
|
||||
// System Clock generation (25MHz)
|
||||
// ===============================================================
|
||||
|
||||
reg clk25 = 1;
|
||||
reg clk25 = 1;
|
||||
|
||||
// generate 25MHz clock from 50MHz master clock
|
||||
always @(posedge clk)
|
||||
begin
|
||||
clk25 <= ~clk25;
|
||||
end
|
||||
// generate 25MHz clock from 50MHz master clock
|
||||
always @(posedge clk) begin
|
||||
clk25 <= ~clk25;
|
||||
end
|
||||
|
||||
wire vga_bit;
|
||||
wire vga_bit;
|
||||
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
assign vga_g[3:0] = vga_bit ? 4'b1111 : 4'b0000;
|
||||
assign vga_b[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
assign vga_g[3:0] = vga_bit ? 4'b1111 : 4'b0000;
|
||||
assign vga_b[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.uart_rx (uart_rx),
|
||||
.uart_tx (uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
|
||||
// .ps2_select(1'b0), // PS/2 disabled, UART TX enabled
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
.vga_cls(~reset_n),
|
||||
);
|
||||
.key_select(2'b10), // PS/2 enabled, UART TX disabled
|
||||
// .key_select(2'b00), // PS/2 disabled, UART TX enabled
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
.vga_cls(~reset_n),
|
||||
);
|
||||
endmodule
|
||||
@@ -29,18 +29,18 @@ module apple1_top #(
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk, // 50 MHz board clock
|
||||
input clk, // 50 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input usb_rx, // asynchronous serial data input from computer
|
||||
output usb_tx, // asynchronous serial data output to computer
|
||||
input usb_rx, // asynchronous serial data input from computer
|
||||
output usb_tx, // asynchronous serial data output to computer
|
||||
|
||||
// I/O interface to keyboard
|
||||
input [1:0] usb_dp, // PS/2 keyboard serial clock input
|
||||
input [1:0] usb_dn, // PS/2 keyboard serial data input
|
||||
input [1:0] usb_dp, // PS/2 keyboard serial clock input
|
||||
input [1:0] usb_dn, // PS/2 keyboard serial data input
|
||||
|
||||
output [1:0] usb_pull_dp, // USB pullup/pulldown
|
||||
output [1:0] usb_pull_dn, // USB pullup/pulldown
|
||||
output [1:0] usb_pull_dp, // USB pullup/pulldown
|
||||
output [1:0] usb_pull_dn, // USB pullup/pulldown
|
||||
|
||||
// DVI port
|
||||
output [3:0] gpdi_dp,
|
||||
@@ -49,75 +49,91 @@ module apple1_top #(
|
||||
output [4:0] led,
|
||||
input [1:0] button
|
||||
);
|
||||
wire uart_cts; // No CTS pin
|
||||
wire uart_cts; // No CTS pin
|
||||
|
||||
wire clkp, clkt; // clkp: 25MHz, clkt: 250MHz
|
||||
dvi_pll pll(clk, clkp, clkt, led[0]);
|
||||
wire clkp, clkt; // clkp: 25MHz, clkt: 250MHz
|
||||
dvi_pll pll (
|
||||
clk,
|
||||
clkp,
|
||||
clkt,
|
||||
led[0]
|
||||
);
|
||||
|
||||
wire vsync, hsync, de;
|
||||
wire [7:0] vga_r, vga_g, vga_b;
|
||||
wire vsync, hsync, de;
|
||||
wire [7:0] vga_r, vga_g, vga_b;
|
||||
|
||||
// Active low
|
||||
assign led[1] = reset_n;
|
||||
assign led[2] = hsync;
|
||||
assign led[3] = 1'b1;
|
||||
assign led[4] = 1'b0;
|
||||
// Active low
|
||||
assign led[1] = reset_n;
|
||||
assign led[2] = hsync;
|
||||
assign led[3] = 1'b1;
|
||||
assign led[4] = 1'b0;
|
||||
|
||||
wire vga_bit;
|
||||
wire vga_bit;
|
||||
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r = vga_bit ? 8'b10000000 : 4'b00000000;
|
||||
assign vga_g = vga_bit ? 8'b11111111 : 4'b00000000;
|
||||
assign vga_b = vga_bit ? 8'b10000000 : 4'b00000000;
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r = vga_bit ? 8'b10000000 : 4'b00000000;
|
||||
assign vga_g = vga_bit ? 8'b11111111 : 4'b00000000;
|
||||
assign vga_b = vga_bit ? 8'b10000000 : 4'b00000000;
|
||||
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clkp),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clkp),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
|
||||
// debounce clear button
|
||||
wire cls;
|
||||
debounce cls_button (
|
||||
.clk25(clkp),
|
||||
.rst(1'b0),
|
||||
.sig_in(~button[1]),
|
||||
.sig_out(cls)
|
||||
);
|
||||
// debounce clear button
|
||||
wire cls;
|
||||
debounce cls_button (
|
||||
.clk25(clkp),
|
||||
.rst(1'b0),
|
||||
.sig_in(~button[1]),
|
||||
.sig_out(cls)
|
||||
);
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clkp),
|
||||
.rst_n(reset_n),
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clkp),
|
||||
.rst_n(reset_n),
|
||||
|
||||
.uart_rx(usb_rx),
|
||||
.uart_tx(usb_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.uart_rx (usb_rx),
|
||||
.uart_tx (usb_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.ps2_clk(usb_dp[0]),
|
||||
.ps2_din(usb_dn[0]),
|
||||
.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
|
||||
// .ps2_select(1'b0), // PS/2 disabled, UART TX enabled
|
||||
.ps2_clk(usb_dp[0]),
|
||||
.ps2_din(usb_dn[0]),
|
||||
|
||||
.vga_h_sync(hsync),
|
||||
.vga_v_sync(vsync),
|
||||
.vga_red(vga_bit),
|
||||
.vga_cls(cls),
|
||||
.vga_de(de)
|
||||
);
|
||||
.key_select(2'b10), // PS/2 enabled, UART TX disabled
|
||||
// .key_select(2'b00), // PS/2 disabled, UART TX enabled
|
||||
|
||||
assign usb_pull_dn[0] = 1'b1; // PS/2 emulation mode
|
||||
assign usb_pull_dp[0] = 1'b1;
|
||||
.vga_h_sync(hsync),
|
||||
.vga_v_sync(vsync),
|
||||
.vga_red(vga_bit),
|
||||
.vga_cls(cls),
|
||||
.vga_de(de)
|
||||
);
|
||||
|
||||
// Convert the signal to DVI and send over HDMI
|
||||
vga2tmds tmds_generator(clkp, clkt, vsync, hsync, de, vga_r, vga_g, vga_b, gpdi_dp);
|
||||
assign usb_pull_dn[0] = 1'b1; // PS/2 emulation mode
|
||||
assign usb_pull_dp[0] = 1'b1;
|
||||
|
||||
// Convert the signal to DVI and send over HDMI
|
||||
vga2tmds tmds_generator (
|
||||
clkp,
|
||||
clkt,
|
||||
vsync,
|
||||
hsync,
|
||||
de,
|
||||
vga_r,
|
||||
vga_g,
|
||||
vga_b,
|
||||
gpdi_dp
|
||||
);
|
||||
endmodule
|
||||
@@ -28,78 +28,79 @@ module apple1_top #(
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk, // 100 MHz board clock
|
||||
input clk, // 100 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer - not used
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer - not used
|
||||
|
||||
// I/O interface to keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
|
||||
output [3:0] vga_r, // red VGA signal
|
||||
output [3:0] vga_g, // green VGA signal
|
||||
output [3:0] vga_b, // blue VGA signal
|
||||
output [3:0] vga_r, // red VGA signal
|
||||
output [3:0] vga_g, // green VGA signal
|
||||
output [3:0] vga_b, // blue VGA signal
|
||||
|
||||
// Debugging ports
|
||||
output [1:0] led,
|
||||
input [1:0] button // 2 buttons on board
|
||||
input [1:0] button // 2 buttons on board
|
||||
);
|
||||
|
||||
assign led[0] = reset_n;
|
||||
assign led[1] = clr_screen_n;
|
||||
assign led[0] = reset_n;
|
||||
assign led[1] = clr_screen_n;
|
||||
|
||||
wire clk25;
|
||||
// 100MHz down to 25MHz
|
||||
pll my_pll(
|
||||
.clock_in(clk),
|
||||
.clock_out(clk25)
|
||||
);
|
||||
wire clk25;
|
||||
// 100MHz down to 25MHz
|
||||
pll my_pll (
|
||||
.clock_in (clk),
|
||||
.clock_out(clk25)
|
||||
);
|
||||
|
||||
wire vga_bit;
|
||||
wire vga_bit;
|
||||
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
assign vga_g[3:0] = vga_bit ? 4'b1111 : 4'b0000;
|
||||
assign vga_b[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
// set the monochrome base colour here..
|
||||
assign vga_r[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
assign vga_g[3:0] = vga_bit ? 4'b1111 : 4'b0000;
|
||||
assign vga_b[3:0] = vga_bit ? 4'b1000 : 4'b0000;
|
||||
|
||||
wire reset_n;
|
||||
assign reset_n = ~button[0];
|
||||
wire reset_n;
|
||||
assign reset_n = ~button[0];
|
||||
|
||||
wire clr_screen_n;
|
||||
assign clr_screen_n = ~button[1];
|
||||
wire clr_screen_n;
|
||||
assign clr_screen_n = ~button[1];
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.uart_rx (uart_rx),
|
||||
.uart_tx (uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
//.ps2_select(1'b1), // PS/2 not working, at the moment
|
||||
.ps2_select(1'b0), // PS/2 disabled, UART TX enabled
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
//.vga_grn(vga_bit),
|
||||
//.vga_blu(vga_bit),
|
||||
.vga_cls(~clr_screen_n),
|
||||
);
|
||||
// .key_select(2'b10), // PS/2 enabled, UART TX disabled
|
||||
.key_select(2'b00), // PS/2 disabled, UART TX enabled
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_bit),
|
||||
//.vga_grn(vga_bit),
|
||||
//.vga_blu(vga_bit),
|
||||
.vga_cls(~clr_screen_n),
|
||||
);
|
||||
endmodule
|
||||
@@ -29,83 +29,84 @@ module apple1_top #(
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk, // 100 MHz board clock
|
||||
input clk, // 100 MHz board clock
|
||||
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
|
||||
// I/O interface to keyboard
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
input ps2_clk, // PS/2 keyboard serial clock input
|
||||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output [2:0] vga_r, // red VGA signal
|
||||
output [2:0] vga_g, // green VGA signal
|
||||
output [2:0] vga_b, // blue VGA signal
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output [2:0] vga_r, // red VGA signal
|
||||
output [2:0] vga_g, // green VGA signal
|
||||
output [2:0] vga_b, // blue VGA signal
|
||||
|
||||
input [1:0] button // 2 buttons on board
|
||||
input [1:0] button // 2 buttons on board
|
||||
);
|
||||
|
||||
wire clk25;
|
||||
wire clk25;
|
||||
|
||||
// 100MHz to 25MHz
|
||||
pll pll(
|
||||
.clock_in(clk),
|
||||
.clock_out(clk25),
|
||||
);
|
||||
// 100MHz to 25MHz
|
||||
pll pll (
|
||||
.clock_in (clk),
|
||||
.clock_out(clk25),
|
||||
);
|
||||
|
||||
wire vga_red, vga_green, vga_blue;
|
||||
assign vga_r[2:0] = {vga_red, vga_red, vga_red};
|
||||
assign vga_g[2:0] = {vga_green, vga_green, vga_green};
|
||||
assign vga_b[2:0] = {vga_blue, vga_blue, vga_blue};
|
||||
wire vga_red, vga_green, vga_blue;
|
||||
assign vga_r[2:0] = {vga_red, vga_red, vga_red};
|
||||
assign vga_g[2:0] = {vga_green, vga_green, vga_green};
|
||||
assign vga_b[2:0] = {vga_blue, vga_blue, vga_blue};
|
||||
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
// debounce reset button
|
||||
wire reset_n;
|
||||
debounce reset_button (
|
||||
.clk25(clk25),
|
||||
.rst(1'b0),
|
||||
.sig_in(button[0]),
|
||||
.sig_out(reset_n)
|
||||
);
|
||||
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[1]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
// debounce clear screen button
|
||||
wire clr_screen_n;
|
||||
debounce clr_button (
|
||||
.clk25(clk25),
|
||||
.rst(~reset_n),
|
||||
.sig_in(button[1]),
|
||||
.sig_out(clr_screen_n)
|
||||
);
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(reset_n),
|
||||
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.uart_rx (uart_rx),
|
||||
.uart_tx (uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
|
||||
//.ps2_select(1'b0), // PS/2 disabled, UART TX enabled
|
||||
.ps2_clk(ps2_clk),
|
||||
.ps2_din(ps2_din),
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_green),
|
||||
.vga_blu(vga_blue),
|
||||
.vga_cls(~clr_screen_n),
|
||||
);
|
||||
.key_select(2'b10), // PS/2 enabled, UART TX disabled
|
||||
// .key_select(2'b00), // PS/2 disabled, UART TX enabled
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_green),
|
||||
.vga_blu(vga_blue),
|
||||
.vga_cls(~clr_screen_n),
|
||||
);
|
||||
endmodule
|
||||
@@ -20,7 +20,7 @@
|
||||
//
|
||||
// Author.....: Niels A. Moseley
|
||||
// Date.......: 11-2-2018
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
module apple1_s3e_starterkit_top #(
|
||||
@@ -29,64 +29,63 @@ module apple1_s3e_starterkit_top #(
|
||||
parameter RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input CLK_50MHZ, // the 50 MHz master clock
|
||||
) (
|
||||
input CLK_50MHZ, // the 50 MHz master clock
|
||||
|
||||
// UART I/O signals
|
||||
output UART_TXD, // UART transmit pin on board
|
||||
input UART_RXD, // UART receive pin on board
|
||||
|
||||
input PS2_KBCLK,
|
||||
input PS2_KBDAT,
|
||||
output UART_TXD, // UART transmit pin on board
|
||||
input UART_RXD, // UART receive pin on board
|
||||
|
||||
input BUTTON, // Button for RESET
|
||||
input SWITCH, // Switch between PS/2 input and UART
|
||||
input PS2_KBCLK,
|
||||
input PS2_KBDAT,
|
||||
|
||||
output VGA_R,
|
||||
output VGA_G,
|
||||
output VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS
|
||||
input BUTTON, // Button for RESET
|
||||
input SWITCH, // Switch between PS/2 input and UART
|
||||
|
||||
output VGA_R,
|
||||
output VGA_G,
|
||||
output VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
reg clk25;
|
||||
wire [15:0] pc_monitor;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
reg clk25;
|
||||
wire [15:0] pc_monitor;
|
||||
|
||||
wire rst_n;
|
||||
assign rst_n = ~BUTTON;
|
||||
wire rst_n;
|
||||
assign rst_n = ~BUTTON;
|
||||
|
||||
// generate 25MHz clock from 50MHz master clock
|
||||
always @(posedge CLK_50MHZ) begin
|
||||
clk25 <= ~clk25;
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Core of system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) apple1_top (
|
||||
.clk25 (clk25),
|
||||
.rst_n (rst_n), // we don't have any reset pulse..
|
||||
.uart_rx (UART_RXD),
|
||||
.uart_tx (UART_TXD),
|
||||
//.uart_cts(UART_CTS), // there is no CTS on the board :(
|
||||
.ps2_clk (PS2_KBCLK),
|
||||
.ps2_din (PS2_KBDAT),
|
||||
.key_select(SWITCH ? 2'b10 : 2'b00), // PS/2 or UART with switch
|
||||
.vga_h_sync(VGA_HS),
|
||||
.vga_v_sync(VGA_VS),
|
||||
.vga_red (VGA_R),
|
||||
.vga_grn (VGA_G),
|
||||
.vga_blu (VGA_B),
|
||||
.vga_cls (~rst_n),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
|
||||
// generate 25MHz clock from 50MHz master clock
|
||||
always @(posedge CLK_50MHZ)
|
||||
begin
|
||||
clk25 <= ~clk25;
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Core of system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) apple1_top(
|
||||
.clk25(clk25),
|
||||
.rst_n(rst_n), // we don't have any reset pulse..
|
||||
.uart_rx(UART_RXD),
|
||||
.uart_tx(UART_TXD),
|
||||
//.uart_cts(UART_CTS), // there is no CTS on the board :(
|
||||
.ps2_clk(PS2_KBCLK),
|
||||
.ps2_din(PS2_KBDAT),
|
||||
.ps2_select(SWITCH),
|
||||
.vga_h_sync(VGA_HS),
|
||||
.vga_v_sync(VGA_VS),
|
||||
.vga_red(VGA_R),
|
||||
.vga_grn(VGA_G),
|
||||
.vga_blu(VGA_B),
|
||||
.vga_cls(~rst_n),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,38 @@
|
||||
IO_LOC "clk" E2;
|
||||
IO_PORT "clk" IO_TYPE=LVCMOS33 PULL_MODE=NONE BANK_VCCIO=3.3;
|
||||
|
||||
IO_LOC "rst" H11;
|
||||
IO_PORT "rst" IO_TYPE=LVCMOS33 PULL_MODE=DOWN BANK_VCCIO=3.3;
|
||||
|
||||
// UART
|
||||
IO_LOC "uart_tx" C3;
|
||||
IO_PORT "uart_tx" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3;
|
||||
|
||||
IO_LOC "uart_rx" B3;
|
||||
IO_PORT "uart_rx" IO_TYPE=LVCMOS33 PULL_MODE=NONE BANK_VCCIO=3.3;
|
||||
|
||||
// USB port
|
||||
IO_LOC "usb_dp" L6; // D+
|
||||
IO_PORT "usb_dp" PULL_MODE=NONE IO_TYPE=LVCMOS33;
|
||||
IO_LOC "usb_dm" K6; // D-
|
||||
IO_PORT "usb_dm" PULL_MODE=NONE IO_TYPE=LVCMOS33;
|
||||
IO_LOC "usb_led_act" D7; // USB activity LED
|
||||
IO_PORT "usb_led_act" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
IO_LOC "usb_led_err" E8; // USB connection error LED
|
||||
IO_PORT "usb_led_err" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
|
||||
// VGA
|
||||
IO_LOC "vga_red" C10;
|
||||
IO_PORT "vga_red" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
IO_LOC "vga_grn" B10;
|
||||
IO_PORT "vga_grn" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
IO_LOC "vga_blu" D10;
|
||||
IO_PORT "vga_blu" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
IO_LOC "vga_h_sync" C11;
|
||||
IO_PORT "vga_h_sync" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
IO_LOC "vga_v_sync" B11;
|
||||
IO_PORT "vga_v_sync" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
IO_LOC "vga_de" D11;
|
||||
IO_PORT "vga_de" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8;
|
||||
IO_LOC "vga_cls" H10;
|
||||
IO_PORT "vga_cls" IO_TYPE=LVCMOS33 PULL_MODE=DOWN BANK_VCCIO=3.3;
|
||||
@@ -0,0 +1 @@
|
||||
create_clock -name {clk} -period 20 [get_ports {clk}]
|
||||
@@ -0,0 +1,100 @@
|
||||
// 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: Apple1 implementation for the Tang Primer 25k
|
||||
//
|
||||
// Author.....: Alan Garfield
|
||||
// Date.......: 20/09/2025
|
||||
//
|
||||
|
||||
module apple1_primer #(
|
||||
parameter string BASIC_FILENAME = "../../../roms/basic.hex",
|
||||
parameter string FONT_ROM_FILENAME = "../../../roms/vga_font_bitreversed.hex",
|
||||
parameter string RAM_FILENAME = "../../../roms/ram.hex",
|
||||
parameter string VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter string WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
input uart_rx,
|
||||
output uart_tx,
|
||||
|
||||
inout usb_dm,
|
||||
inout usb_dp,
|
||||
output usb_led_err,
|
||||
output usb_led_act,
|
||||
|
||||
output vga_h_sync,
|
||||
output vga_v_sync,
|
||||
output vga_red,
|
||||
output vga_grn,
|
||||
output vga_blu,
|
||||
input vga_cls,
|
||||
output vga_de
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
wire uart_cts; // No CTS pin
|
||||
|
||||
wire clk25;
|
||||
wire usb_clk;
|
||||
|
||||
Gowin_PLL your_instance_name (
|
||||
.clkin (clk),
|
||||
.clkout0(clk25),
|
||||
.clkout1(usb_clk),
|
||||
.mdclk (1'd0)
|
||||
);
|
||||
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(!rst),
|
||||
|
||||
.uart_rx (uart_rx),
|
||||
.uart_tx (uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
|
||||
.key_select(2'b00), // USB keyboard selected
|
||||
|
||||
.ps2_clk(1'b0),
|
||||
.ps2_din(1'b0),
|
||||
|
||||
.usb_clk(usb_clk),
|
||||
.usb_dm(usb_dm),
|
||||
.usb_dp(usb_dp),
|
||||
.usb_led_err(usb_led_err),
|
||||
.usb_led_act(usb_led_act),
|
||||
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.vga_cls(vga_cls),
|
||||
.vga_de(vga_de),
|
||||
|
||||
.pc_monitor()
|
||||
);
|
||||
endmodule
|
||||
@@ -0,0 +1,57 @@
|
||||
module Gowin_PLL(
|
||||
clkin,
|
||||
clkout0,
|
||||
clkout1,
|
||||
mdclk
|
||||
);
|
||||
|
||||
|
||||
input clkin;
|
||||
output clkout0;
|
||||
output clkout1;
|
||||
input mdclk;
|
||||
wire [7:0] mdrdo;
|
||||
wire lock;
|
||||
wire [1:0] wMdOpc;
|
||||
wire wMdAInc;
|
||||
wire [7:0] wMdDIn;
|
||||
wire [7:0] wMdQOut;
|
||||
wire pll_lock;
|
||||
wire pll_rst;
|
||||
|
||||
|
||||
Gowin_PLL_MOD u_pll(
|
||||
.clkout1(clkout1),
|
||||
.clkout0(clkout0),
|
||||
.lock(pll_lock),
|
||||
.mdrdo(wMdQOut),
|
||||
.clkin(clkin),
|
||||
.reset(pll_rst),
|
||||
.mdclk(mdclk),
|
||||
.mdopc(wMdOpc),
|
||||
.mdainc(wMdAInc),
|
||||
.mdwdi(wMdDIn)
|
||||
);
|
||||
|
||||
|
||||
PLL_INIT u_pll_init(
|
||||
.I_RST(1'b0),
|
||||
.O_RST(pll_rst),
|
||||
.I_LOCK(pll_lock),
|
||||
.O_LOCK(lock),
|
||||
.I_MD_CLK(mdclk),
|
||||
.O_MD_INC(wMdAInc),
|
||||
.O_MD_OPC(wMdOpc),
|
||||
.O_MD_WR_DATA(wMdDIn),
|
||||
.I_MD_RD_DATA(wMdQOut),
|
||||
.PLL_INIT_BYPASS(1'b0),
|
||||
.MDRDO(mdrdo),
|
||||
.MDOPC(2'b00),
|
||||
.MDAINC(1'b0),
|
||||
.MDWDI(8'h0)
|
||||
);
|
||||
defparam u_pll_init.CLK_PERIOD = 20;
|
||||
defparam u_pll_init.MULTI_FAC = 18;
|
||||
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,142 @@
|
||||
//Copyright (C)2014-2025 Gowin Semiconductor Corporation.
|
||||
//All rights reserved.
|
||||
//File Title: IP file
|
||||
//Tool Version: V1.9.12
|
||||
//Part Number: GW5A-LV25MG121NES
|
||||
//Device: GW5A-25
|
||||
//Device Version: A
|
||||
//Created Time: Sat Sep 20 23:20:21 2025
|
||||
|
||||
module Gowin_PLL_MOD (lock, clkout0, clkout1, mdrdo, clkin, reset, mdclk, mdopc, mdainc, mdwdi);
|
||||
|
||||
output lock;
|
||||
output clkout0;
|
||||
output clkout1;
|
||||
output [7:0] mdrdo;
|
||||
input clkin;
|
||||
input reset;
|
||||
input mdclk;
|
||||
input [1:0] mdopc;
|
||||
input mdainc;
|
||||
input [7:0] mdwdi;
|
||||
|
||||
wire clkout2;
|
||||
wire clkout3;
|
||||
wire clkout4;
|
||||
wire clkout5;
|
||||
wire clkout6;
|
||||
wire clkfbout;
|
||||
wire gw_gnd;
|
||||
|
||||
assign gw_gnd = 1'b0;
|
||||
|
||||
PLLA PLLA_inst (
|
||||
.LOCK(lock),
|
||||
.CLKOUT0(clkout0),
|
||||
.CLKOUT1(clkout1),
|
||||
.CLKOUT2(clkout2),
|
||||
.CLKOUT3(clkout3),
|
||||
.CLKOUT4(clkout4),
|
||||
.CLKOUT5(clkout5),
|
||||
.CLKOUT6(clkout6),
|
||||
.CLKFBOUT(clkfbout),
|
||||
.MDRDO(mdrdo),
|
||||
.CLKIN(clkin),
|
||||
.CLKFB(gw_gnd),
|
||||
.RESET(reset),
|
||||
.PLLPWD(gw_gnd),
|
||||
.RESET_I(gw_gnd),
|
||||
.RESET_O(gw_gnd),
|
||||
.PSSEL({gw_gnd,gw_gnd,gw_gnd}),
|
||||
.PSDIR(gw_gnd),
|
||||
.PSPULSE(gw_gnd),
|
||||
.SSCPOL(gw_gnd),
|
||||
.SSCON(gw_gnd),
|
||||
.SSCMDSEL({gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd,gw_gnd}),
|
||||
.SSCMDSEL_FRAC({gw_gnd,gw_gnd,gw_gnd}),
|
||||
.MDCLK(mdclk),
|
||||
.MDOPC(mdopc),
|
||||
.MDAINC(mdainc),
|
||||
.MDWDI(mdwdi)
|
||||
);
|
||||
|
||||
defparam PLLA_inst.FCLKIN = "50";
|
||||
defparam PLLA_inst.IDIV_SEL = 1;
|
||||
defparam PLLA_inst.FBDIV_SEL = 1;
|
||||
defparam PLLA_inst.ODIV0_SEL = 36;
|
||||
defparam PLLA_inst.ODIV1_SEL = 75;
|
||||
defparam PLLA_inst.ODIV2_SEL = 8;
|
||||
defparam PLLA_inst.ODIV3_SEL = 8;
|
||||
defparam PLLA_inst.ODIV4_SEL = 8;
|
||||
defparam PLLA_inst.ODIV5_SEL = 8;
|
||||
defparam PLLA_inst.ODIV6_SEL = 8;
|
||||
defparam PLLA_inst.MDIV_SEL = 18;
|
||||
defparam PLLA_inst.MDIV_FRAC_SEL = 0;
|
||||
defparam PLLA_inst.ODIV0_FRAC_SEL = 0;
|
||||
defparam PLLA_inst.CLKOUT0_EN = "TRUE";
|
||||
defparam PLLA_inst.CLKOUT1_EN = "TRUE";
|
||||
defparam PLLA_inst.CLKOUT2_EN = "FALSE";
|
||||
defparam PLLA_inst.CLKOUT3_EN = "FALSE";
|
||||
defparam PLLA_inst.CLKOUT4_EN = "FALSE";
|
||||
defparam PLLA_inst.CLKOUT5_EN = "FALSE";
|
||||
defparam PLLA_inst.CLKOUT6_EN = "FALSE";
|
||||
defparam PLLA_inst.CLKFB_SEL = "INTERNAL";
|
||||
defparam PLLA_inst.CLKOUT0_DT_DIR = 1'b1;
|
||||
defparam PLLA_inst.CLKOUT1_DT_DIR = 1'b1;
|
||||
defparam PLLA_inst.CLKOUT2_DT_DIR = 1'b1;
|
||||
defparam PLLA_inst.CLKOUT3_DT_DIR = 1'b1;
|
||||
defparam PLLA_inst.CLKOUT0_DT_STEP = 0;
|
||||
defparam PLLA_inst.CLKOUT1_DT_STEP = 0;
|
||||
defparam PLLA_inst.CLKOUT2_DT_STEP = 0;
|
||||
defparam PLLA_inst.CLKOUT3_DT_STEP = 0;
|
||||
defparam PLLA_inst.CLK0_IN_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK0_OUT_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK1_IN_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK1_OUT_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK2_IN_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK2_OUT_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK3_IN_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK3_OUT_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK4_IN_SEL = 2'b00;
|
||||
defparam PLLA_inst.CLK4_OUT_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK5_IN_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK5_OUT_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK6_IN_SEL = 1'b0;
|
||||
defparam PLLA_inst.CLK6_OUT_SEL = 1'b0;
|
||||
defparam PLLA_inst.DYN_DPA_EN = "FALSE";
|
||||
defparam PLLA_inst.CLKOUT0_PE_COARSE = 0;
|
||||
defparam PLLA_inst.CLKOUT0_PE_FINE = 0;
|
||||
defparam PLLA_inst.CLKOUT1_PE_COARSE = 0;
|
||||
defparam PLLA_inst.CLKOUT1_PE_FINE = 0;
|
||||
defparam PLLA_inst.CLKOUT2_PE_COARSE = 0;
|
||||
defparam PLLA_inst.CLKOUT2_PE_FINE = 0;
|
||||
defparam PLLA_inst.CLKOUT3_PE_COARSE = 0;
|
||||
defparam PLLA_inst.CLKOUT3_PE_FINE = 0;
|
||||
defparam PLLA_inst.CLKOUT4_PE_COARSE = 0;
|
||||
defparam PLLA_inst.CLKOUT4_PE_FINE = 0;
|
||||
defparam PLLA_inst.CLKOUT5_PE_COARSE = 0;
|
||||
defparam PLLA_inst.CLKOUT5_PE_FINE = 0;
|
||||
defparam PLLA_inst.CLKOUT6_PE_COARSE = 0;
|
||||
defparam PLLA_inst.CLKOUT6_PE_FINE = 0;
|
||||
defparam PLLA_inst.DYN_PE0_SEL = "FALSE";
|
||||
defparam PLLA_inst.DYN_PE1_SEL = "FALSE";
|
||||
defparam PLLA_inst.DYN_PE2_SEL = "FALSE";
|
||||
defparam PLLA_inst.DYN_PE3_SEL = "FALSE";
|
||||
defparam PLLA_inst.DYN_PE4_SEL = "FALSE";
|
||||
defparam PLLA_inst.DYN_PE5_SEL = "FALSE";
|
||||
defparam PLLA_inst.DYN_PE6_SEL = "FALSE";
|
||||
defparam PLLA_inst.DE0_EN = "FALSE";
|
||||
defparam PLLA_inst.DE1_EN = "FALSE";
|
||||
defparam PLLA_inst.DE2_EN = "FALSE";
|
||||
defparam PLLA_inst.DE3_EN = "FALSE";
|
||||
defparam PLLA_inst.DE4_EN = "FALSE";
|
||||
defparam PLLA_inst.DE5_EN = "FALSE";
|
||||
defparam PLLA_inst.DE6_EN = "FALSE";
|
||||
defparam PLLA_inst.RESET_I_EN = "FALSE";
|
||||
defparam PLLA_inst.RESET_O_EN = "FALSE";
|
||||
defparam PLLA_inst.ICP_SEL = 6'bXXXXXX;
|
||||
defparam PLLA_inst.LPF_RES = 3'bXXX;
|
||||
defparam PLLA_inst.LPF_CAP = 2'b00;
|
||||
defparam PLLA_inst.SSC_EN = "FALSE";
|
||||
|
||||
endmodule //Gowin_PLL_MOD
|
||||
@@ -0,0 +1,398 @@
|
||||
`timescale 1ns/1ns
|
||||
|
||||
|
||||
module PLL_INIT #
|
||||
( parameter CLK_PERIOD = 20
|
||||
, parameter MULTI_FAC = 24
|
||||
)
|
||||
( input I_RST
|
||||
, input I_MD_CLK
|
||||
|
||||
, output O_RST
|
||||
|
||||
, output O_MD_INC
|
||||
, output [1:0] O_MD_OPC
|
||||
, output [7:0] O_MD_WR_DATA
|
||||
, input [7:0] I_MD_RD_DATA
|
||||
|
||||
, input I_LOCK
|
||||
, output O_LOCK
|
||||
|
||||
, input PLL_INIT_BYPASS
|
||||
, output [7:0] MDRDO
|
||||
, input [1:0] MDOPC
|
||||
, input MDAINC
|
||||
, input [7:0] MDWDI
|
||||
|
||||
|
||||
);
|
||||
|
||||
`ifdef SIM
|
||||
`define DL #1
|
||||
`else
|
||||
`define DL
|
||||
`endif
|
||||
|
||||
`ifdef SIM
|
||||
localparam WAIT_TIME = 'd8_000;
|
||||
localparam LOCK_TIME = 'd2_000;
|
||||
`else
|
||||
localparam WAIT_TIME = 'd800_000;
|
||||
localparam LOCK_TIME = 'd200_000;
|
||||
`endif
|
||||
localparam WAIT_CNT = (WAIT_TIME + CLK_PERIOD - 1) / CLK_PERIOD; //! 1ms
|
||||
localparam LOCK_CNT = (LOCK_TIME + CLK_PERIOD - 1) / CLK_PERIOD;
|
||||
localparam WW = $clog2(WAIT_CNT + 1);
|
||||
localparam LW = $clog2(LOCK_CNT + 1);
|
||||
|
||||
localparam INIT_STEP_0 = 4'd0
|
||||
, INIT_STEP_1 = 4'd1
|
||||
, INIT_STEP_2 = 4'd2
|
||||
, INIT_STEP_3 = 4'd3
|
||||
, INIT_STEP_4 = 4'd4
|
||||
, INIT_STEP_5 = 4'd5
|
||||
, INIT_STEP_6 = 4'd6
|
||||
, INIT_STEP_7 = 4'd7
|
||||
, INIT_STEP_8 = 4'd8
|
||||
, INIT_STEP_9 = 4'd9
|
||||
;
|
||||
|
||||
reg [ 1:0] rEnable = 'b0;
|
||||
|
||||
reg rRomRd = 'b0;
|
||||
reg [ 7:0] rRomAddr = 'b0;
|
||||
reg [ 24:0] rRomData = 'b0;
|
||||
|
||||
reg [ 2:0] rReqCnt = 'b0;
|
||||
reg [ 4:0] rLoopCnt = 'b0;
|
||||
|
||||
reg [ 3:0] rChkOkCnt = 'b0;
|
||||
reg [ 5:0] rChkStart = 'b0;
|
||||
|
||||
reg [ 3:0] rInitFsmC = INIT_STEP_0 ;
|
||||
reg [ 3:0] rInitFsmN = INIT_STEP_1 ;
|
||||
|
||||
reg [ 7:0] rMdAddr = 'b0;
|
||||
|
||||
reg rMdInc = 'b0;
|
||||
reg [ 1:0] rMdOpc = 'b0;
|
||||
reg [ 7:0] rMdDOut = 'b0;
|
||||
|
||||
reg [ 7:0] rChkFlag = 'b0;
|
||||
|
||||
reg rLockReg = 'b0;
|
||||
reg [LW-1:0] rLockCnt = 'b0;
|
||||
reg rLocked = 'b0;
|
||||
reg [WW-1:0] rWaitCnt = 'b0;
|
||||
|
||||
reg rLastStep = 'b0;
|
||||
|
||||
reg rLockOut = 'b0;
|
||||
|
||||
reg rChkVld = 'b0;
|
||||
reg [ 7:0] rRomAddrVld = 'b0;
|
||||
|
||||
reg rRstOut = 1'b1;
|
||||
|
||||
wire wEnable = rEnable[1];
|
||||
wire [ 7:0] wMdAddrNext = rMdAddr + 2'd1;
|
||||
wire wLocked = (rLockCnt >= LOCK_CNT);
|
||||
|
||||
wire wIsStep0 = (rInitFsmC == INIT_STEP_0);
|
||||
wire wIsStep1 = (rInitFsmC == INIT_STEP_1);
|
||||
wire wIsStep2 = (rInitFsmC == INIT_STEP_2);
|
||||
wire wIsStep3 = (rInitFsmC == INIT_STEP_3);
|
||||
wire wIsStep4 = (rInitFsmC == INIT_STEP_4);
|
||||
wire wIsStep5 = (rInitFsmC == INIT_STEP_5);
|
||||
wire wIsStep6 = (rInitFsmC == INIT_STEP_6);
|
||||
wire wIsStep7 = (rInitFsmC == INIT_STEP_7);
|
||||
wire wIsStep8 = (rInitFsmC == INIT_STEP_8);
|
||||
wire wIsStep9 = (rInitFsmC == INIT_STEP_9);
|
||||
|
||||
wire wReqOver = ~rRomData[24];
|
||||
wire wMdrpReq = rRomData[24];
|
||||
wire wWaitLock = rReqCnt[2];//(rReqCnt == 4);
|
||||
|
||||
|
||||
wire [ 7:0] wReqAddr = rRomData[16+:8];
|
||||
wire [ 7:0] wReqMask = rRomData[ 8+:8];
|
||||
wire [ 7:0] wReqData = rRomData[ 0+:8];
|
||||
|
||||
|
||||
localparam ROM_FILE = "";
|
||||
|
||||
reg [ 27:0] rRomDReg = 'b0;
|
||||
|
||||
|
||||
reg [27:0] rRom [63:0];
|
||||
|
||||
|
||||
always @ (posedge PLL_INIT_BYPASS or posedge I_MD_CLK or posedge I_RST) begin
|
||||
if (PLL_INIT_BYPASS || I_RST) rEnable <=`DL 2'b00;
|
||||
else rEnable <=`DL {rEnable[0], 1'b1};
|
||||
end
|
||||
|
||||
generate
|
||||
if (ROM_FILE != "") begin: ram_init_file
|
||||
initial begin
|
||||
$readmemh (ROM_FILE, rRom);
|
||||
end
|
||||
|
||||
always @ (posedge I_MD_CLK) begin
|
||||
rRomDReg <=`DL rRom[rRomAddr[5:0]];
|
||||
end
|
||||
end else begin : ram_init
|
||||
always @ (posedge I_MD_CLK) begin
|
||||
if (~rEnable[1]) begin
|
||||
rRomDReg <=`DL 28'h000_0000;
|
||||
//1
|
||||
rRom[00] <=`DL (MULTI_FAC > 34) ? 28'h10B_3F03
|
||||
: (MULTI_FAC > 16) ? 28'h10B_3F01
|
||||
: 28'h10B_3F00;
|
||||
rRom[01] <=`DL 28'h10C_E080;
|
||||
rRom[02] <=`DL 28'h111_0701;
|
||||
rRom[03] <=`DL 28'h112_0C08;
|
||||
//2
|
||||
rRom[04] <=`DL (MULTI_FAC > 34) ? 28'h10B_3F03
|
||||
: (MULTI_FAC > 16) ? 28'h10B_3F01
|
||||
: 28'h10B_3F00;
|
||||
rRom[05] <=`DL 28'h10C_E080;
|
||||
rRom[06] <=`DL 28'h111_0703;
|
||||
rRom[07] <=`DL 28'h112_0C08;
|
||||
//3
|
||||
rRom[08] <=`DL (MULTI_FAC > 34) ? 28'h10B_3F03
|
||||
: (MULTI_FAC > 16) ? 28'h10B_3F01
|
||||
: 28'h10B_3F00;
|
||||
rRom[09] <=`DL 28'h10C_E0A0;
|
||||
rRom[10] <=`DL 28'h111_0703;
|
||||
rRom[11] <=`DL 28'h112_0C08;
|
||||
//4
|
||||
rRom[12] <=`DL (MULTI_FAC > 34) ? 28'h10B_3F03
|
||||
: (MULTI_FAC > 16) ? 28'h10B_3F01
|
||||
: 28'h10B_3F00;
|
||||
rRom[13] <=`DL 28'h10C_E0A0;
|
||||
rRom[14] <=`DL 28'h111_0707;
|
||||
rRom[15] <=`DL 28'h112_0C08;
|
||||
//5
|
||||
rRom[16] <=`DL (MULTI_FAC > 34) ? 28'h10B_3F07
|
||||
: (MULTI_FAC > 16) ? 28'h10B_3F03
|
||||
: 28'h10B_3F01;
|
||||
rRom[17] <=`DL 28'h10C_E0A0;
|
||||
rRom[18] <=`DL 28'h111_0707;
|
||||
rRom[19] <=`DL 28'h112_0C08;
|
||||
//6
|
||||
rRom[20] <=`DL (MULTI_FAC > 34) ? 28'h10B_3F05
|
||||
: (MULTI_FAC > 16) ? 28'h10B_3F02
|
||||
: 28'h10B_3F01;
|
||||
rRom[21] <=`DL 28'h10C_E0C0;
|
||||
rRom[22] <=`DL 28'h111_0707;
|
||||
rRom[23] <=`DL 28'h112_0C08;
|
||||
//over
|
||||
rRom[24] <=`DL 28'h000_0000;
|
||||
rRom[25] <=`DL 28'h000_0000;
|
||||
rRom[26] <=`DL 28'h000_0000;
|
||||
rRom[27] <=`DL 28'h000_0000;
|
||||
//1.5
|
||||
rRom[28] <=`DL (MULTI_FAC > 34) ? 28'h10B3F03
|
||||
: (MULTI_FAC > 16) ? 28'h10B3F01
|
||||
: 28'h10B3F00;
|
||||
rRom[29] <=`DL 28'h10CE080;
|
||||
rRom[30] <=`DL 28'h1110702;
|
||||
rRom[31] <=`DL 28'h1120C08;
|
||||
//2.5
|
||||
rRom[32] <=`DL (MULTI_FAC > 34) ? 28'h10B3F05
|
||||
: (MULTI_FAC > 16) ? 28'h10B3F02
|
||||
: 28'h10B3F00;
|
||||
rRom[33] <=`DL 28'h10CE080;
|
||||
rRom[34] <=`DL 28'h1110703;
|
||||
rRom[35] <=`DL 28'h1120C08;
|
||||
//3.5
|
||||
rRom[36] <=`DL (MULTI_FAC > 34) ? 28'h10B3F03
|
||||
: (MULTI_FAC > 16) ? 28'h10B3F01
|
||||
: 28'h10B3F00;
|
||||
rRom[37] <=`DL 28'h10CE0A0;
|
||||
rRom[38] <=`DL 28'h1110704;
|
||||
rRom[39] <=`DL 28'h112_0C08;
|
||||
|
||||
//4.5
|
||||
rRom[40] <=`DL (MULTI_FAC > 34) ? 28'h10B3F04
|
||||
: (MULTI_FAC > 16) ? 28'h10B3F02
|
||||
: 28'h10B3F00;
|
||||
rRom[41] <=`DL 28'h10CE0A0;
|
||||
rRom[42] <=`DL 28'h1110707;
|
||||
rRom[43] <=`DL 28'h1120C08;
|
||||
|
||||
//5.5
|
||||
rRom[44] <=`DL (MULTI_FAC > 34) ? 28'h10B3F03
|
||||
: (MULTI_FAC > 16) ? 28'h10B3F01
|
||||
: 28'h10B3F00;
|
||||
rRom[45] <=`DL 28'h10CE0C0;
|
||||
rRom[46] <=`DL 28'h1110707;
|
||||
rRom[47] <=`DL 28'h1120C08;
|
||||
|
||||
rRom[48] <=`DL 28'h000_0000;
|
||||
rRom[49] <=`DL 28'h000_0000;
|
||||
rRom[50] <=`DL 28'h000_0000;
|
||||
rRom[51] <=`DL 28'h000_0000;
|
||||
rRom[52] <=`DL 28'h000_0000;
|
||||
rRom[53] <=`DL 28'h000_0000;
|
||||
rRom[54] <=`DL 28'h000_0000;
|
||||
rRom[55] <=`DL 28'h000_0000;
|
||||
rRom[56] <=`DL 28'h000_0000;
|
||||
rRom[57] <=`DL 28'h000_0000;
|
||||
rRom[58] <=`DL 28'h000_0000;
|
||||
rRom[59] <=`DL 28'h000_0000;
|
||||
rRom[60] <=`DL 28'h000_0000;
|
||||
rRom[61] <=`DL 28'h000_0000;
|
||||
rRom[62] <=`DL 28'h000_0000;
|
||||
rRom[63] <=`DL 28'h000_0000;
|
||||
|
||||
|
||||
end else
|
||||
rRomDReg <=`DL rRom[rRomAddr[5:0]];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
always @ (*) begin
|
||||
casex (rChkFlag[5:0])
|
||||
6'b111_111 : {rChkVld, rRomAddrVld} = 9'b1_0000_1000;
|
||||
6'b011_111 : {rChkVld, rRomAddrVld} = 9'b1_0000_1000;
|
||||
6'b111_110 : {rChkVld, rRomAddrVld} = 9'b1_0000_1100;
|
||||
6'b111_10x : {rChkVld, rRomAddrVld} = 9'b1_0000_1100;
|
||||
6'bx01_111 : {rChkVld, rRomAddrVld} = 9'b1_0000_0100;
|
||||
6'b011_110 : {rChkVld, rRomAddrVld} = 9'b1_0000_1000;
|
||||
6'bxx0_111 : {rChkVld, rRomAddrVld} = 9'b1_0000_0100;
|
||||
6'bx01_110 : {rChkVld, rRomAddrVld} = 9'b1_0000_1000;
|
||||
6'b011_10x : {rChkVld, rRomAddrVld} = 9'b1_0000_1100;
|
||||
6'b111_0xx : {rChkVld, rRomAddrVld} = 9'b1_0001_0000;
|
||||
|
||||
6'bxxx_011 : {rChkVld, rRomAddrVld} = 9'b1_0001_1100;
|
||||
6'bxx0_110 : {rChkVld, rRomAddrVld} = 9'b1_0010_0000;
|
||||
6'bx01_100 : {rChkVld, rRomAddrVld} = 9'b1_0010_0100;
|
||||
6'b011_000 : {rChkVld, rRomAddrVld} = 9'b1_0010_1000;
|
||||
6'b110_000 : {rChkVld, rRomAddrVld} = 9'b1_0010_1100;
|
||||
6'bxxx_x01 : {rChkVld, rRomAddrVld} = 9'b1_0000_0000;
|
||||
6'bxxx_010 : {rChkVld, rRomAddrVld} = 9'b1_0000_0100;
|
||||
6'bxx0_100 : {rChkVld, rRomAddrVld} = 9'b1_0000_1000;
|
||||
6'bx01_000 : {rChkVld, rRomAddrVld} = 9'b1_0000_1100;
|
||||
6'b010_000 : {rChkVld, rRomAddrVld} = 9'b1_0001_0000;
|
||||
6'b100_000 : {rChkVld, rRomAddrVld} = 9'b1_0001_0100;
|
||||
|
||||
6'b000_000 : {rChkVld, rRomAddrVld} = 9'b0_0000_0000;
|
||||
|
||||
default : {rChkVld, rRomAddrVld} = 9'b0_0000_0000;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (posedge I_MD_CLK) begin
|
||||
rInitFsmC <=`DL wEnable ? rInitFsmN : INIT_STEP_0;
|
||||
//!_____________________________________________________________________________
|
||||
rRomRd <=`DL wEnable & (wIsStep1 | wIsStep6 & ~wWaitLock);
|
||||
//!_____________________________________________________________________________
|
||||
rRomData <=`DL rRomRd ? rRomDReg[24:0] : rRomData;
|
||||
//!_____________________________________________________________________________
|
||||
rRomAddr <=`DL ~wEnable ? 8'd0
|
||||
: (wIsStep3 & wReqOver) ? rRomAddrVld
|
||||
: rRomRd ? rRomAddr + 1'd1
|
||||
: rRomAddr;
|
||||
//!_____________________________________________________________________________
|
||||
rLastStep <=`DL wEnable & (wIsStep3 & wReqOver | rLastStep);
|
||||
//!_____________________________________________________________________________
|
||||
rReqCnt <=`DL ~wEnable ? 3'd0
|
||||
: wIsStep7 ? 3'd0
|
||||
: wIsStep5 ? rReqCnt + 1'd1
|
||||
: rReqCnt;
|
||||
//!_____________________________________________________________________________
|
||||
rLoopCnt <=`DL ~wEnable ? 3'd0
|
||||
: wIsStep8 ? rLoopCnt + 1'd1
|
||||
: rLoopCnt;
|
||||
//!_____________________________________________________________________________
|
||||
rLockReg <=`DL wEnable & I_LOCK;
|
||||
//!_____________________________________________________________________________
|
||||
rLockCnt <=`DL (~wEnable) ? {LW{1'b0}}
|
||||
: (~wIsStep7&~wIsStep9) ? {LW{1'b0}}
|
||||
: (~rLockReg) ? {LW{1'b0}}
|
||||
: (rLockCnt<LOCK_CNT) ? rLockCnt + 1'd1
|
||||
: rLockCnt;
|
||||
//!_____________________________________________________________________________
|
||||
rLocked <=`DL wLocked;
|
||||
//!_____________________________________________________________________________
|
||||
rWaitCnt <=`DL wIsStep3 ? WAIT_CNT[0+:WW]
|
||||
: ~wIsStep7 ? rWaitCnt
|
||||
: (|rWaitCnt) ? rWaitCnt - 1'd1
|
||||
: {WW{1'b0}};
|
||||
//!_____________________________________________________________________________
|
||||
if (~wEnable) rChkFlag <=`DL 8'h00;
|
||||
else if (wIsStep7 & rLocked) rChkFlag[rLoopCnt[2:0]] <=`DL 1'b1;
|
||||
//!_____________________________________________________________________________
|
||||
rChkOkCnt <=`DL ~wEnable ? 4'd0
|
||||
: ~wIsStep7 ? rChkOkCnt
|
||||
: (rWaitCnt==0) ? 4'd0
|
||||
: rLocked ? rChkOkCnt + 1'd1
|
||||
: rChkOkCnt;
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
if (~wEnable) rInitFsmN =`DL INIT_STEP_1;
|
||||
else case (rInitFsmC) /* synthesis full_case */
|
||||
INIT_STEP_0 : rInitFsmN =`DL INIT_STEP_1;
|
||||
INIT_STEP_1 : rInitFsmN =`DL INIT_STEP_2;
|
||||
INIT_STEP_2 : rInitFsmN =`DL INIT_STEP_3;
|
||||
INIT_STEP_3 : rInitFsmN =`DL wWaitLock ? INIT_STEP_7
|
||||
: wReqOver & rLastStep ? INIT_STEP_9
|
||||
: wReqOver &~rLastStep ? INIT_STEP_1
|
||||
: (rMdAddr >= wReqAddr) ? INIT_STEP_4
|
||||
: INIT_STEP_3;
|
||||
INIT_STEP_4 : rInitFsmN =`DL INIT_STEP_5;
|
||||
INIT_STEP_5 : rInitFsmN =`DL INIT_STEP_6;
|
||||
INIT_STEP_6 : rInitFsmN =`DL INIT_STEP_2;
|
||||
INIT_STEP_7 : rInitFsmN =`DL (rWaitCnt==0) ? INIT_STEP_8
|
||||
: ~rLocked ? INIT_STEP_7
|
||||
: rLastStep ? INIT_STEP_9
|
||||
: INIT_STEP_8;
|
||||
INIT_STEP_8 : rInitFsmN =`DL ~rLastStep ? INIT_STEP_1
|
||||
: rChkVld ? INIT_STEP_1
|
||||
: INIT_STEP_9;
|
||||
INIT_STEP_9 : rInitFsmN =`DL INIT_STEP_9;
|
||||
default : rInitFsmN =`DL INIT_STEP_9;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @ (posedge I_MD_CLK) begin
|
||||
rMdOpc <=`DL ~wEnable ? 2'b00
|
||||
: wIsStep7 ? 2'b00
|
||||
: wIsStep5 ? 2'b01
|
||||
: 2'b10;
|
||||
//!_____________________________________________________________________________
|
||||
rMdInc <=`DL wIsStep3 & (~rMdInc ? (rMdAddr<wReqAddr)
|
||||
: (wMdAddrNext < wReqAddr));
|
||||
//!_____________________________________________________________________________
|
||||
rMdAddr <=`DL ~wEnable ? 8'd0
|
||||
: wIsStep7 ? 8'd0
|
||||
: rMdInc ? wMdAddrNext
|
||||
: rMdAddr;
|
||||
//!_____________________________________________________________________________
|
||||
rMdDOut <=`DL wIsStep5 ? (I_MD_RD_DATA&~wReqMask|wReqData) : rMdDOut;
|
||||
//!_____________________________________________________________________________
|
||||
rRstOut <=`DL ~wEnable | (~wIsStep7 & ~wIsStep9);
|
||||
//!_____________________________________________________________________________
|
||||
rLockOut <=`DL rLocked & wIsStep9 & rChkVld;
|
||||
end
|
||||
|
||||
|
||||
/////////////mdrp switch//////////////////////////
|
||||
assign O_LOCK = (PLL_INIT_BYPASS == 1'b1) ? I_LOCK : rLockOut;
|
||||
assign O_RST = (PLL_INIT_BYPASS == 1'b1) ? I_RST : rRstOut;
|
||||
assign O_MD_INC = (PLL_INIT_BYPASS == 1'b1) ? MDAINC : rMdInc;
|
||||
assign O_MD_OPC = (PLL_INIT_BYPASS == 1'b1) ? MDOPC : rMdOpc;
|
||||
assign O_MD_WR_DATA= (PLL_INIT_BYPASS == 1'b1) ? MDWDI : rMdDOut;
|
||||
assign MDRDO = (PLL_INIT_BYPASS == 1'b1) ? I_MD_RD_DATA : 8'b0000_0000;
|
||||
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
endmodule//: PLL_INIT
|
||||
|
||||
|
||||
@@ -29,104 +29,104 @@ module apple1_de0_top #(
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input CLOCK_50, // the 50 MHz DE0 master clock
|
||||
input CLOCK_50, // the 50 MHz DE0 master clock
|
||||
|
||||
// UART I/O signals
|
||||
output UART_TXD, // UART transmit pin on DE0 board
|
||||
input UART_RXD, // UART receive pin on DE0 board
|
||||
output UART_CTS, // UART clear-to-send pin on DE0 board
|
||||
output UART_TXD, // UART transmit pin on DE0 board
|
||||
input UART_RXD, // UART receive pin on DE0 board
|
||||
output UART_CTS, // UART clear-to-send pin on DE0 board
|
||||
|
||||
output [7:0] LEDG, // monitoring for lower 8 address bits
|
||||
input [2:0] BUTTON, // BUTTON[0] for reset
|
||||
output [6:0] HEX0_D,
|
||||
output [6:0] HEX1_D,
|
||||
output [6:0] HEX2_D,
|
||||
output [6:0] HEX3_D,
|
||||
output [7:0] LEDG, // monitoring for lower 8 address bits
|
||||
input [2:0] BUTTON, // BUTTON[0] for reset
|
||||
output [6:0] HEX0_D,
|
||||
output [6:0] HEX1_D,
|
||||
output [6:0] HEX2_D,
|
||||
output [6:0] HEX3_D,
|
||||
|
||||
input PS2_KBCLK,
|
||||
input PS2_KBDAT,
|
||||
input PS2_KBCLK,
|
||||
input PS2_KBDAT,
|
||||
|
||||
output [3:0] VGA_R,
|
||||
output [3:0] VGA_G,
|
||||
output [3:0] VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS
|
||||
output [3:0] VGA_R,
|
||||
output [3:0] VGA_G,
|
||||
output [3:0] VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
reg clk25;
|
||||
wire [15:0] pc_monitor;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Registers and Wires
|
||||
reg clk25;
|
||||
wire [15:0] pc_monitor;
|
||||
|
||||
// generate 25MHz clock from 50MHz master clock
|
||||
always @(posedge CLOCK_50)
|
||||
begin
|
||||
clk25 <= ~clk25;
|
||||
end
|
||||
// generate 25MHz clock from 50MHz master clock
|
||||
always @(posedge CLOCK_50) begin
|
||||
clk25 <= ~clk25;
|
||||
end
|
||||
|
||||
wire r_bit, g_bit, b_bit;
|
||||
wire r_bit, g_bit, b_bit;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Core of system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) apple1_top(
|
||||
.clk25(clk25),
|
||||
.rst_n(BUTTON[0]), // we don't have any reset pulse..
|
||||
.uart_rx(UART_RXD),
|
||||
.uart_tx(UART_TXD),
|
||||
.uart_cts(UART_CTS),
|
||||
.ps2_clk(PS2_KBCLK),
|
||||
.ps2_din(PS2_KBDAT),
|
||||
.ps2_select(1'b1),
|
||||
.vga_h_sync(VGA_HS),
|
||||
.vga_v_sync(VGA_VS),
|
||||
.vga_red(r_bit),
|
||||
.vga_grn(g_bit),
|
||||
.vga_blu(b_bit),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Core of system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) apple1_top (
|
||||
.clk25 (clk25),
|
||||
.rst_n (BUTTON[0]), // we don't have any reset pulse..
|
||||
.uart_rx (UART_RXD),
|
||||
.uart_tx (UART_TXD),
|
||||
.uart_cts (UART_CTS),
|
||||
.ps2_clk (PS2_KBCLK),
|
||||
.ps2_din (PS2_KBDAT),
|
||||
.key_select(2'b10), // PS/2 enabled, UART TX disabled
|
||||
// .key_select(2'b00), // PS/2 disabled, UART TX enabled
|
||||
.vga_h_sync(VGA_HS),
|
||||
.vga_v_sync(VGA_VS),
|
||||
.vga_red (r_bit),
|
||||
.vga_grn (g_bit),
|
||||
.vga_blu (b_bit),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
|
||||
// set the monochrome base colour here..
|
||||
assign VGA_R[3:0] = {4{r_bit}};
|
||||
assign VGA_G[3:0] = {4{g_bit}};
|
||||
assign VGA_B[3:0] = {4{b_bit}};
|
||||
// set the monochrome base colour here..
|
||||
assign VGA_R[3:0] = {4{r_bit}};
|
||||
assign VGA_G[3:0] = {4{g_bit}};
|
||||
assign VGA_B[3:0] = {4{b_bit}};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Display 6502 address on 7-segment displays
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Display 6502 address on 7-segment displays
|
||||
|
||||
segmentdisplay seg1(
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[3:0]),
|
||||
.display_out(HEX0_D)
|
||||
);
|
||||
segmentdisplay seg1 (
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[3:0]),
|
||||
.display_out(HEX0_D)
|
||||
);
|
||||
|
||||
segmentdisplay seg2(
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[7:4]),
|
||||
.display_out(HEX1_D)
|
||||
);
|
||||
segmentdisplay seg2 (
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[7:4]),
|
||||
.display_out(HEX1_D)
|
||||
);
|
||||
|
||||
segmentdisplay seg3(
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[11:8]),
|
||||
.display_out(HEX2_D)
|
||||
);
|
||||
segmentdisplay seg3 (
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[11:8]),
|
||||
.display_out(HEX2_D)
|
||||
);
|
||||
|
||||
segmentdisplay seg4(
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[15:12]),
|
||||
.display_out(HEX3_D)
|
||||
);
|
||||
segmentdisplay seg4 (
|
||||
.clk(clk25),
|
||||
.latch(1'b1),
|
||||
.hexdigit_in(pc_monitor[15:12]),
|
||||
.display_out(HEX3_D)
|
||||
);
|
||||
|
||||
assign LEDG = 0;
|
||||
assign LEDG = 0;
|
||||
|
||||
endmodule
|
||||
@@ -29,75 +29,76 @@ module apple1_top #(
|
||||
parameter VRAM_FILENAME = "../../../roms/vga_vram.bin",
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
input pin3_clk_16mhz,// 16 MHz board clock
|
||||
input pin3_clk_16mhz, // 16 MHz board clock
|
||||
|
||||
// Outputs to VGA display
|
||||
output pin4, // hozizontal VGA sync pulse
|
||||
output pin5, // vertical VGA sync pulse
|
||||
output pin4, // hozizontal VGA sync pulse
|
||||
output pin5, // vertical VGA sync pulse
|
||||
|
||||
input pin6, // PS/2 data input
|
||||
input pin7, // PS/2 clock
|
||||
input pin6, // PS/2 data input
|
||||
input pin7, // PS/2 clock
|
||||
|
||||
// I/O interface to computer
|
||||
input pin11, // asynchronous serial data input from computer
|
||||
output pin12, // asynchronous serial data output to computer
|
||||
output pin13, // clear to send flag to computer
|
||||
input pin11, // asynchronous serial data input from computer
|
||||
output pin12, // asynchronous serial data output to computer
|
||||
output pin13, // clear to send flag to computer
|
||||
|
||||
output reg pin24, // red VGA signal
|
||||
output reg pin23, // red VGA signal
|
||||
output reg pin22, // green VGA signal
|
||||
output reg pin21, // green VGA signal
|
||||
output reg pin20, // blue VGA signal
|
||||
output reg pin19 // blue VGA signal
|
||||
output reg pin24, // red VGA signal
|
||||
output reg pin23, // red VGA signal
|
||||
output reg pin22, // green VGA signal
|
||||
output reg pin21, // green VGA signal
|
||||
output reg pin20, // blue VGA signal
|
||||
output reg pin19 // blue VGA signal
|
||||
|
||||
);
|
||||
|
||||
wire clk25;
|
||||
wire clk25;
|
||||
|
||||
// 16MHz up to 25MHz
|
||||
clock_pll clock_pll_inst(
|
||||
.REFERENCECLK(pin3_clk_16mhz),
|
||||
.PLLOUTGLOBAL(clk25),
|
||||
.RESET(1'b1)
|
||||
);
|
||||
// 16MHz up to 25MHz
|
||||
clock_pll clock_pll_inst (
|
||||
.REFERENCECLK(pin3_clk_16mhz),
|
||||
.PLLOUTGLOBAL(clk25),
|
||||
.RESET(1'b1)
|
||||
);
|
||||
|
||||
wire [15:0] pc_monitor;
|
||||
wire [15:0] pc_monitor;
|
||||
|
||||
reg [1:0] button = 2'b01;
|
||||
reg [1:0] button = 2'b01;
|
||||
|
||||
wire vga_red;
|
||||
wire vga_grn;
|
||||
wire vga_blu;
|
||||
wire vga_red;
|
||||
wire vga_grn;
|
||||
wire vga_blu;
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk25),
|
||||
.rst_n(button[0]),
|
||||
.ps2_clk(pin7), // PS/2 not working with my keyboard
|
||||
.ps2_din(pin6),
|
||||
.ps2_select(1'b0), // change to 1 in order to test with keyboard
|
||||
.uart_rx(pin11),
|
||||
.uart_tx(pin12),
|
||||
.uart_cts(pin13),
|
||||
.vga_h_sync(pin4),
|
||||
.vga_v_sync(pin5),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(button[0]),
|
||||
.ps2_clk(pin7), // PS/2 not working with my keyboard
|
||||
.ps2_din(pin6),
|
||||
// .key_select(2'b10), // PS/2 enabled, UART TX disabled
|
||||
.key_select(2'b00), // PS/2 disabled, UART TX enabled
|
||||
.uart_rx(pin11),
|
||||
.uart_tx(pin12),
|
||||
.uart_cts(pin13),
|
||||
.vga_h_sync(pin4),
|
||||
.vga_v_sync(pin5),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.pc_monitor(pc_monitor)
|
||||
);
|
||||
|
||||
assign pin19 = vga_blu;
|
||||
assign pin20 = vga_blu;
|
||||
assign pin21 = vga_grn;
|
||||
assign pin22 = vga_grn;
|
||||
assign pin23 = vga_red;
|
||||
assign pin24 = vga_red;
|
||||
assign pin19 = vga_blu;
|
||||
assign pin20 = vga_blu;
|
||||
assign pin21 = vga_grn;
|
||||
assign pin22 = vga_grn;
|
||||
assign pin23 = vga_red;
|
||||
assign pin24 = vga_red;
|
||||
|
||||
endmodule
|
||||
@@ -30,16 +30,16 @@ module apple1_top #(
|
||||
parameter WOZMON_ROM_FILENAME = "../../../roms/wozmon.hex"
|
||||
) (
|
||||
// I/O interface to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
input uart_rx, // asynchronous serial data input from computer
|
||||
output uart_tx, // asynchronous serial data output to computer
|
||||
output uart_cts, // clear to send flag to computer
|
||||
|
||||
// Outputs to VGA display
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output reg vga_red, // red VGA signal
|
||||
output reg vga_grn, // green VGA signal
|
||||
output reg vga_blu, // blue VGA signal
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output reg vga_red, // red VGA signal
|
||||
output reg vga_grn, // green VGA signal
|
||||
output reg vga_blu, // blue VGA signal
|
||||
|
||||
// Tricolor LED on the UPDuino
|
||||
output red_led,
|
||||
@@ -47,45 +47,45 @@ module apple1_top #(
|
||||
output blue_led
|
||||
);
|
||||
|
||||
wire [15:0] leds;
|
||||
assign red_led = ~leds[9];
|
||||
assign green_led = ~leds[8];
|
||||
assign blue_led = ~leds[7];
|
||||
wire [15:0] leds;
|
||||
assign red_led = ~leds[9];
|
||||
assign green_led = ~leds[8];
|
||||
assign blue_led = ~leds[7];
|
||||
|
||||
wire clk25;
|
||||
wire clk;
|
||||
wire clk25;
|
||||
wire clk;
|
||||
|
||||
SB_HFOSC inthosc (
|
||||
.CLKHFPU(1'b1),
|
||||
.CLKHFEN(1'b1),
|
||||
.CLKHF(clk)
|
||||
);
|
||||
SB_HFOSC inthosc (
|
||||
.CLKHFPU(1'b1),
|
||||
.CLKHFEN(1'b1),
|
||||
.CLKHF (clk)
|
||||
);
|
||||
|
||||
pll pll(
|
||||
.clock_in(clk),
|
||||
.clock_out(clk25),
|
||||
);
|
||||
pll pll (
|
||||
.clock_in (clk),
|
||||
.clock_out(clk25),
|
||||
);
|
||||
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME (BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME (FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME (RAM_FILENAME),
|
||||
.VRAM_FILENAME (VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME (WOZMON_ROM_FILENAME)
|
||||
) my_apple1(
|
||||
.clk25(clk25),
|
||||
.rst_n(1'b1),
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.pc_monitor(leds),
|
||||
.ps2_select(1'b0), // no ps2 keyboard right now
|
||||
);
|
||||
// apple one main system
|
||||
apple1 #(
|
||||
.BASIC_FILENAME(BASIC_FILENAME),
|
||||
.FONT_ROM_FILENAME(FONT_ROM_FILENAME),
|
||||
.RAM_FILENAME(RAM_FILENAME),
|
||||
.VRAM_FILENAME(VRAM_FILENAME),
|
||||
.WOZMON_ROM_FILENAME(WOZMON_ROM_FILENAME)
|
||||
) my_apple1 (
|
||||
.clk25(clk25),
|
||||
.rst_n(1'b1),
|
||||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu),
|
||||
.pc_monitor(leds),
|
||||
.key_select(1'b00) // UART only for now
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -44,7 +44,7 @@ module ps2keyboard (
|
||||
|
||||
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
|
||||
@@ -70,7 +70,7 @@ module ps2keyboard (
|
||||
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))
|
||||
@@ -84,7 +84,7 @@ module ps2keyboard (
|
||||
// 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!
|
||||
@@ -93,13 +93,13 @@ module ps2keyboard (
|
||||
rx_flag <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// update previous clock state
|
||||
prev_ps2_clkdb <= ps2_clkdb;
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// IBM Keyboard code page translation
|
||||
// state machine for US keyboard layout
|
||||
@@ -138,11 +138,11 @@ module ps2keyboard (
|
||||
dout <= {ascii_rdy, 7'b0};
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// keyboard translation state machine
|
||||
if (rx_flag == 1'b1)
|
||||
begin
|
||||
// latch data from the serial buffer into
|
||||
begin
|
||||
// latch data from the serial buffer into
|
||||
// the rx scancode buffer.
|
||||
rx <= rxshiftbuf[8:1];
|
||||
case(cur_state)
|
||||
@@ -154,26 +154,26 @@ module ps2keyboard (
|
||||
next_state = S_KEYE0;
|
||||
else
|
||||
begin
|
||||
// check the debounce timer, if this is
|
||||
// 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
|
||||
end
|
||||
else begin
|
||||
if (!shift)
|
||||
case(rx)
|
||||
@@ -218,7 +218,7 @@ module ps2keyboard (
|
||||
8'h4E: ascii <= "-";
|
||||
8'h55: ascii <= "=";
|
||||
8'h5D: ascii <= 8'h34; // backslash
|
||||
8'h66: ascii <= "_"; // backspace
|
||||
8'h66: ascii <= "_"; // backspace
|
||||
8'h29: ascii <= " ";
|
||||
|
||||
8'h5A: ascii <= 8'd13; // enter
|
||||
@@ -229,7 +229,7 @@ module ps2keyboard (
|
||||
8'h41: ascii <= ",";
|
||||
8'h49: ascii <= ".";
|
||||
8'h4A: ascii <= "/";
|
||||
default:
|
||||
default:
|
||||
// unsupported key!
|
||||
begin
|
||||
ascii_rdy <= 1'b0; // shift is not a key!
|
||||
@@ -291,7 +291,7 @@ module ps2keyboard (
|
||||
8'h41: ascii <= "<";
|
||||
8'h49: ascii <= ">";
|
||||
8'h4A: ascii <= "?";
|
||||
default:
|
||||
default:
|
||||
// unsupported key!
|
||||
begin
|
||||
ascii_rdy <= 1'b0; // shift is not a key!
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
localparam [7:0] SHIFT_MASK = 8'b00100010;
|
||||
function [7:0] scancode2char(input [7:0] scancode, input [7:0] modifiers);
|
||||
reg [7:0] a;
|
||||
begin
|
||||
if (scancode >= 4 && scancode <= 29) begin // only uppercase for apple 1
|
||||
a = scancode - {8'd4} + {8'd65};
|
||||
end else if (modifiers == 0) begin
|
||||
case (scancode)
|
||||
30: a = "1";
|
||||
31: a = "2";
|
||||
32: a = "3";
|
||||
33: a = "4";
|
||||
34: a = "5";
|
||||
35: a = "6";
|
||||
36: a = "7";
|
||||
37: a = "8";
|
||||
38: a = "9";
|
||||
39: a = "0";
|
||||
40: a = 13; // enter
|
||||
41: a = 27; // esc
|
||||
42: a = "_"; // backspace - Apple1 only understands '_' for backspace
|
||||
43: a = 9; // tab
|
||||
44: a = 32; // space
|
||||
45: a = "-"; // -
|
||||
46: a = "="; // =
|
||||
47: a = "["; // [
|
||||
48: a = "]"; // ]
|
||||
49: a = "\\"; // \
|
||||
50: a = "#"; // non-use # ~
|
||||
51: a = ";"; // ;
|
||||
52: a = "'"; // '
|
||||
53: a = "`"; // `
|
||||
54: a = ","; // ,
|
||||
55: a = "."; // .
|
||||
56: a = "/"; // /
|
||||
57: ; // caps lock
|
||||
endcase
|
||||
end if ((modifiers & SHIFT_MASK) && (modifiers & ~SHIFT_MASK) == 0) begin
|
||||
// shift down
|
||||
case (scancode)
|
||||
30: a = "!";
|
||||
31: a = "@";
|
||||
32: a = "#";
|
||||
33: a = "$";
|
||||
34: a = "%";
|
||||
35: a = "^";
|
||||
36: a = "&";
|
||||
37: a = "*";
|
||||
38: a = "(";
|
||||
39: a = ")";
|
||||
40: a = "\n";
|
||||
40: a = 13; // enter
|
||||
41: a = 27; // esc
|
||||
42: a = "_"; // backspace - Apple1 only understands '_' for backspace
|
||||
43: a = 9; // tab
|
||||
44: a = 32; // space
|
||||
45: a = "_";
|
||||
46: a = "+";
|
||||
47: a = "{";
|
||||
48: a = "}";
|
||||
49: a = "|";
|
||||
50: a = "~";
|
||||
51: a = ":";
|
||||
52: a = "\"";
|
||||
53: a = "~";
|
||||
54: a = "<";
|
||||
55: a = ">";
|
||||
56: a = "?";
|
||||
57: ;
|
||||
endcase
|
||||
end
|
||||
scancode2char = a;
|
||||
end
|
||||
endfunction
|
||||
@@ -0,0 +1,394 @@
|
||||
// Usb_hid_host: A compact USB HID host core.
|
||||
//
|
||||
// nand2mario, 8/2023, based on work by hi631
|
||||
// modified heavily by Alan Garfield <alan@fromorbit.com> 09/2025
|
||||
//
|
||||
// This should support keyboard input out of the box, over low-speed
|
||||
// USB (1.5Mbps). Just connect D+, D-, VBUS (5V) and GND, and two 15K resistors between
|
||||
// D+ and GND, D- and GND. Then provide a 12Mhz clock through usbclk.
|
||||
//
|
||||
// See https://github.com/nand2mario/usb_hid_host
|
||||
//
|
||||
|
||||
module usb_hid_host (
|
||||
input usbclk, // 12MHz clock
|
||||
input usbrst_n, // reset
|
||||
inout usb_dm, usb_dp, // USB D- and D+
|
||||
|
||||
output reg [1:0] typ, // device type. 0: no device, 1: keyboard, 2: mouse, 3: gamepad
|
||||
output reg report, // pulse after report received from device.
|
||||
output conerr, // connection or protocol error
|
||||
|
||||
// keyboard
|
||||
output reg [7:0] key_modifiers,
|
||||
output reg [7:0] key1, key2, key3, key4
|
||||
|
||||
// debug
|
||||
// output [63:0] dbg_hid_report // last HID report
|
||||
);
|
||||
|
||||
wire data_rdy; // data ready
|
||||
wire data_strobe; // data strobe for each byte
|
||||
|
||||
wire [7:0] ukpdat; // actual data
|
||||
reg [7:0] regs [7:0]; // 0 (VID_L), 1 (VID_H), 2 (PID_L), 3 (PID_H), 4 (INTERFACE_CLASS), 5 (INTERFACE_SUBCLASS), 6 (INTERFACE_PROTOCOL)
|
||||
|
||||
wire save; // save dat[b] to output register r
|
||||
wire [3:0] save_r; // which register to save to
|
||||
wire [3:0] save_b; // dat[b]
|
||||
wire connected;
|
||||
|
||||
ukp ukp(
|
||||
.usbrst_n(usbrst_n),
|
||||
.usbclk(usbclk),
|
||||
.usb_dp(usb_dp),
|
||||
.usb_dm(usb_dm),
|
||||
.usb_oe(),
|
||||
.ukprdy(data_rdy),
|
||||
.ukpstb(data_strobe),
|
||||
.ukpdat(ukpdat),
|
||||
.save(save),
|
||||
.save_r(save_r),
|
||||
.save_b(save_b),
|
||||
.connected(connected),
|
||||
.conerr(conerr)
|
||||
);
|
||||
|
||||
reg [3:0] rcvct; // counter for recv data
|
||||
reg data_strobe_r, data_rdy_r; // delayed data_strobe and data_rdy
|
||||
reg [7:0] dat[7:0]; // data in last response
|
||||
// assign dbg_hid_report = {dat[7], dat[6], dat[5], dat[4], dat[3], dat[2], dat[1], dat[0]};
|
||||
|
||||
always @(posedge usbclk) begin : process_in_data
|
||||
data_rdy_r <= data_rdy;
|
||||
data_strobe_r <= data_strobe;
|
||||
report <= 0; // ensure pulse
|
||||
|
||||
if(~data_rdy) rcvct <= 0;
|
||||
else begin
|
||||
if(data_strobe && ~data_strobe_r) begin // rising edge of ukp data strobe
|
||||
dat[rcvct] <= ukpdat;
|
||||
|
||||
if (typ == 1) begin // keyboard
|
||||
case (rcvct)
|
||||
0: key_modifiers <= ukpdat;
|
||||
2: key1 <= ukpdat;
|
||||
3: key2 <= ukpdat;
|
||||
4: key3 <= ukpdat;
|
||||
5: key4 <= ukpdat;
|
||||
endcase
|
||||
end
|
||||
rcvct <= rcvct + {1'd1};
|
||||
end
|
||||
end
|
||||
if(~data_rdy && data_rdy_r && typ != 0) // falling edge of ukp data ready
|
||||
report <= 1;
|
||||
end
|
||||
|
||||
reg save_delayed;
|
||||
reg connected_r;
|
||||
always @(posedge usbclk) begin : response_recognition
|
||||
save_delayed <= save;
|
||||
if (save) begin
|
||||
regs[save_r] <= dat[save_b];
|
||||
end else if (save_delayed && ~save && save_r == 6) begin
|
||||
// falling edge of save for bInterfaceProtocol
|
||||
if (regs[4] == 3) begin // bInterfaceClass. 3: HID, other: non-HID
|
||||
if (regs[5] == 1) // bInterfaceSubClass. 1: Boot device
|
||||
typ <= regs[6] == 1 ? 1 : 2; // bInterfaceProtocol. 1: keyboard, 2: mouse
|
||||
else
|
||||
typ <= 3; // gamepad
|
||||
end else
|
||||
typ <= 0;
|
||||
end
|
||||
connected_r <= connected;
|
||||
if (~connected & connected_r) typ <= 0; // clear device type on disconnect
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module ukp(
|
||||
input usbrst_n,
|
||||
input usbclk, // 12MHz clock
|
||||
inout usb_dp, usb_dm, // D+, D-
|
||||
output usb_oe,
|
||||
output reg ukprdy, // data frame is outputing
|
||||
output ukpstb, // strobe for a byte within the frame
|
||||
output reg [7:0] ukpdat, // output data when ukpstb=1
|
||||
output reg save, // save: regs[save_r] <= dat[save_b]
|
||||
output reg [3:0] save_r, save_b,
|
||||
output reg connected,
|
||||
output conerr
|
||||
);
|
||||
|
||||
parameter S_OPCODE = 0;
|
||||
parameter S_LDI0 = 1;
|
||||
parameter S_LDI1 = 2;
|
||||
parameter S_B0 = 3;
|
||||
parameter S_B1 = 4;
|
||||
parameter S_B2 = 5;
|
||||
parameter S_S0 = 6;
|
||||
parameter S_S1 = 7;
|
||||
parameter S_S2 = 8;
|
||||
parameter S_TOGGLE0 = 9;
|
||||
parameter S_TOGGLE1 = 10;
|
||||
|
||||
wire [3:0] inst;
|
||||
reg [3:0] insth;
|
||||
wire sample; // 1: an IN sample is available
|
||||
// reg connected = 0;
|
||||
reg inst_ready = 0;
|
||||
reg up = 0;
|
||||
reg um = 0;
|
||||
reg cond = 0;
|
||||
reg nak = 0;
|
||||
reg dmis = 0;
|
||||
reg ug, ugw, nrzon; // ug=1: output enabled, 0: hi-Z
|
||||
reg bank = 0, record1 = 0;
|
||||
reg [1:0] mbit = 0; // 1: out4/outb is transmitting
|
||||
reg [3:0] state = 0, stated;
|
||||
reg [7:0] wk = 0; // W register
|
||||
reg [7:0] sb = 0; // out value
|
||||
reg [3:0] sadr; // out4/outb write ptr
|
||||
reg [13:0] pc = 0, wpc; // program counter, wpc = next pc
|
||||
reg [2:0] timing = 0; // T register (0~7)
|
||||
reg [3:0] lb4 = 0, lb4w;
|
||||
reg [13:0] interval = 0;
|
||||
reg [6:0] bitadr = 0; // 0~127
|
||||
reg [7:0] data = 0; // received data
|
||||
reg [2:0] nrztxct, nrzrxct; // NRZI trans/recv count for bit stuffing
|
||||
wire interval_cy = interval == 12001;
|
||||
wire next = ~(state == S_OPCODE & (
|
||||
inst ==2 & dmi | // start
|
||||
(inst==4 || inst==5) & timing != 0 | // out0/hiz
|
||||
inst ==13 & (~sample | (dpi | dmi) & wk != 1) | // in
|
||||
inst ==14 & ~interval_cy // wait
|
||||
));
|
||||
wire branch = state == S_B1 & cond;
|
||||
wire retpc = state == S_OPCODE && inst==7 ? 1 : 0;
|
||||
wire jmppc = state == S_OPCODE && inst==15 ? 1 : 0;
|
||||
wire dbit = sb[7-sadr[2:0]];
|
||||
wire record;
|
||||
reg dmid;
|
||||
reg [23:0] conct;
|
||||
assign conerr = conct[23] || ~usbrst_n;
|
||||
|
||||
usb_hid_host_rom ukprom(.clk(usbclk), .adr(pc), .data(inst));
|
||||
|
||||
always @(posedge usbclk) begin
|
||||
if(~usbrst_n) begin
|
||||
pc <= 0;
|
||||
connected <= 0;
|
||||
cond <= 0;
|
||||
inst_ready <= 0;
|
||||
state <= S_OPCODE;
|
||||
timing <= 0;
|
||||
mbit <= 0;
|
||||
bitadr <= 0;
|
||||
nak <= 1;
|
||||
ug <= 0;
|
||||
end else begin
|
||||
dpi <= usb_dp;
|
||||
dmi <= usb_dm;
|
||||
save <= 0; // ensure pulse
|
||||
|
||||
if (!inst_ready) begin
|
||||
inst_ready <= 1;
|
||||
end else begin
|
||||
// Instruction decoding
|
||||
case(state)
|
||||
S_OPCODE: begin
|
||||
insth <= inst;
|
||||
if(inst==1) state <= S_LDI0; // op=ldi
|
||||
if(inst==3) begin sadr <= 3; state <= S_S0; end // op=out4
|
||||
if(inst==4) begin ug <= 1; up <= 0; um <= 0; end
|
||||
if(inst==5) begin ug <= 0; end
|
||||
if(inst==6) begin sadr <= 7; state <= S_S0; end // op=outb
|
||||
if (inst[3:2]==2'b10) begin // op=10xx(BZ,BC,BNAK,DJNZ)
|
||||
state <= S_B0;
|
||||
case (inst[1:0])
|
||||
2'b00: cond <= ~dmi;
|
||||
2'b01: cond <= connected;
|
||||
2'b10: cond <= nak;
|
||||
2'b11: cond <= wk != 1;
|
||||
endcase
|
||||
end
|
||||
if(inst==11 | inst==13 & sample) wk <= wk - 1'd1; // op=DJNZ,IN
|
||||
if(inst==15) begin state <= S_B2; cond <= 1; end // op=jmp
|
||||
if(inst==12) state <= S_TOGGLE0;
|
||||
end
|
||||
// Instructions with operands
|
||||
// ldi
|
||||
S_LDI0: begin
|
||||
wk[3:0] <= inst;
|
||||
state <= S_LDI1;
|
||||
end
|
||||
S_LDI1: begin
|
||||
wk[7:4] <= inst;
|
||||
state <= S_OPCODE;
|
||||
end
|
||||
// branch/jmp
|
||||
S_B2: begin
|
||||
lb4w <= inst;
|
||||
state <= S_B0;
|
||||
end
|
||||
S_B0: begin
|
||||
lb4 <= inst;
|
||||
state <= S_B1;
|
||||
end
|
||||
// out
|
||||
S_B1: begin
|
||||
state <= S_OPCODE;
|
||||
end
|
||||
S_S0: begin
|
||||
sb[3:0] <= inst;
|
||||
state <= S_S1;
|
||||
end
|
||||
S_S1: begin
|
||||
sb[7:4] <= inst;
|
||||
state <= S_S2;
|
||||
mbit <= 1;
|
||||
end
|
||||
// toggle and save
|
||||
S_TOGGLE0: begin
|
||||
if (inst == 15) connected <= ~connected;// toggle
|
||||
else save_r <= inst; // save
|
||||
state <= S_TOGGLE1;
|
||||
end
|
||||
S_TOGGLE1: begin
|
||||
if (inst != 15) begin
|
||||
save_b <= inst;
|
||||
save <= 1;
|
||||
end
|
||||
state <= S_OPCODE;
|
||||
end
|
||||
endcase
|
||||
|
||||
// pc control
|
||||
if (mbit==0) begin
|
||||
if(jmppc) wpc <= pc + {3'd4};
|
||||
if (next | branch | retpc) begin
|
||||
if(retpc) pc <= wpc; // ret
|
||||
else if(branch)
|
||||
if(insth==15) // jmp
|
||||
pc <= { inst, lb4, lb4w, 2'b00 };
|
||||
else // branch
|
||||
pc <= { 4'b0000, inst, lb4, 2'b00 };
|
||||
else pc <= pc + {1'd1}; // next
|
||||
inst_ready <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// bit transmission (out4/outb)
|
||||
if (mbit==1 && timing == 0) begin
|
||||
if(ug==0) begin
|
||||
nrztxct <= 0;
|
||||
end else begin
|
||||
if(dbit) begin
|
||||
nrztxct <= nrztxct + {1'd1};
|
||||
end else begin
|
||||
nrztxct <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
if(insth == 4'd6) begin
|
||||
if(nrztxct!=6) begin
|
||||
up <= dbit ? up : ~up;
|
||||
um <= dbit ? ~up : up;
|
||||
end else begin
|
||||
up <= ~up;
|
||||
um <= up;
|
||||
nrztxct <= 0;
|
||||
end
|
||||
end else begin
|
||||
up <= sb[{1'b1,sadr[1:0]}]; um <= sb[sadr[2:0]];
|
||||
end
|
||||
|
||||
ug <= 1'b1;
|
||||
if(nrztxct!=6) begin
|
||||
sadr <= sadr - {1'd1};
|
||||
end
|
||||
if(sadr==0) begin
|
||||
mbit <= 0;
|
||||
state <= S_OPCODE;
|
||||
end
|
||||
end
|
||||
|
||||
// start instruction
|
||||
dmid <= dmi;
|
||||
if (inst_ready & state == S_OPCODE & inst == 4'b0010) begin // op=start
|
||||
bitadr <= 0; nak <= 1; nrzrxct <= 0;
|
||||
end else begin
|
||||
if(ug==0 && dmi!=dmid) begin
|
||||
timing <= 1;
|
||||
end else begin
|
||||
timing <= timing + {1'd1};
|
||||
end
|
||||
end
|
||||
|
||||
// IN instruction
|
||||
if (sample) begin
|
||||
if (bitadr == 8) begin
|
||||
nak <= dmi;
|
||||
end
|
||||
|
||||
if(nrzrxct!=6) begin
|
||||
data[6:0] <= data[7:1];
|
||||
data[7] <= dmis ~^ dmi; // ~^/^~ is XNOR, testing bit equality
|
||||
bitadr <= bitadr + {1'd1};
|
||||
nrzon <= 0;
|
||||
end else begin
|
||||
nrzon <= 1;
|
||||
end
|
||||
|
||||
dmis <= dmi;
|
||||
if(dmis ~^ dmi) begin
|
||||
nrzrxct <= nrzrxct + {1'd1};
|
||||
end else begin
|
||||
nrzrxct <= 0;
|
||||
end
|
||||
|
||||
if (~dmi && ~dpi) begin
|
||||
ukprdy <= 0; // SE0: packet is finished. Mouses send length 4 reports.
|
||||
end
|
||||
end
|
||||
|
||||
if (ug==0) begin
|
||||
if(bitadr==24) ukprdy <= 1; // ignore first 3 bytes
|
||||
if(bitadr==88) ukprdy <= 0; // output next 8 bytes
|
||||
end
|
||||
if ((bitadr>11 & bitadr[2:0] == 3'b000) & (timing == 2)) ukpdat <= data;
|
||||
|
||||
// Timing
|
||||
interval <= interval_cy ? {14'd0} : interval + {1'd1};
|
||||
record1 <= record;
|
||||
|
||||
if (~record & record1) bank <= ~bank;
|
||||
|
||||
// Connection status & WDT
|
||||
ukprdyd <= ukprdy;
|
||||
nakd <= nak;
|
||||
|
||||
if (ukprdy && ~ukprdyd || inst_ready && state == S_OPCODE && inst == 4'b0010)
|
||||
conct <= 0; // reset watchdog on data received or START instruction
|
||||
else begin
|
||||
if(conct[23:22]!=2'b11) conct <= conct + {1'd1};
|
||||
else begin
|
||||
pc <= 0;
|
||||
conct <= 0;
|
||||
end // !! WDT ON
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign usb_dp = ug ? up : 1'bZ;
|
||||
assign usb_dm = ug ? um : 1'bZ;
|
||||
assign usb_oe = ug;
|
||||
assign sample = inst_ready & state == S_OPCODE & inst == 4'b1101 & timing == 4; // IN
|
||||
assign record = connected & ~nak;
|
||||
assign ukpstb = ~nrzon & ukprdy & (bitadr[2:0] == 3'b100) & (timing == 2);
|
||||
reg dpi, dmi;
|
||||
reg ukprdyd;
|
||||
reg nakd;
|
||||
endmodule
|
||||
@@ -0,0 +1,536 @@
|
||||
1
|
||||
9
|
||||
0
|
||||
0
|
||||
e
|
||||
9
|
||||
a
|
||||
2
|
||||
8
|
||||
0
|
||||
0
|
||||
1
|
||||
8
|
||||
c
|
||||
0
|
||||
0
|
||||
e
|
||||
b
|
||||
4
|
||||
0
|
||||
f
|
||||
4
|
||||
3
|
||||
0
|
||||
f
|
||||
8
|
||||
4
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
f
|
||||
7
|
||||
7
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
a
|
||||
9
|
||||
0
|
||||
f
|
||||
3
|
||||
8
|
||||
0
|
||||
5
|
||||
0
|
||||
0
|
||||
0
|
||||
f
|
||||
7
|
||||
7
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
a
|
||||
e
|
||||
0
|
||||
c
|
||||
4
|
||||
6
|
||||
c
|
||||
5
|
||||
7
|
||||
f
|
||||
3
|
||||
8
|
||||
0
|
||||
5
|
||||
0
|
||||
f
|
||||
7
|
||||
7
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
a
|
||||
4
|
||||
1
|
||||
c
|
||||
6
|
||||
0
|
||||
f
|
||||
3
|
||||
8
|
||||
0
|
||||
5
|
||||
f
|
||||
4
|
||||
3
|
||||
0
|
||||
f
|
||||
6
|
||||
5
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
f
|
||||
7
|
||||
7
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
a
|
||||
d
|
||||
1
|
||||
f
|
||||
3
|
||||
8
|
||||
0
|
||||
5
|
||||
e
|
||||
f
|
||||
4
|
||||
6
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
0
|
||||
f
|
||||
b
|
||||
7
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
a
|
||||
4
|
||||
2
|
||||
f
|
||||
3
|
||||
8
|
||||
0
|
||||
5
|
||||
c
|
||||
f
|
||||
f
|
||||
f
|
||||
0
|
||||
0
|
||||
0
|
||||
8
|
||||
2
|
||||
3
|
||||
3
|
||||
3
|
||||
0
|
||||
5
|
||||
b
|
||||
1
|
||||
0
|
||||
e
|
||||
f
|
||||
f
|
||||
7
|
||||
0
|
||||
5
|
||||
f
|
||||
2
|
||||
7
|
||||
0
|
||||
a
|
||||
0
|
||||
0
|
||||
f
|
||||
3
|
||||
8
|
||||
0
|
||||
5
|
||||
f
|
||||
0
|
||||
0
|
||||
0
|
||||
c
|
||||
f
|
||||
f
|
||||
f
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
4
|
||||
1
|
||||
a
|
||||
0
|
||||
e
|
||||
b
|
||||
5
|
||||
3
|
||||
5
|
||||
1
|
||||
8
|
||||
2
|
||||
e
|
||||
3
|
||||
3
|
||||
0
|
||||
5
|
||||
b
|
||||
7
|
||||
3
|
||||
e
|
||||
7
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
d
|
||||
2
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
1
|
||||
3
|
||||
3
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
3
|
||||
c
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
6
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
1
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
2
|
||||
1
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
e
|
||||
6
|
||||
4
|
||||
f
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
d
|
||||
2
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
1
|
||||
3
|
||||
3
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
3
|
||||
c
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
6
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
2
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
8
|
||||
1
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
2
|
||||
a
|
||||
6
|
||||
4
|
||||
5
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
d
|
||||
2
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
1
|
||||
3
|
||||
3
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
3
|
||||
c
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
5
|
||||
0
|
||||
6
|
||||
1
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
b
|
||||
e
|
||||
6
|
||||
5
|
||||
2
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
d
|
||||
2
|
||||
6
|
||||
1
|
||||
0
|
||||
6
|
||||
8
|
||||
e
|
||||
3
|
||||
3
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
3
|
||||
c
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
9
|
||||
0
|
||||
6
|
||||
1
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
7
|
||||
2
|
||||
6
|
||||
5
|
||||
2
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
0
|
||||
1
|
||||
8
|
||||
6
|
||||
2
|
||||
d
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
2
|
||||
0
|
||||
0
|
||||
8
|
||||
4
|
||||
7
|
||||
b
|
||||
5
|
||||
7
|
||||
7
|
||||
0
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
9
|
||||
6
|
||||
6
|
||||
0
|
||||
0
|
||||
6
|
||||
0
|
||||
1
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
9
|
||||
6
|
||||
6
|
||||
1
|
||||
0
|
||||
6
|
||||
8
|
||||
e
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
9
|
||||
6
|
||||
6
|
||||
1
|
||||
8
|
||||
6
|
||||
8
|
||||
5
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
6
|
||||
0
|
||||
8
|
||||
6
|
||||
2
|
||||
d
|
||||
3
|
||||
3
|
||||
0
|
||||
7
|
||||
0
|
||||
0
|
||||
@@ -0,0 +1,9 @@
|
||||
module usb_hid_host_rom(clk, adr, data);
|
||||
input clk;
|
||||
input [13:0] adr;
|
||||
output [3:0] data;
|
||||
reg [3:0] data;
|
||||
reg [3:0] mem [0:535];
|
||||
initial $readmemh("usb_hid_host_rom.hex", mem);
|
||||
always @(posedge clk) data <= mem[adr];
|
||||
endmodule
|
||||
@@ -0,0 +1,90 @@
|
||||
module usb_keyboard (
|
||||
input usb_clk,
|
||||
input rst,
|
||||
|
||||
// I/O interface to computer
|
||||
input cs, // chip select, active high
|
||||
input address, // =0 RX buffer, =1 RX status
|
||||
output reg [7:0] dout, // 8-bit output bus.
|
||||
|
||||
// LEDs
|
||||
output led_connerr,
|
||||
output led_activity,
|
||||
|
||||
// USB
|
||||
inout usb_dm,
|
||||
inout usb_dp
|
||||
);
|
||||
|
||||
`include "scancodes.v"
|
||||
|
||||
wire [1:0] usb_type;
|
||||
wire [7:0] key_modifiers, key1, key2, key3, key4;
|
||||
wire [7:0] hid_regs [7:0];
|
||||
|
||||
wire usb_report;
|
||||
wire usb_conerr;
|
||||
|
||||
usb_hid_host usb (
|
||||
.usbclk(usb_clk),
|
||||
.usbrst_n(!rst),
|
||||
.usb_dm(usb_dm),
|
||||
.usb_dp(usb_dp),
|
||||
.typ(usb_type),
|
||||
.report(usb_report),
|
||||
.key_modifiers(key_modifiers),
|
||||
.key1(key1),
|
||||
.key2(key2),
|
||||
.key3(key3),
|
||||
.key4(key4),
|
||||
.conerr(usb_conerr)
|
||||
);
|
||||
|
||||
reg report_toggle; // blinks whenever there's a report
|
||||
reg usb_rdy; // new USB character flag
|
||||
reg ascii_rdy; // new ASCII character for CPU
|
||||
reg [7:0] ascii; // ASCII code of key character
|
||||
reg [7:0] key_active;
|
||||
|
||||
always @(posedge usb_clk or posedge rst) begin
|
||||
if(rst) begin
|
||||
usb_rdy <= 1'b0;
|
||||
ascii_rdy <= 1'b0;
|
||||
end else begin
|
||||
usb_rdy <= 1'b0;
|
||||
|
||||
if (usb_report) report_toggle <= ~report_toggle;
|
||||
|
||||
if (usb_report && usb_type == 1'd1) begin
|
||||
// keyboard
|
||||
if (key1 != 0 && key1 != key_active) begin
|
||||
ascii <= scancode2char(key1, key_modifiers);
|
||||
usb_rdy <= 1'b1;
|
||||
end
|
||||
key_active <= key1;
|
||||
end
|
||||
|
||||
// handle I/O from CPU
|
||||
if (cs == 1'b1) begin
|
||||
if (address == 1'b0) begin
|
||||
// CPU RX buffer address
|
||||
dout <= {1'b1, ascii[6:0]};
|
||||
ascii_rdy <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// CPU RX status register
|
||||
dout <= {ascii_rdy, 7'b0};
|
||||
end
|
||||
end
|
||||
|
||||
if (usb_rdy == 1'b1) begin
|
||||
ascii_rdy <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign led_connerr = ~usb_conerr;
|
||||
assign led_activity = ~report_toggle;
|
||||
|
||||
endmodule
|
||||
Reference in new issue
Block a user