alangarf / apple-one Goto Github PK
View Code? Open in Web Editor NEWAn attempt at a small Verilog implementation of the original Apple 1 on an FPGA
License: Apache License 2.0
An attempt at a small Verilog implementation of the original Apple 1 on an FPGA
License: Apache License 2.0
DE0 board ignores colour settings. Will fix in the near future.
dalb@latitude:~/apple-one/boards/tinyfpga_b2/yosys$ make
mkdir -p build
yosys -q -p "chparam -list; hierarchy -top apple1_top; synth_ice40 -blif build/apple1.blif" ../../../rtl/apple1.v ../../../rtl/clock.v ../../../rtl/pwr_reset.v ../../../rtl/ram.v ../../../rtl/rom_wozmon.v ../../../rtl/rom_basic.v ../../../rtl/cpu/arlet_6502.v ../../../rtl/cpu/arlet/ALU.v ../../../rtl/cpu/arlet/cpu.v ../../../rtl/uart/uart.v ../../../rtl/uart/async_tx_rx.v ../../../rtl/vga/vga.v ../../../rtl/vga/vram.v ../../../rtl/vga/font_rom.v ../../../rtl/ps2keyboard/debounce.v ../../../rtl/ps2keyboard/ps2keyboard.v ../../../rtl/boards/tinyfpga_b2/clock_pll.v ../../../rtl/boards/tinyfpga_b2/apple1_hx8k.v
/bin/sh: 1: yosys: not found
Makefile:20: recipe for target 'build/apple1.blif' failed
make: *** [build/apple1.blif] Error 127
Any idea what's going wrong?
I tried loading the ice40hx8k-evb board files. The LEDs are blinking and I'm using just the UART for IO, without VGA/PS2.
No response on UART with screen and miniterm (--rtscts /dev/ttyUSB1 115200). Even with CAPS entry.
Tried setting the ps2_select to 1'b0. Still no luck.
Anything else to check ? How do I check if CTS is willing ?
The top-level module name in apple1-top.v is 'top', which is undescriptive. Suggestion: change it to apple1-top or apple1_top.
Hi, could you please check this fork https://github.com/lawrie/apple-one
Lawrie added some boards but unfortunately he is not longer with us, it would be shame to lose those changes.
Backspace on PS/2 keyboard sends '(' instead of '_'. At least on my iCE40HX8K-EVB with iCE40-IO, see video https://youtu.be/2yIBnhapzEU . You can backspace by typing '_' using Shift+- on US keyboard.
According to the ad Apple 1 could be expanded to 32KB RAM on-board using larger chips. Could you not expand the RAM to 32KB? I think it would be fun with more RAM. The iCE40HX8K-EVB has 512KB RAM.
In the https://github.com/alangarf/apple-one/blob/master/README.md it says in the Memory Map:
0xFF00 | 0xFFFF | 512B of block RAM for WozMon ROM
But should the first value not be 0xFE00, because otherwise it's just 256B? If it is actually 256B then the comment "512B of block RAM" should be changed.
The link to the Olimex board in the README.md now goes to the wrong board (1K). It should be (8K):
https://www.olimex.com/Products/FPGA/iCE40/iCE40HX8K-EVB/open-source-hardware
Hi there, I managed to program my FPGA with this (if you remember this issue: #40
But now I am facing a problem, that I have no video output (and no serial output), even if I assigned all the pins to the designated ones (when I press CPU reset, I see the screen detects something, but I get no signal at the end), the board also does respond depending if I select UART or VGA with: https://github.com/alangarf/apple-one/blob/1d21ed1f6369cb94089a9bbe188d8e7db9e3eb08/rtl/boards/blackice2/apple1_hx8k.v#LL116C9-L116C67
(if its .ps2_select(1'b0), the screen does not respond (it doesn't even detect anything), if its .ps2_select(1'b1), the screen detect something but after that goes into no signal state
I saw there is some wire [15:0] pc_monitor; I can use:
Line 54 in 1d21ed1
now, how is this meant to be used? (I did wire it direcly to my 16 leds and when I press CPU reset, leds do come on, but don't move at all, if I press the button again, different leds come one (again when they come on they stay on forever)
So something is happening it appears, but now I have to figure out what
I did start with this example: https://github.com/alangarf/apple-one/blob/master/rtl/boards/blackice2/apple1_hx8k.v#LL116C9-L116C67
because it seamed to be the closest to my boards (I also have 100Mhz clock and 4bit VGA)
If it helps, here is my constraint file
##Pin definitions
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
#create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100MHZ}];
#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK100MHZ_IBUF]
# ps/2 keyboard
##USB HID (PS/2)
set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { PS2_KBCLK }]; #IO_L13P_T2_MRCC_35 Sch=ps2_clk
set_property -dict { PACKAGE_PIN B2 IOSTANDARD LVCMOS33 } [get_ports { PS2_KBDAT }]; #IO_L10N_T1_AD15N_35 Sch=ps2_data
##VGA Connector
set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs
set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_TXD }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { UART_RXD }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out
set_property -dict { PACKAGE_PIN D3 IOSTANDARD LVCMOS33 } [get_ports { UART_CTS }]; #IO_L12N_T1_MRCC_35 Sch=uart_cts
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { UART_RTS }]; #IO_L5N_T0_AD13N_35 Sch=uart_rts
# RESET BUTTON / SOUTH on the board
set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { RESETN_BTN }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
# INPUT SELECTION SWITCH (PS/2 vs. UART)
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { SWITCH }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
## LEDs
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { LED[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { LED[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { LED[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { LED[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { LED[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { LED[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { LED[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { LED[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { LED[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { LED[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { LED[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
and here is my apple1_nexsys_a7_top.v
`timescale 1ns / 1ps
module apple1_nexsys_a7_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 CLK100MHZ, // 100 MHz board clock
// I/O interface to computer
input UART_RXD, // asynchronous serial data input from computer
output UART_TXD, // asynchronous serial data output to computer
output UART_CTS, // clear to send flag to computer - not used
// I/O interface to keyboard
input PS2_KBCLK, // PS/2 keyboard serial clock input
input PS2_KBDAT, // PS/2 keyboard serial data input
input RESETN_BTN, // Button for RESET
input SWITCH, // Switch between PS/2 input and UART
// Outputs to VGA display
output VGA_HS, // hozizontal VGA sync pulse
output VGA_VS, // 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
// Debugging ports
output [15:0] LED
//input [1:0] button // 2 buttons on board
);
//////////////////////////////////////////////////////////////////////////
// DEBUGGING
//assign LED[0] = 1;
//assign LED[1] = reset_n;
//assign LED[2] = clr_screen_n;
//assign LED[3] = 0;
// Debugging ports
wire [15:0] pc_monitor; // spy for program counter / debugging
wire clk25;
wire rst_n;
assign rst_n = ~RESETN_BTN;
assign LED = pc_monitor;
// ===============================================================
// System Clock generation (25MHz)
// ===============================================================
reg [1:0] clkpre = 2'b00; // prescaler, from 100MHz to 25MHz
always @(posedge CLK100MHZ)
begin
clkpre <= clkpre + 1;
end
wire clk25 = clkpre[1];
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;
// 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)
) 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),
.ps2_clk(PS2_KBCLK),
.ps2_din(PS2_KBDAT),
.ps2_select(1'b1), // PS/2 disabled, UART TX enabled
//.ps2_select(SWITCH), // PS/2 enabled, UART TX disabled
//.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
//.ps2_select(1'b0), // PS/2 disabled, UART TX enabled
.vga_h_sync(VGA_HS),
.vga_v_sync(VGA_VS),
.vga_red(vga_bit),
.vga_grn(vga_bit),
.vga_blu(vga_bit),
.vga_cls(~clr_screen_n),
.vga_cls(~rst_n),
.pc_monitor(pc_monitor)
);
endmodule
As I said, it does compile, it does run (but for now, I have no way of figuring out whats going on ๐ )
Sorry for a lot of questions, I am just starting to play with FPGA (I already got VGA example working (I managed to fill the screen with blue), but am otherwise a noob ๐
I had to fix the Makefile for board olimex_ice40hx8k_evb_ice40-io:
https://github.com/alangarf/apple-one/blob/master/boards/olimex_ice40hx8k_evb_ice40-io/yosys/Makefile
I had to change to this, i.e. go up one level higher:
SOURCEDIR = ../../../rtl
I can confirm I could upload the resulting apple1.bin using winiceprogduino.exe -Icom5 apple1.bin
in Cmd.exe in Windows 10 and it works great! I compiled using WSL Ubuntu from Microsoft Store.
When I flash the sof-file everything works correctly. But when I flash the pof-file to keep the software after a power cycle the keyboard doesn't work correctly anymore. The buttons are mixed-up completely. Any idea what goes wrong here and how to fix? I use the Quartus II 13.1 (32-bit) Web Edition.
To use the bultin USB FTDI serial port to access the woz monitor, on Upduino V2.0, just change rx,tx pin mapping in boards/upduino/yosys/ice40up5k.pcf as follows
set_io -nowarn uart_rx 15
set_io -nowarn uart_tx 14
Then in boards/upduino/yosys/Makefile, find the "prog:" target and remove -S switch. This allows iceprog to program the SPI flash onboard.
After programming the chip, on Linux the USB FTDI inteface may become unresponsive. To restore communication you can just unplug and reinsert USB connector, or you can reload the ftdi kernel module, by issuing the command:
sudo rmmod ftdi_sio
followed by:
sudo mod_probe ftdi_sio
Damiano
Hello there, I saw your awesome project and just happen to have this Nexys A7 FPGA: https://digilent.com/shop/nexys-a7-fpga-trainer-board-recommended-for-ece-curriculum/
at hand, it has onboard VGA, doesn't have onboard PS/2 (I could probably wire a PS/2 connector externaly), but I also found an USB keyboard demo: https://github.com/Digilent/Nexys-A7-100T-Keyboard/tree/master
Which if I understands corecly allows you to connect USB keyboard to FPGA and it would convert it to PS/2 scancodes
Or I could always use SerialTerminal if PS/2 doesn't work ๐
If I understand everything to port this to my board I just need to define inputs and outputs and I should at least have a picture from VGA display at first (if input doesn't work yet)
What I am very confused is how to open this project in Vivado (if thats even possible)
Thanks for Anwsering and Best Regards
Maybe is not the right way to ask this.
I'm working on a TFG(in spanish), final degree thesis in Computers Engineering in UPM,Madrid,Spain. I had found this repository with an interesting proyect.
I want to know, if there is any possibility to change some things to work on a Zybo Zynq-7000 FPGA board, is the "oldest" board that my university has. If someone thinks there is possible, I need some help with small things concerning with Verilog and which codes I should modify.
First, why Vivado don't accept .inc files for the 6502 code?
Solved: "wrong path for "`include" to ".inc" files" & "changed ".inc" to ".vh" because don't make any difference".
Thanks,
Oskar
Contact: [email protected]
PS. Maybe I had some mystakes on my English, sorry.
I try in WozMon to change background color using C002:1 and C002:2, but nothing changes.
I tried to look at the Verilog code, but I see nothing wrong with it. It is possible to have different colors in VGA using iCE40HX8K with ICE40-IO because a demo from Olimex has this.
I get the following program counter values at boot time (DE0 + Quartus) :
FFFE
FFFD -- fetch instruction
FF01
FF02
FF03
FF02 -- don't understand this value
FFFE
FFFF
0001
0002
FFFE
FFFF
0001
0002 -- continues the prev 4 instructions forever
I think the 6502 reads 0x00 as the next instruction, which is a BRK instruction, and it resets itself.
Could be a problem with RAM/ROM or some timing issue.
ps. I think in some cases, the PC is +1 because it already points to the next instruction.
There is no button that works for clearing the screen on iCE40HX8K, but BUT2 could have this role. I think the warning on the last line in the code box below could have something to do with this.
pi@lenovo5:~/apple-one/boards/olimex_ice40hx8k_evb_ice40-io/yosys$ make
mkdir -p build
yosys -q -p "chparam -list; hierarchy -top apple1_top; synth_ice40 -blif build/apple1.blif" ../../../rtl/apple1.v ../../../rtl/clock.v ../../../rtl/pwr_reset.v ../../../rtl/ram.v ../../../rtl/rom_wozmon.v ../../../rtl/rom_basic.v ../../../rtl/cpu/arlet_6502.v ../../../rtl/cpu/arlet/ALU.v ../../../rtl/cpu/arlet/cpu.v ../../../rtl/uart/uart.v ../../../rtl/uart/async_tx_rx.v ../../../rtl/vga/vga.v ../../../rtl/vga/vram.v ../../../rtl/vga/font_rom.v ../../../rtl/ps2keyboard/debounce.v ../../../rtl/ps2keyboard/ps2keyboard.v ../../../rtl/boards/olimex_ice40hx8k/pll.v ../../../rtl/boards/olimex_ice40hx8k/apple1_hx8k.v
Warning: Replacing memory \AXYS with list of registers. See ../../../rtl/cpu/arlet/cpu.v:541
Warning: Wire apple1_top.\my_apple1.my_vga.clr_screen is used but has no driver.
BUT1 starts WozMon without clearing the screen.
BUT2 does nothing.
RESET1 resets i.e. clears the screen and starts WozMon.
PS/2 and serial in ought to work at the same time. Now you have to change this file for Olimex iCE40HX8K-EVB each time you want to use a different input source:
https://github.com/alangarf/apple-one/blob/master/rtl/boards/olimex_ice40hx8k/apple1_hx8k.v
.ps2_select(1'b1), // PS/2 enabled, UART TX disabled
//.ps2_select(1'b0), // PS/2 disabled, UART TX enabled
Also, should it not say UART RX in the comments above? if you are talking about the Apple One side.
I see some boards use a switch or toggle button to switch key input source. I think if Bluetooth, USB, and Apple II keyboard ports are added in the future they should also work at the same time as PS/2 and serial. Then you don't need to switch key input source.
I use serial to paste in code in Apple I, see e.g. this article with link to a video:
Apple-I Checkers AI & USB to Serial & FPGA programmer for Olimex iCE40HX8K-EVB
https://www.reddit.com/r/FPGA/comments/8k42g7/applei_checkers_ai_usb_to_serial_fpga_programmer/
https://github.com/mobluse/iCE40HX1K-EVB/tree/master/programmer/olimexino-32u4%20firmware
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.