{"id":13474931,"url":"https://github.com/howerj/forth-cpu","last_synced_at":"2025-12-26T23:44:33.378Z","repository":{"id":8134666,"uuid":"9552590","full_name":"howerj/forth-cpu","owner":"howerj","description":"A Forth CPU and System on a Chip, based on the J1, written in VHDL","archived":false,"fork":false,"pushed_at":"2024-03-19T21:00:50.000Z","size":18084,"stargazers_count":330,"open_issues_count":0,"forks_count":29,"subscribers_count":24,"default_branch":"master","last_synced_at":"2024-10-30T08:51:08.387Z","etag":null,"topics":["c","cpu","forth","fpga","processor","simulator","softcore","target-board","vhdl"],"latest_commit_sha":null,"homepage":"","language":"VHDL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/howerj.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"howerj","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2013-04-19T19:07:48.000Z","updated_at":"2024-10-23T18:05:42.000Z","dependencies_parsed_at":"2024-10-30T06:51:39.394Z","dependency_job_id":null,"html_url":"https://github.com/howerj/forth-cpu","commit_stats":{"total_commits":710,"total_committers":3,"mean_commits":"236.66666666666666","dds":0.05070422535211272,"last_synced_commit":"e3e8a69fa1bae49e40a48456596191b06b4af94d"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/howerj%2Fforth-cpu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/howerj%2Fforth-cpu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/howerj%2Fforth-cpu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/howerj%2Fforth-cpu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/howerj","download_url":"https://codeload.github.com/howerj/forth-cpu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245747845,"owners_count":20665874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","cpu","forth","fpga","processor","simulator","softcore","target-board","vhdl"],"created_at":"2024-07-31T16:01:16.045Z","updated_at":"2025-12-26T23:44:33.338Z","avatar_url":"https://github.com/howerj.png","language":"VHDL","readme":"# Forth computing system\n\n| Project   | Forth SoC written in VHDL |\n| --------- | ------------------------- |\n| Author    | Richard James Howe        |\n| Copyright | 2013-2019 Richard Howe    |\n| License   | MIT/LGPL                  |\n| Email     | howe.r.j.89@gmail.com     |\n\n![H2 build status](https://travis-ci.org/howerj/forth-cpu.svg?branch=master \"Build status of the H2 Assembler\")\n\n# Introduction\n\nThis project implements a small stack computer tailored to executing Forth\nbased on the [J1][] CPU. The processor has been rewritten in [VHDL][] from\n[Verilog][], and extended slightly.\n\nThe goals of the project are as follows:\n\n* Create a working version of [J1][] processor (called the H2).\n* Make a working toolchain for the processor.\n* Create a [FORTH][] for the processor which can take its input either from a\n  [UART][] or a USB keyboard and a [VGA][] adapter.\n\nAll three of which have been completed.\n\nThe H2 processor, like the [J1][], is a stack based processor that executes an\ninstruction set especially suited for [FORTH][].\n\nThe current target is the [Nexys3][] board, with a [Xilinx][] Spartan-6 XC6LX16-CS324\n[FPGA][], new boards will be targeted in the future as this board is reaching it's\nend of life. The [VHDL][] is written in a generic way, with hardware components\nbeing inferred instead of explicitly instantiated, this should make the code\nfairly portable, although the interfaces to the [Nexys3][] board components are\nspecific to the peripherals on that board.\n\nA video of the project in action, on the hardware, can be viewed here:\n\nhttps://user-images.githubusercontent.com/1807662/159563952-729cdfa2-9eef-4969-ba0f-ac8bbb03ce9c.mp4\n\nThe SoC can also be simulated with a simulator written in C, as shown below:\n\n![GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/sim2.gif)\n\nThe System Architecture is as follows:\n\n![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.png)\n\n# License\n\nThe licenses used by the project are mixed and are on a per file basis. For my\ncode I use the [MIT][] license - so feel free to use it as you wish. The other\nlicenses used are the [LGPL][] and the [Apache 2.0][] license, they are confined \nto single modules so could be removed if you have some aversion to [LGPL][] code.\n\n# Target Board\n\nThe only target board available at the moment is the [Nexys3][], this should\nchange in the future as the board is currently at it's End Of Life. The next\nboards I am looking to support are it's successor, the Nexys 4, and the myStorm\nBlackIce (\u003chttps://mystorm.uk/\u003e). The myStorm board uses a completely open\nsource toolchain for synthesis, place and route and bit file generation.\n\n# Build and Running requirements\n\nThe build has been tested under [Debian][] [Linux][], version 8.\n\nYou will require:\n\n* [GCC][], or a suitable [C][] compiler capable of compiling [C99][]\n* [Make][]\n* [Xilinx ISE][] version 14.7\n* [GHDL][]\n* [GTKWave][]\n* [tcl][] version 8.6\n* Digilent Adept2 runtime and Digilent Adept2 utilities available at\n  \u003chttp://store.digilentinc.com/digilent-adept-2-download-only/\u003e\n* [freeglut][] (for the GUI simulator only)\n* [pandoc][] for building the documentation\n* [picocom][] (or an alternative terminal client)\n\nHardware:\n\n* VGA Monitor, and cable (Optional)\n* USB Keyboard (Optional) (plugs into the Nexys3 USB to PS/2 bridge)\n* [Nexys3][] development board (if communication via UART only is\ndesired, the VGA Monitor and USB and Keyboard are not needed).\n* USB Cables!\n\n[Xilinx ISE][] can (or could be) downloaded for free, but requires\nregistration. ISE needs to be on your path:\n\n\tPATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64;\n\tPATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/lib/lin64;\n\n# Building and Running\n\nTo make the [C][] based toolchain:\n\n\tmake embed.hex\n\nTo make a bit file that can be flashed to the target board:\n\n\tmake simulation synthesis implementation bitfile\n\nTo upload the bitfile to the target board:\n\n\tmake upload\n\nTo view the wave form generated by \"make simulation\":\n\n\tmake viewer\n\nThe [C][] based CLI simulator can be invoked with:\n\n\tmake run\n\nWhich will assemble the H2 Forth source file [embed.fth][], and run the assembled\nobject file under the H2 simulator with the debugger activated. A graphical\nsimulator can be run with:\n\n\tmake gui-run\n\nWhich requires [freeglut][] as well as a [C][] compiler.\n\n# Related Projects\n\nThe original [J1][] project is available at:\n\n* \u003chttp://www.excamera.com/sphinx/fpga-j1.html\u003e\n\nThis project targets the original [J1][] core and provides a eForth\nimplementation (written using [Gforth][] as for meta-compilation/cross\ncompilation to the [J1][] core). It also provides a simulator for the system\nwritten in [C][].\n\n* \u003chttps://github.com/samawati/j1eforth\u003e\n\nThe eForth interpreter which the meta-compiler is built on can be found at: \n\n* \u003chttps://github.com/howerj/embed\u003e\n\n# Manual\n\nThe H2 processor and associated peripherals are now quite stable, however the\nsource is always the definitive guide as to how instructions and peripherals\nbehave, as well as the register map.\n\nThere are a few modifications to the [J1][] CPU which include:\n\n* New instructions\n* A CPU hold line which keeps the processor in the same state so long as it is\nhigh.\n* Interrupt Service Routines have been added.\n* Larger (adjustable at time of synthesis) return and data stacks\n\n### H2 CPU\n\nThe H2 CPU behaves very similarly to the [J1][] CPU, and the [J1 PDF][] can be\nread in order to better understand this processor. The processor is 16-bit with\ninstructions taking a single clock cycle. Most of the primitive Forth words can\nalso be executed in a single cycle as well, one notable exception is store (\"!\"),\nwhich is split into two instructions.\n\nThe CPU has the following state within it:\n\n* A 64 deep return stack (up from 32 in the original [J1][])\n* A 65 deep variable stack (up from 33 in the original [J1][])\n* A program counter\n* An interrupt enable and interrupt request bit\n* An interrupt address register\n* Registers to delay and hold the latest IRQ and hold-line values\n\nLoads and stores into the block RAM that holds the H2 program discard the\nlowest bit, every other memory operation uses the lower bit (such as jumps\nand loads and stores to Input/Output peripherals). This is so applications can\nuse the lowest bit for character operations when accessing the program RAM.\n\nThe instruction set is decoded in the following manner:\n\n\t+---------------------------------------------------------------+\n\t| F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |\n\t+---------------------------------------------------------------+\n\t| 1 |                    LITERAL VALUE                          |\n\t+---------------------------------------------------------------+\n\t| 0 | 0 | 0 |            BRANCH TARGET ADDRESS                  |\n\t+---------------------------------------------------------------+\n\t| 0 | 0 | 1 |            CONDITIONAL BRANCH TARGET ADDRESS      |\n\t+---------------------------------------------------------------+\n\t| 0 | 1 | 0 |            CALL TARGET ADDRESS                    |\n\t+---------------------------------------------------------------+\n\t| 0 | 1 | 1 |   ALU OPERATION   |T2N|T2R|N2A|R2P| RSTACK| DSTACK|\n\t+---------------------------------------------------------------+\n\t| F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |\n\t+---------------------------------------------------------------+\n\n\tT   : Top of data stack\n\tN   : Next on data stack\n\tPC  : Program Counter\n\n\tLITERAL VALUES : push a value onto the data stack\n\tCONDITIONAL    : BRANCHS pop and test the T\n\tCALLS          : PC+1 onto the return stack\n\n\tT2N : Move T to N\n\tT2R : Move T to top of return stack\n\tN2A : STORE T to memory location addressed by N\n\tR2P : Move top of return stack to PC\n\n\tRSTACK and DSTACK are signed values (twos compliment) that are\n\tthe stack delta (the amount to increment or decrement the stack\n\tby for their respective stacks: return and data)\n\n#### ALU operations\n\n\nAll ALU operations replace T:\n\n| Value |   Operation    |     Description       |\n|-------|----------------|-----------------------|\n|   0   |       T        |  Top of Stack         |\n|   1   |       N        |  Copy T to N          |\n|   2   |     T + N      |  Addition             |\n|   3   |     T \u0026 N      |  Bitwise AND          |\n|   4   |     T or N     |  Bitwise OR           |\n|   5   |     T ^ N      |  Bitwise XOR          |\n|   6   |      ~T        |  Bitwise Inversion    |\n|   7   |     T = N      |  Equality test        |\n|   8   |     N \u003c T      |  Signed comparison    |\n|   9   |     N \u003e\u003e T     |  Logical Right Shift  |\n|  10   |     T - 1      |  Decrement            |\n|  11   |       R        |  Top of return stack  |\n|  12   |      [T]       |  Load from address    |\n|  13   |     N \u003c\u003c T     |  Logical Left Shift   |\n|  14   |     depth      |  Depth of stack       |\n|  15   |     N u\u003c T     |  Unsigned comparison  |\n|  16   | Set CPU State  |  Enable interrupts    |\n|  17   | Get CPU State  |  Are interrupts on?   |\n|  18   |     rdepth     |  Depth of return stk  |\n|  19   |      0=        |  T == 0?              |\n|  20   |     CPU ID     |  CPU Identifier       |\n|  21   |     LITERAL    |  Internal Instruction |\n\n\n### Peripherals and registers\n\nRegisters marked prefixed with an 'o' are output registers, those with an 'i'\nprefix are input registers. Registers are divided into an input and output\nsection of registers and the addresses of the input and output registers do not\ncorrespond to each other in all cases. \n\nThe following peripherals have been implemented in the [VHDL][] SoC to\ninterface with devices on the [Nexys3][] board:\n\n* [VGA][] output device, text mode only, 80 by 40 characters from\n  \u003chttp://www.javiervalcarce.eu/html/vhdl-vga80x40-en.html\u003e. This has\nbeen heavily modified from the original, which now implements most of a\n[VT100][] terminal emulator. This has two fonts available to it:\n  - [Terminus][]/[KOI8-R][] (Default)\n  - Latin [ISO-8859-15][] (Secondary Font) from\n  \u003chttps://git.kernel.org/pub/scm/linux/kernel/git/legion/kbd.git\u003e\n* [Timer][] in [timer.vhd][].\n* [UART][] (Rx/Tx) in [uart.vhd][].\n* [PS/2][] Keyboard\nfrom \u003chttps://eewiki.net/pages/viewpage.action?pageId=28279002\u003e\n* [LED][] next to a bank of switches\n* A [7 Segment LED Display][] driver (a 7 segment display with a decimal point)\n\nThe SoC also features a limited set of interrupts that can be enabled or\ndisabled.\n\nThe output register map:\n\n| Register    | Address | Description                     |\n|-------------|---------|---------------------------------|\n| oUart       | 0x4000  | UART register                   |\n| oVT100      | 0x4002  | VT100 Terminal Write            |\n| oLeds       | 0x4004  | LED outputs                     |\n| oTimerCtrl  | 0x4006  | Timer control                   |\n| oMemDout    | 0x4008  | Memory Data Output              |\n| oMemControl | 0x400A  | Memory Control / Hi Address     |\n| oMemAddrLow | 0x400C  | Memory Lo Address               |\n| o7SegLED    | 0x400E  | 4 x LED 7 Segment display       |\n| oIrcMask    | 0x4010  | CPU Interrupt Mask              |\n| oUartBaudTx | 0x4012  | UART Tx Baud Clock Setting      |\n| oUartBaudRx | 0x4014  | UART Rx Baud Clock Setting      |\n\n\nThe input registers:\n\n| Register    | Address | Description                     |\n|-------------|---------|---------------------------------|\n| iUart       | 0x4000  | UART register                   |\n| iVT100      | 0x4002  | Terminal status \u0026 PS/2 Keyboard |\n| iSwitches   | 0x4004  | Buttons and switches            |\n| iTimerDin   | 0x4006  | Current Timer Value             |\n| iMemDin     | 0x4008  | Memory Data Input               |\n\n\nThe following description of the registers should be read in order and describe\nhow the peripherals work as well.\n\n#### oUart\n\nA UART with a fixed baud rate and format (115200, 8 bits, 1 stop bit) is\npresent on the SoC. The UART has a FIFO of depth 8 on both the RX and TX\nchannels. The control of the UART is split across oUart and iUart.\n\nTo write a value to the UART assert TXWE along with putting the data in TXDO.\nThe FIFO state can be analyzed by looking at the iUart register.\n\nTo read a value from the UART: iUart can be checked to see if data is present\nin the FIFO, if it is assert RXRE in the oUart register, on the next clock\ncycle the data will be present in the iUart register.\n\nThe baud rate of the UART can be changed by rebuilding the VHDL project, bit\nlength, parity bits and stop bits can only be changed with modifications to\n[uart.vhd][]\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |\n\t+-------------------------------------------------------------------------------+\n\n\tTXWE: UART TX Write Enable\n\tRXRE: UART RX Read Enable\n\tTXDO: UART TX Data Output\n\n#### oVT100\n\nThe VGA Text device emulates a terminal which the user can talk to by writing\nto the oVT100 register. It supports a subset of the [VT100][] terminal\nfunctionality. The interface behaves much like writing to a UART with the same\nbusy and control signals. The input is taken from a [PS/2][] keyboard available\non the board, this behaves like the RX mechanism of the UART.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |\n\t+-------------------------------------------------------------------------------+\n\n\tTXWE: VT100 TX Write Enable\n\tRXRE: UART RX Read Enable\n\tTXDO: UART TX Data Output\n\n#### oLeds\n\nOn the [Nexys3][] board there is a bank of LEDs that are situated next to the\nswitches, these LEDs can be turned on (1) or off (0) by writing to LEDO. Each\nLED here corresponds to the switch it is next to.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |  X |  X |  X |  X |  X |  X |              LEDO                     |\n\t+-------------------------------------------------------------------------------+\n\n\tLEDO: LED Output\n\n#### oTimerCtrl\n\nThe timer is controllable by the oTimerCtrl register, it is a 13-bit timer\nrunning at 100MHz, it can optionally generate interrupts and the current timers\ninternal count can be read back in with the iTimerDin register.\n\nThe timer counts once the TE bit is asserted, once the timer reaches TCMP value\nit wraps around and can optionally generate an interrupt by asserting INTE.\nThis also toggles the Q and NQ lines that come out of the timer and are routed\nto pins on the board (see the constraints file [top.ucf][] for the pins).\n\nThe timer can be reset by writing to RST.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t| TE | RST|INTE|                      TCMP                                      |\n\t+-------------------------------------------------------------------------------+\n\n\tTE:   Timer Enable\n\tRST:  Timer Reset\n\tINTE: Interrupt Enable\n\tTCMP: Timer Compare Value\n\n\n#### oIrcMask\n\nThe H2 core has a mechanism for interrupts, interrupts have to be enabled or\ndisabled with an instruction. Each interrupt can be masked off with a bit in\nIMSK to enable that specific interrupt. A '1' in a bit of IMSK enables that\nspecific interrupt, which will be delivered to the CPU if interrupts are\nenabled within it.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |  X |  X |  X |  X |  X |  X |                 IMSK                  |\n\t+-------------------------------------------------------------------------------+\n\n\tIMSK: Interrupt Mask\n\n#### oUartBaudTx\n\nThis register is used to set the baud and sample clock frequency for\ntransmission only.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|                                    BTXC                                       |\n\t+-------------------------------------------------------------------------------+\n\n\tBTXC: Baud Clock Settings\n\n#### oUartBaudRx\n\nThis register is used to set the baud and sample clock frequency for\nreception only.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|                                    BRXC                                       |\n\t+-------------------------------------------------------------------------------+\n\n\tBRXC: Baud Clock Settings\n\n\n#### oMemDout\n\nData to be output to selected address when write enable (WE) issued in\noMemControl.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|                           Data Ouput                                          |\n\t+-------------------------------------------------------------------------------+\n\n#### oMemControl\n\nThis register contains the control registers for the onboard memory on the\n[Nexys3][] board. The board contains three memory devices, two non-volatile\nmemory devices and a volatile RAM based device. The two devices accessible by a\nsimple SRAM interface (one volatile M45W8MW16, one non-volatile - a\nNP8P128A13T1760E) are both accessible, the third is an SPI based memory device,\nNP5Q128A13ESFC0E) and is currently not accessible.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t| OE | WE | RST|WAIT| RCS| FCS|                 Address Hi                      |\n\t+-------------------------------------------------------------------------------+\n\n\tOE:  Output Enable - enable reading from current address into iMemDin\n\tWE:  Write Enable  - enable writing oMemDout into ram at current address\n\tRST: Reset the Flash memory controller\n\tRCS: RAM Chip Select, Enable Volatile Memory\n\tFCS: Flash Chip Select, Enable Non-Volatile Memory\n\tAddress Hi: High Bits of RAM address\n\nOE and WE are mutually exclusive, if both are set then there is no effect.\n\nThe memory controller is in active development, and the interface to it might\nchange.\n\n#### oMemAddrLow\n\nThis is the lower address bits of the RAM.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|                           Address Lo                                          |\n\t+-------------------------------------------------------------------------------+\n\n#### o7SegLED\n\nOn the [Nexys3][] board there is a bank of 7 segment displays, with a decimal \npoint (8-segment really), which can be used for numeric output. The LED segments\ncannot be directly addressed. Instead the value stored in L8SD is mapped\nto a hexadecimal display value (or a BCD value, but this requires regeneration\nof the SoC and modification of a generic in the VHDL).\n\nThe value '0' corresponds to a zero displayed on the LED segment, '15' to an\n'F', etcetera.\n\nThere are 4 displays in a row.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|      L7SD0        |       L7SD1       |       L7SD2       |       L7SD3       |\n\t+-------------------------------------------------------------------------------+\n\n\tL7SD0: LED 7 Segment Display (leftmost display)\n\tL7SD1: LED 7 Segment Display\n\tL7SD2: LED 7 Segment Display\n\tL7SD3: LED 7 Segment Display (right most display)\n\n#### iUart\n\nThe iUart register works in conjunction with the oUart register. The status of\nthe FIFO that buffers both transmission and reception of bytes is available in\nthe iUart register, as well as any received bytes.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|                RXDI                   |\n\t+-------------------------------------------------------------------------------+\n\n\tTFFL: UART TX FIFO Full\n\tTFEM: UART TX FIFO Empty\n\tRFFL: UART RX FIFO Full\n\tRFEM: UART RX FIFO Empty\n\tRXDI: UART RX Data Input\n\n#### iVT100\n\nThe iVT100 register works in conjunction with the oVT100 register. The status of\nthe FIFO that buffers both transmission and reception of bytes is available in\nthe iVT100 register, as well as any received bytes. It works the same as the\niUart/oUart registers.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|  0 |           ACHR                   |\n\t+-------------------------------------------------------------------------------+\n\n\tTFFL: VGA VT100 TX FIFO Full\n\tTFEM: VGA VT100 TX FIFO Empty\n\tRFFL: PS2 VT100 RX FIFO Full\n\tRFEM: PS2 VT100 RX FIFO Empty\n\tACHR: New character available on PS2 Keyboard\n\n#### iTimerDin\n\nThis register contains the current value of the timers counter.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |  X |                       TCNT                                     |\n\t+-------------------------------------------------------------------------------+\n\n\tTCNT: Timer Counter Value\n\n#### iSwitches\n\niSwitches contains input lines from multiple sources. The buttons\n(BUP, BDWN, BLFT, BRGH, and BCNT) correspond to a [D-Pad][] on the [Nexys3][]\nboard. The switches (TSWI) are the ones mentioned in oLeds, each have an LED\nnext to them.\n\nThe switches and the buttons are already debounced in hardware so they do not\nhave to be further processed once read in from these registers.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|  X |  X |  X | BUP|BDWN|BLFT|BRGH|BCNT|               TSWI                    |\n\t+-------------------------------------------------------------------------------+\n\n\tBUP:  Button Up\n\tBDWN: Button Down\n\tBLFT: Button Left\n\tBRGH: Button Right\n\tBCNT: Button Center\n\tTSWI: Two Position Switches\n\n#### iMemDin\n\nMemory input, either from the SRAM or Flash, indexed by oMemControl and\noMemAddrLow. When reading from flash this might actually be status information\nor information from the query table.\n\n\t+-------------------------------------------------------------------------------+\n\t| 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |\n\t+-------------------------------------------------------------------------------+\n\t|                           Data Input                                          |\n\t+-------------------------------------------------------------------------------+\n\n\n### Interrupt Service Routines\n\nThe following interrupt service routines are defined:\n\n|       Name        | Number |         Description           |\n|-------------------|--------|-------------------------------|\n| isrNone           |   0    | Not used                      |\n| isrRxFifoNotEmpty |   1    | UART RX FIFO Is Not Empty     |\n| isrRxFifoFull     |   2    | UART RX FIFI Is Full          |\n| isrTxFifoNotEmpty |   3    | UART TX FIFO Is Not Empty     |\n| isrTxFifoFull     |   4    | UART TX FIFO Is Full          |\n| isrKbdNew         |   5    | New PS/2 Keyboard Character   |\n| isrTimer          |   6    | Timer Counter                 |\n| isrDPadButton     |   7    | Any D-Pad Button Change State |\n\n\nWhen an interrupt occurs, and interrupts are enabled within the processor, then\na call to the location in memory is performed - the location is the same as the\nISR number. An ISR with a number of '4' will perform a call (not a jump) to the\nlocation '4' within memory, for example.\n\nInterrupts have a latency of at least 4-5 cycles before they are acted on, there\nis a two to three cycle delay in the interrupt request handler, then the call\nto the ISR location in memory has to be done, then the call to the word that\nimplements the ISR itself.\n\nIf two interrupts occur at the same time they are processed from the lowest\ninterrupt number to the highest.\n\nInterrupts are lost when an interrupt with the same number occurs that has not\nbeen processed.\n\n# The Toolchain\n\nThe Disassembler and [C][] based simulator for the H2 is in a single\nprogram (see [h2.c][]). This simulator complements the [VHDL][] test bench\n[tb.vhd][] and is not a replacement for it. The meta-compiler runs on top of an\neForth interpreter and it contained within the files [embed.c][] and\n[embed.blk][]. The meta-compiler (Forth parlance for a cross-compiler) is a\nForth program which is used to create the eForth image that runs on the target.\n\nThe toolchain is currently in flux, going forward there is liable to more\nintegration between [h2.c][] and [embed.c][], along with changing the Embed\nVirtual Machine into one that more closely resembles the H2 CPU with the long\nterm goal of creating a self hosting system.\n\nTo build both, a [C][] compiler is needed, the build target \"h2\" will build the\nexecutable, h2, and \"embed\" will build the meta-compiler:\n\n\tmake h2 embed\n\nAnd it can be run on the source file [embed.fth][] with the make target:\n\n\tmake run\n\nThe make file is not needed:\n\n\tLinux:\n\n\tcc -std=c99 h2.c -o h2        # To build the h2 executable\n\tcc -std=c99 embed.c -o embed  # To build the embed VM executable\n\t./embed embed.blk embed.hex embed.fth # Create the target eForth image\n\t./h2 -h                     # For a list of options\n\t./h2 -r embed.hex           # Run the assembled file\n\n\tWindows:\n\n\tgcc -std=c99 h2.c -o h2.exe       # Builds the h2.exe executable\n\tgcc -std=c99 embed.c -o embed.exe # Builds the embed.exe executable\n\tembed.exe embed.blk embed.hex embed.fth # Create the target eForth iamge\n\th2.exe -h                   # For a list of options\n\th2.exe -r embed.hex         # Run the assembled file\n\nA list of command line options available:\n\n        -       stop processing options, following arguments are files\n        -h      print a help message and exit\n        -v      increase logging level\n        -d      disassemble input files (default)\n        -D      full disassembly of input files\n        -T      Enter debug mode when running simulation\n        -r      run hex file\n        -L #    load symbol file\n        -s #    number of steps to run simulation (0 = forever)\n\t-n #    specify NVRAM block file (default is nvram.blk)\n        file*   file to process\n\nThis program is released under the [MIT][] license, feel free to use it and\nmodify it as you please. With minimal modification it should be able to\nassemble programs for the original [J1][] core.\n\n## Meta-Compiler\n\nThe meta-compiler runs on top of the [embed][] virtual machine, it is a 16-bit\nvirtual machine that originally descended from the H2 CPU. The project includes\na meta-compilation scheme that allows an eForth image to generate a new eForth\nimage with modifications. That system has been adapted for use with the H2,\nwhich replaced the cross compiler written in C, which allowed the first image\nfor the H2 to be created.\n\nThe meta-compiler is an ordinary Forth program, it is contained within\n[embed.fth][]. The meta-compiler Forth program is then used to build up an\neForth image capable of running on the H2 target.\n\nFor more information about meta-compilation in Forth, see:\n\n* \u003chttps://github.com/howerj/embed\u003e\n* \u003chttps://github.com/howerj/embed/blob/master/embed.fth\u003e\n* \u003chttp://www.ultratechnology.com/meta.html\u003e\n\n## Disassembler\n\nThe disassembler takes a text file containing the assembled program, which\nconsists of 16-bit hexadecimal numbers. It then attempts to disassemble the\ninstructions. It can also be fed a symbols file which can be generated by the\nassembler and attempt to find the locations jumps and calls point to.\n\nThe disassembler is used by a [tcl][] script called by [GTKwave][], it\nturns the instruction trace of the H2 from a series of numbers into the\ninstructions and branch destinations that they represent. This makes debugging\nthe VHDL much easier.\n\n![H2 Disassembly Results](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-wave.png \"Dissembled Instructions in GTKWave\")\n\nThe purple trace shows the disassembled instructions.\n\n## Simulator\n\nThe simulator in C implements the H2 core and most of the SoC. The IO for the\nsimulator is not cycle accurate, but can be used for running and debugging\nprograms with results that are very similar to how the hardware behaves.\nThis is much faster than rebuilding the bit file used to flash the [FPGA][].\n\n## Debugger\n\nThe simulator also includes a debugger, which is designed to be similar to the\n[DEBUG.COM][] program available in [DOS][]. The debugger can be used to\ndisassemble sections of memory, inspect the status of the peripherals and dump\nsections of memory to the screen. It can also be used to set breakpoints,\nsingle step and run through the code until a breakpoint is hit.\n\nTo run the debugger either a hex file or a source file must be given:\n\n\t# -T turns debugging mode on\n\t./h2 -T -r file.hex  # Run simulator\n\nBoth modes of operation can be augmented with a symbols file, which lists where\nvariables, labels and functions are located with the assembled core.\n\nWhen the \"-T\" option is given debug mode will be entered before the simulation\nis executed. A prompt should appear and the command line should look like this:\n\n\t$ ./h2 -T -R h2.fth\n\tDebugger running, type 'h' for a list of command\n\tdebug\u003e\n\nBreak points can be set either symbolically or by program location, the 'b'\ncommand is used to set breakpoints:\n\nNumbers can be entered in octal (prefix the number with '0'), hexadecimal\n(prefix with '0x') or in decimal. As an example, the following three debug\ncommands all set a breakpoint at the same location:\n\n\tdebug\u003e b 16\n\tdebug\u003e b 0x10\n\tdebug\u003e b 020\n\n'k' can be used to list the current break points that are set:\n\n\tdebug\u003e k\n\t\t0x0010\n\nThis sets a breakpoint when the function \"key?\" is called:\n\n\tdebug\u003e b key?\n\nFunctions and labels can both be halted on, this requires either a\nsymbols file to be specified on the command line or assemble and run\nto be used on a source file, not a hex file. Symbol files can be used\non source or on hex files.\n\nTo single step the 's' command can be given, although not much will happen if\ntracing is turned off (tracing is off by default). Tracing can be toggled on or\noff with the 't' command:\n\n\tdebug\u003e s\n\tdebug\u003e s\n\tdebug\u003e t\n\ttrace on\n\tdebug\u003e s\n\t0001: pc(089a) inst(4889) sp(0) rp(0) tos(0000) r(0000) call 889 init\n\tdebug\u003e s\n\t0002: pc(0889) inst(807a) sp(0) rp(1) tos(0000) r(089b) 7a\n\tdebug\u003e s\n\t0003: pc(088a) inst(e004) sp(1) rp(1) tos(007a) r(089b) 6004\n\nIt is advisable to turn tracing off when running issuing the 'c', or continue,\ncommand.\n\nThe '.' command can be used to display the H2 cores internal state:\n\n\tdebug\u003e .\n\tReturn Stack:\n\t0000: 0000 08aa 0883 017b 0000 031b 0000 ffb0 0000 02eb ffb5 0210 0167 0167\n\t0167 0167\n\t0010: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000\n\t0000 0000\n\n\tVariable Stack:\n\ttos:  0000\n\t0001: 0000 0000 0000 0001 0004 0005 0000 ffb0 0000 0000 0000 0000 0000 0000\n\t0000 0000\n\t0011: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000\n\t0000 0000\n\n\tpc:   0538\n\trp:   0001\n\tdp:   0000\n\tie:   false\n\nAnd the 'p' command can be used to display the state of the simulated\nperipherals:\n\n\tdebug\u003e p\n\tLEDS:          00\n\tVGA Cursor:    0005\n\tVGA Control:   007a\n\tTimer Control: 8032\n\tTimer:         001b\n\tIRC Mask:      0000\n\tUART Input:    6c\n\tLED 7seg:      0005\n\tSwitches:      00\n\tLFSR:          40ba\n\tWaiting:       false\n\nFor a complete list of commands, use the 'h' command.\n\nOther ways to enter debug mode include putting the \".break\" assembler directive\ninto the source code (this only works if the assemble and run command is used\non source files, not on hex files), and hitting the escape character when the\nsimulator is trying to read data via the simulated UART or PS/2 keyboard (the\nescape will still be passed onto the simulator, but it also activates debug\nmode).\n\n## Graphical simulator\n\nA separate program can be compiled, tested under [Linux][] and [Windows][].\nThis simulates the [Nexys3][] board peripherals that the SoC interfaces with,\nbut provides a graphical environment, unlike the command line utility. It is easier\nto interact with the device and see what it is doing, but the debugging sessions\nare a less controlled. It requires [free glut][].\n\n* VGA shown on screen.\n* UART or PS/2 input (selectable by pressing F11) comes from typing in the screen,\nand in the case of the UART this is buffered with a FIFO.\n* UART output gets written to a display box.\n* There are four 7-Segment displays as on the original board.\n* The switches and push buttons can take their input from either keyboard keys\nor from mouse clicks.\n* The LED indicators above the switches can be lit up.\n\nBelow is an image of a running session in the GUI simulator:\n\n![H2 GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-gui.png \"Running GUI H2 SoC Simulator\")\n\nBuilding can be done with\n\n\tmake gui\n\nAnd running:\n\n\tmake gui-run\n\nOr:\n\n\t./gui   h2.hex (on Linux)\n\tgui.exe h2.hex (on Windows)\n\nThe [Linux][] build should work when the development package for [free glut][]\nis installed on your system, the [Windows][] build may require changes to the\nbuild system and/or manual installation of the compiler, libraries and headers.\n\nThe current key map is:\n\n\tUp         Activate Up D-Pad Button, Release turns off\n\tDown       Activate Down D-Pad Button, Release turns off\n\tLeft       Activate Left D-Pad Button, Release turns off\n\tRight      Activate Right D-Pad Button, Release turns off\n\tF1 - F8    Toggle Switch On/Off, F1 is left most, F8 Right Most\n\tF11        Toggle UART/PS2 Keyboard Input\n\tF12        Toggle Debugging Information\n\tEscape     Quit simulator\n\nAll other keyboard keys are redirected to the UART or PS/2 Keyboard input.\n\nThe Switches and D-Pad buttons can be clicked on to turn them on, the switches\nturn on with left clicks and off with right clicks. The D-Pads buttons turn on\nwith a click on top of them and turn off with a key release anywhere on the\nscreen.\n\n# VHDL Components\n\nThe VHDL components used in this system are designed to be reusable and\nportable across different toolchains and vendors. Hardware components, like block\nRAM, are inferred and not explicitly instantiated. The components are also made\nto be as generic as possible, with most having selectable widths. This would be\ntaken to the extreme, but unfortunately many vendors still do not support the\nVHDL-2008 standard.\n\n| File     | License    | Author          | Description                         |\n| -------- | ---------- | --------------- | ----------------------------------- |\n| util.vhd | MIT        | Richard J Howe  | A collection of generic components  |\n| h2.vhd   | MIT        | Richard J Howe  | H2 Forth CPU Core                   |\n| uart.vhd | MIT        | Richard J Howe  | UART TX/RX (Run time customizable)  |\n| vga.vhd  | LGPL 3.0   | Javier V García | Text Mode VGA 80x40 Display         |\n|          |            | Richard J Howe  | (and VT100 terminal emulator)       |\n| kbd.vhd  | ???        | Scott Larson    | PS/2 Keyboard                       |\n\n\n# eForth on the H2\n\nThe pseudo Forth like language used as an assembler is described above, the\napplication that actually runs on the Forth core is in itself a Forth\ninterpreter. This section describes the Forth interpreter that runs on H2 Core,\nit is contained within [embed.fth][].\n\nTODO:\n* Describe the Forth environment running on the H2 CPU.\n\n# Coding standards\n\nThere are several languages used throughout this project, all of which are\nradically different from each other and require their own set of coding\nstandards and style guides.\n\n## VHDL\n\nCommon signal names:\n\n\tclk       - The system clock\n\trst       - A reset signal for the module\n\twe        - Write Enable\n\tre        - Read  Enable\n\tdi        - Data  In\n\tdin       - Data  In\n\tdo        - Data  Out\n\tdout      - Data  Out\n\tcontrol   - Generally an input to a register, the documentation\n\t            for the module will need to be consulted to find out\n\t            what each bit means\n\tsignal_we - The write enable for 'signal'\n\tsignal_i  - This is an input signal\n\tsignal_o  - This is an output signal\n\nGenerally the use of the \"\\_i\" and \"\\_o\" suffixes are not used, modules are\nkept short and names chosen so their meaning is obvious. This rule might be\nrevisited once the project grows.\n\nComponents should:\n\n* Be as generic as possible\n* Use an asynchronous reset\n* If a feature of a module can be made optional, by either ignoring outputs\nor setting inputs to sensible values, it should be.\n* Where possible use a function, it is easy enough to turn a generic\ncomponent into a module that can be synthesized but not the other way around.\n* Use \"downto\" not \"to\" when specify variable ranges.\n* Use assertions throughout the code with the correct severity level ('failure'\nfor when something has seriously gone wrong or 'error' for debugging purposes)\n* Constrain types and generic parameters if possible, as an example, if a generic\nvalue should never be zero, use \"positive\" not \"natural\".\n* Try not to specify constants with fixed lengths where an expression using\n\"others\" can be used instead, for example:\n\n\u003c!-- --\u003e\n\n\tconstant N: positive := 4;\n\tsignal a: std_logic_vector(N - 1 downto 0) := (others =\u003e '1');\n\n\n\nInstead of:\n\n\n\tsignal a: std_logic_vector(3 downto 0) := x\"F\";\n\n\n\nThe style rules are as follows:\n\n* All words, including keywords, are to be in lower case. An underscore\nwill separate words in names.\n* Tabs are to be used to indent text, a tab spacing of 8 has been used when\nmaking the VHDL code\n* Do not repeat the name of a entity, component, function or architecture,\nthere is little point of repeating this, it just means when a unit has to be\nrenamed it has to be done in two places instead of one.\n* The \":\" in definitions of signals belongs next to the signal name, not\nsome arbitrary amount of spaces after it.\n* Group related signals.\n* Try to line up rows of signals\n* Trigger logic on the rising edge, and use the \"rising\\_edge\" function not\n\"clk'event and clk ='1'\"\n* By and large, each warning produced by the synthesis tool should be\njustified, and there should be very few warnings in the entire project if any.\n* Do not use inferred latches.\n* Load data from a file instead of generating VHDL files that contain the data,\nsynthesis tools can handle impure VHDL functions that can read the initial data\n(for a ROM or block RAM as an example) from textual files.\n\n\u003c!-- --\u003e\n\nAn example of the formatting guidelines, this describes a simple arbitrary\nwidth register:\n\n\t-- Lots of comments about what the unit does should go\n\t-- here. Describe the waveforms, states and use ASCII\n\t-- art where possible.\n\tlibrary ieee, work;\n\tuse ieee.std_logic_1164.all;\n\tuse ieee.numeric_std.all;    -- numeric_std not std_logic_arith\n\n\tentity reg is -- generic and port indented one tab, their parameters two\n\t\tgeneric (\n\t\t\tN: positive); -- Generic parameters make for a generic component\n\t\tport (\n\t\t\tclk: in  std_logic; -- standard signal names\n\t\t\trst: in  std_logic; --\n\t\t\twe:  in  std_logic;\n\t\t\tdi:  in  std_logic_vector(N - 1 downto 0);\n\t\t\tdo:  out std_logic_vector(N - 1 downto 0)); -- note the position of \");\n\tend entity; -- \"end entity\", not \"end reg\"\n\n\tarchitecture rtl of reg is\n\t\tsignal r_c, r_n: std_logic_vector(N - 1 downto 0) := (others =\u003e '0');\n\tbegin\n\t\tdo \u003c= r_c;\n\n\t\tprocess(rst, clk)\n\t\tbegin\n\t\t\tif rst = '1' then -- asynchronous reset\n\t\t\t\tr_c \u003c= (others =\u003e '0');\n\t\t\telsif rising_edge(clk) then -- rising edge, not \"clk'event and clk = '1'\"\n\t\t\t\tr_c \u003c= r_n;\n\t\t\tend if;\n\t\tend process;\n\n\t\tprocess(r_c, di, we)\n\t\tbegin\n\t\t\tr_n \u003c= r_c;\n\t\t\tif we = '1' then\n\t\t\t\tr_n \u003c= di;\n\t\t\tend if;\n\t\tend process;\n\tend; -- \"end\" or \"end architecture\"\n\n\n## C\n\nThere is quite a lot of [C][] code used within this project, used to make a\ntool chain for the H2 core and to simulate the system.\n\n* Usage of assertions for any pre or post condition, or invariant, are encouraged.\n* Tabs are to be used instead of spaces, a tab width of 8 was used when coding\n  the C, if this causes any code to go off screen then there is a problem with\n  the code and not the tab length.\n* Generally the [K\u0026R][] style is followed.\n* Line lengths should ideally be limited to 80 characters, but this is\n  definitely not an enforced limit.\n* Where there are two or more data structures that must be kept in sync, with a\n  one to one correspondence of elements, such as an enumeration and an array of\n  strings that each enumeration maps onto, an [X-Macro][] should be used to\n  keep the data in sync and to initialize the enumeration and array of strings.\n* Try to use only portable constructs and isolate the constructs that are not\n  portable.\n\n\u003c!-- --\u003e\n\nThere is nothing too surprising about the [C][] code within here, so some of\nthe exceptions should be dealt with.\n\n* Switch statements are formatted depending upon what the switch statement 'case'\nclauses look like, if they are a simple one liner such as an assignment or a\nmapping then the entire statement should occupy only a single line, for\nexample:\n\n\u003c!-- --\u003e\n\n\tstatic const char *alu_op_to_string(uint16_t instruction) {\n\t\t/* notice also that the 'case' clauses are inline with the\n\t\t * switch selector */\n\t\tswitch (ALU_OP(instruction)) {\n\t\tcase ALU_OP_T:                  return \"T\";\n\t\tcase ALU_OP_N:                  return \"N\";\n\t\tcase ALU_OP_T_PLUS_N:           return \"T+N\";\n\t\tcase ALU_OP_T_AND_N:            return \"T\u0026N\";\n\t\tcase ALU_OP_T_OR_N:             return \"T|N\";\n\t\tcase ALU_OP_T_XOR_N:            return \"T^N\";\n\t\tcase ALU_OP_T_INVERT:           return \"~T\";\n\t\tcase ALU_OP_T_EQUAL_N:          return \"N=T\";\n\t\tcase ALU_OP_N_LESS_T:           return \"T\u003eN\";\n\t\tcase ALU_OP_N_RSHIFT_T:         return \"N\u003e\u003eT\";\n\t\tcase ALU_OP_T_DECREMENT:        return \"T-1\";\n\t\tcase ALU_OP_R:                  return \"R\";\n\t\tcase ALU_OP_T_LOAD:             return \"[T]\";\n\t\tcase ALU_OP_N_LSHIFT_T:         return \"N\u003c\u003cT\";\n\t\tcase ALU_OP_DEPTH:              return \"depth\";\n\t\tcase ALU_OP_N_ULESS_T:          return \"Tu\u003eN\";\n\t\tcase ALU_OP_ENABLE_INTERRUPTS:  return \"seti\";\n\t\tcase ALU_OP_INTERRUPTS_ENABLED: return \"iset?\";\n\t\tcase ALU_OP_RDEPTH:             return \"rdepth\";\n\t\tcase ALU_OP_T_EQUAL_0:          return \"0=\";\n\t\tcase ALU_OP_CPU_ID:             return \"cpu-id\";\n\t\tdefault:                        return \"unknown\";\n\t\t}\n\t}\n\n* Unnecessary braces are avoided:\n\n\u003c!-- --\u003e\n\n\tif (foo)\n\t\tbar();\n\telse\n\t\tbaz();\n\n* \"goto\" can be used - it can be misused, but using it does not instantly make\n  code inscrutable contrary to popular belief.\n\n# To Do\n\n* Even better than using the [embed][] project directly, would be to port the\n[embed][] project so the meta-compiler runs directly on the hardware. The\nsimulator could then be used to assemble new images, making the system (much\nmore) self-hosting. Input/Output would be a problem, a possible solution is to\nuse one of the UARTs for reading the meta-compiler and meta-compiled eForth\nprogram, and writing status/error messages. A second UART could be used to\ndump the binary as a stream of hexadecimal numbers, the simulator could\nredirect the second UART output to a file.\n* Create a cut down version of the project; remove nearly everything apart from\nthe H2 Core, Block RAM and timer components. The interrupt handler could be\nsimplified as well. The UART could be handed in the H2 Core\n* The GUI simulator could be written to be built against [SDL][], and include\nproper textures for the buttons and displays, instead of the current simulator\nwhich looks like an early 90s test application for OpenGL.\n* Prepare more documentation. Specifically about the eForth interpreter that\nruns on the target and the online help stored within the non-volatile storage\non the board.\n* An IDE for resetting/uploading the image to the target board and then sending\na text buffer to it would help in developing code for the platform.\n* A [Super Optimizer][] could be made for the H2.\n* More instructions can be combined \n* It might be possible to add a conditional exit instruction. Other\ninstructions which would be useful are: Add with Carry, Bit Count, Leading\nZeroes Count, Sign Extend, Arithmetic Right Shift, Rotate Left/Right, ...\n* Add notes about picocom, and setting up the hardware:\n\n\u003c!-- --\u003e\n\n\tpicocom --omap delbs -b 115200 -e b /dev/ttyUSB1\n\n# Resources\n\n* \u003chttps://nanode0000.wordpress.com/2017/04/08/exploring-the-j1-instruction-set-and-architecture/\u003e\n* \u003chttps://www.fpgarelated.com/showarticle/790.php\u003e\n* \u003chttps://opencores.org/\u003e\n* \u003chttps://en.wikipedia.org/wiki/Peephole_optimization\u003e\n* \u003chttps://en.wikipedia.org/wiki/Superoptimization\u003e\n* \u003chttps://github.com/samawati/j1eforth\u003e\n* \u003chttps://github.com/jamesbowman/j1\u003e\n* \u003chttp://sovietov.com/app/forthwiz.html\u003e\n\n[j1eforth]: https://github.com/samawati/j1eforth\n[javascript]: https://www.javascript.com/\n[emscripten]: https://github.com/kripken/emscripten\n[DEBUG.COM]: https://en.wikipedia.org/wiki/Debug_%28command%29\n[DOS]: https://en.wikipedia.org/wiki/DOS\n[h2.c]: h2.c\n[embed.fth]: embed.fth\n[embed.c]: embed.c\n[embed.blk]: embed.blk\n[tb.vhd]: tb.vhd\n[uart.vhd]: uart.vhd\n[timer.vhd]: timer.vhd\n[top.ucf]: top.ucf\n[font.bin]: font.bin\n[text.bin]: text.bin\n[J1]: http://www.excamera.com/sphinx/fpga-j1.html\n[J1 PDF]: http://excamera.com/files/j1.pdf\n[PL/0]: https://github.com/howerj/pl0\n[libforth]: https://github.com/howerj/libforth/\n[MIT]: https://en.wikipedia.org/wiki/MIT_License\n[LGPL]: https://www.gnu.org/licenses/lgpl-3.0.en.html\n[VHDL]: https://en.wikipedia.org/wiki/VHDL\n[Verilog]: https://en.wikipedia.org/wiki/Verilog\n[UART]: https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter\n[FORTH]: https://en.wikipedia.org/wiki/Forth_%28programming_language%29\n[Nexys3]: http://store.digilentinc.com/nexys-3-spartan-6-fpga-trainer-board-limited-time-see-nexys4-ddr/\n[Make]: https://en.wikipedia.org/wiki/Make_%28software%29\n[C]: https://en.wikipedia.org/wiki/C_%28programming_language%29\n[Debian]: https://en.wikipedia.org/wiki/Debian\n[Linux]: https://en.wikipedia.org/wiki/Linux\n[GCC]: https://en.wikipedia.org/wiki/GNU_Compiler_Collection\n[Xilinx ISE]: https://www.xilinx.com/products/design-tools/ise-design-suite.html\n[Xilinx]: https://www.xilinx.com\n[GHDL]: http://ghdl.free.fr/\n[GTKWave]: http://gtkwave.sourceforge.net/\n[C99]: https://en.wikipedia.org/wiki/C99\n[tcl]: https://en.wikipedia.org/wiki/Tcl\n[Wishbone interface]: https://en.wikipedia.org/wiki/Wishbone_%28computer_bus%29\n[D-Pad]: https://en.wikipedia.org/wiki/D-pad\n[FIFO]: https://en.wikipedia.org/wiki/FIFO_%28computing_and_electronics%29\n[VGA]: https://en.wikipedia.org/wiki/Video_Graphics_Array\n[PS/2]: https://en.wikipedia.org/wiki/PS/2_port\n[LED]: https://en.wikipedia.org/wiki/Light-emitting_diode\n[7 Segment LED Display]: https://en.wikipedia.org/wiki/Seven-segment_display\n[ISO 8859-1 (Latin-1)]: https://cs.stanford.edu/people/miles/iso8859.html\n[Spartan 6]: https://www.xilinx.com/products/silicon-devices/fpga/spartan-6.html\n[FPGA]: https://en.wikipedia.org/wiki/Field-programmable_gate_array\n[ASCII]: https://en.wikipedia.org/wiki/ASCII\n[free glut]: http://freeglut.sourceforge.net/\n[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads\n[LFSR]: https://en.wikipedia.org/wiki/Linear-feedback_shift_register\n[freeglut]: http://freeglut.sourceforge.net/\n[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form\n[K\u0026R]: https://en.wikipedia.org/wiki/Indent_style#K.26R\n[X-Macro]: https://en.wikipedia.org/wiki/X_Macro\n[Windows]: https://en.wikipedia.org/wiki/Windows_7\n[pandoc]: https://pandoc.org\n[picocom]: https://github.com/npat-efault/picocom\n[Gforth]: https://www.gnu.org/software/gforth/\n[opencores]: https://opencores.org\n[VT100]: https://en.wikipedia.org/wiki/VT100\n[embed]: https://github.com/howerj/embed\n[SDL]: https://www.libsdl.org/\n[Apache 2.0]: https://www.apache.org/licenses/LICENSE-2.0.html\n[KOI8-R]: https://en.wikipedia.org/wiki/KOI8-R\n[Terminus]: http://terminus-font.sourceforge.net/\n[ISO-8859-15]: https://en.wikipedia.org/wiki/ISO/IEC_8859-15\n[Super Optimizer]: https://en.wikipedia.org/wiki/Superoptimization\n\u003c!--\n\nhttps://www.w3schools.com/css/css_table.asp\nhttp://adis.ca/entry/2011/pretty-code-block-in-css/\nhttps://www.w3.org/Style/Examples/007/center.en.html\nhttps://css-tricks.com/centering-css-complete-guide/\n--\u003e\n\u003c!-- \n\n![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.svg) \n--\u003e\n\u003cstyle type=\"text/css\"\u003ebody{margin:40px auto;max-width:850px;line-height:1.6;font-size:16px;color:#444;padding:0 10px}h1,h2,h3{line-height:1.2}table {width: 100%; border-collapse: collapse;}table, th, td{border: 1px solid black;}code { color: #091992; } \u003c/style\u003e\n","funding_links":["https://github.com/sponsors/howerj"],"categories":["VHDL"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhowerj%2Fforth-cpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhowerj%2Fforth-cpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhowerj%2Fforth-cpu/lists"}