diff --git a/boards/ice40updevboard/README.md b/boards/ice40updevboard/README.md new file mode 100644 index 0000000..a7ef79b --- /dev/null +++ b/boards/ice40updevboard/README.md @@ -0,0 +1,17 @@ +# TinyFPGA B2 support + +![ICE40UPDevBoard board render](images/ICE40UPDevBoard.png) + +This adds support for building apple one design for [Aslak3's ICE40UP Development Board](http://github.com/aslak3/ICE40UPDevBoard). The board contains a [ADV7123](https://www.analog.com/media/en/technical-documentation/data-sheets/ADV7123-EP.pdf) (PDF) RGB DAC and PS/2 port, and some I2C hardware that this Apple 1 implementation does not yet make use of. The single push button on the board is mapped to the reset line. The PS/2 port on the board is actually wired to two PS/2 connections, but this project makes only use of the first ("default") wiring for the keyboard. + +## Building +Install a recent toolchain and: + +``` +$ cd yosys +$ make +``` + +Unlike other boards in this project nextpnr-ice4 is used for routing, since it has been the current tool for some years now and arachne-pnr was deprecated in 2015. + +Program the board using any suitable method. diff --git a/boards/ice40updevboard/images/ICE40UPDevBoard.png b/boards/ice40updevboard/images/ICE40UPDevBoard.png new file mode 100644 index 0000000..fcb14c9 Binary files /dev/null and b/boards/ice40updevboard/images/ICE40UPDevBoard.png differ diff --git a/boards/ice40updevboard/yosys/Makefile b/boards/ice40updevboard/yosys/Makefile new file mode 100644 index 0000000..1bf538e --- /dev/null +++ b/boards/ice40updevboard/yosys/Makefile @@ -0,0 +1,67 @@ +DEVICE = up5k +PIN_DEF = ice40updevboard.pcf + +SOURCEDIR = ../../../rtl +BUILDDIR = build + +all: apple1 + +info: + @echo " To build: make apple1" + @echo "To build report: make report" + @echo " To clean up: make clean" + +dir: + mkdir -p $(BUILDDIR) + +# ------ TEMPLATES ------ +$(BUILDDIR)/%.json: $(SOURCEDIR)/%.v + yosys -q -p "chparam -list; hierarchy -top apple1_top; synth_ice40 -json $@" $^ + +$(BUILDDIR)/%.asc: $(BUILDDIR)/%.json + nextpnr-ice40 --up5k --package sg48 --pcf $(PIN_DEF) --json $^ --asc $@ + +$(BUILDDIR)/%.bin: $(BUILDDIR)/%.asc + icepack $^ $@ + +%.rpt: $(BUILDDIR)/%.asc + icetime -d $(DEVICE) -mtr $@ $< + +%_tb.vvp: %_tb.v %.v + iverilog -o $@ $^ + +%_tb.vcd: %_tb.vvp + vvp -N $< +vcd=$@ + +# ------ APPLE 1 ------ +apple1: dir $(BUILDDIR)/apple1.bin +report: dir apple1.rpt + +$(BUILDDIR)/apple1.bin: $(BUILDDIR)/apple1.asc +$(BUILDDIR)/apple1.asc: $(BUILDDIR)/apple1.json +$(BUILDDIR)/apple1.json: $(SOURCEDIR)/apple1.v \ + $(SOURCEDIR)/clock.v \ + $(SOURCEDIR)/pwr_reset.v \ + $(SOURCEDIR)/ram.v \ + $(SOURCEDIR)/rom_wozmon.v \ + $(SOURCEDIR)/rom_basic.v \ + $(SOURCEDIR)/cpu/arlet_6502.v \ + $(SOURCEDIR)/cpu/arlet/ALU.v \ + $(SOURCEDIR)/cpu/arlet/cpu.v \ + $(SOURCEDIR)/uart/uart.v \ + $(SOURCEDIR)/uart/async_tx_rx.v \ + $(SOURCEDIR)/vga/vga.v \ + $(SOURCEDIR)/vga/vram.v \ + $(SOURCEDIR)/vga/font_rom.v \ + $(SOURCEDIR)/ps2keyboard/debounce.v \ + $(SOURCEDIR)/ps2keyboard/ps2keyboard.v \ + $(SOURCEDIR)/boards/ice40updevboard/apple1_ice40updevboard.v + +apple1.rpt: $(BUILDDIR)/apple1.asc + +# ------ HELPERS ------ +clean: + rm -rf build apple1.rpt + +.SECONDARY: +.PHONY: all info clean diff --git a/boards/ice40updevboard/yosys/ice40updevboard.pcf b/boards/ice40updevboard/yosys/ice40updevboard.pcf new file mode 100644 index 0000000..8bd6eaa --- /dev/null +++ b/boards/ice40updevboard/yosys/ice40updevboard.pcf @@ -0,0 +1,35 @@ +### UART - This is the first 3 userheader pins, USER0 through 2 on the board +set_io uart_rx 45 +set_io uart_tx 46 +set_io uart_cts 47 + +### LEDs +set_io led[0] 38 +set_io led[1] 39 +set_io led[2] 40 + +set_io vga_h_sync 9 +set_io vga_v_sync 10 +set_io vga_clk 11 # DAC clock +set_io vga_blank_n 20 # Blanking pin + +set_io vga_r[3] 27 +set_io vga_r[2] 28 +set_io vga_r[1] 31 +set_io vga_r[0] 32 +set_io vga_g[3] 21 +set_io vga_g[2] 23 +set_io vga_g[1] 25 +set_io vga_g[0] 26 +set_io vga_b[3] 12 +set_io vga_b[2] 13 +set_io vga_b[1] 18 +set_io vga_b[0] 19 + +set_io clk 44 + +set_io ps2_din 36 +set_io ps2_clk 37 + +set_io button 41 + diff --git a/rtl/boards/ice40updevboard/apple1_ice40updevboard.v b/rtl/boards/ice40updevboard/apple1_ice40updevboard.v new file mode 100644 index 0000000..5f1c6bd --- /dev/null +++ b/rtl/boards/ice40updevboard/apple1_ice40updevboard.v @@ -0,0 +1,120 @@ +// 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: Apple 1 implementation for the Blackeice II ICE40HX8K + +// +// Author.....: Lawrence Manning +// Date.......: 18-04-2024 (inspired by blackice2/apple1_hx8k.v) +// + +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" +) ( + 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 + + // I/O interface to keyboard + 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 + + // 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 + + // Debugging ports + output [2:0] led, + input button, // 1 button on board +); + + assign vga_clk = clk25; + assign vga_blank_n = 1; + + // Active low + assign led[0] = reset_n; + assign led[1] = 1; + assign led[2] = 1; + + // =============================================================== + // System Clock generation (25MHz) + // =============================================================== + + reg clk25 = 1; + + // generate 25MHz clock from 50MHz master clock + always @(posedge clk) + begin + clk25 <= ~clk25; + end + + 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; + + // 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), + + .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 + + .vga_h_sync(vga_h_sync), + .vga_v_sync(vga_v_sync), + .vga_red(vga_bit), + .vga_cls(~reset_n), + ); +endmodule