OpenCores
URL https://opencores.org/ocsvn/forth-cpu/forth-cpu/trunk

Subversion Repositories forth-cpu

[/] [forth-cpu/] [trunk/] [readme.md] - Diff between revs 3 and 5

Only display areas with differences | Details | Blame | View Log

Rev 3 Rev 5
# Forth computing system
# Forth computing system
| Project   | Forth SoC written in VHDL |
| Project   | Forth SoC written in VHDL |
| --------- | ------------------------- |
| --------- | ------------------------- |
| Author    | Richard James Howe        |
| Author    | Richard James Howe        |
| Copyright | 2013-2017 Richard Howe    |
| Copyright | 2013-2019 Richard Howe    |
| License   | MIT/LGPL                  |
| License   | MIT/LGPL                  |
| Email     | howe.r.j.89@gmail.com     |
| Email     | howe.r.j.89@gmail.com     |
![H2 build status](https://travis-ci.org/howerj/forth-cpu.svg?branch=master "Build status of the H2 Assembler")
![H2 build status](https://travis-ci.org/howerj/forth-cpu.svg?branch=master "Build status of the H2 Assembler")
# Introduction
# Introduction
This project implements a small stack computer tailored to executing Forth
This project implements a small stack computer tailored to executing Forth
based on the [J1][] CPU. The processor has been rewritten in [VHDL][] from
based on the [J1][] CPU. The processor has been rewritten in [VHDL][] from
[Verilog][], and extended slightly.
[Verilog][], and extended slightly.
The goals of the project are as follows:
The goals of the project are as follows:
* Create a working version of [J1][] processor (called the H2).
* Create a working version of [J1][] processor (called the H2).
* Make a working toolchain for the processor.
* Make a working toolchain for the processor.
* Create a [FORTH][] for the processor which can take its input either from a
* Create a [FORTH][] for the processor which can take its input either from a
  [UART][] or a USB keyboard and a [VGA][] adapter.
  [UART][] or a USB keyboard and a [VGA][] adapter.
 
 
 
All three of which have been completed.
 
 
The H2 processor, like the [J1][], is a stack based processor that executes an
The H2 processor, like the [J1][], is a stack based processor that executes an
instruction set especially suited for [FORTH][].
instruction set especially suited for [FORTH][].
The current target is the [Nexys3][] board, with a [Xilinx][] Spartan-6 XC6LX16-CS324
The current target is the [Nexys3][] board, with a [Xilinx][] Spartan-6 XC6LX16-CS324
[FPGA][], new boards will be targeted in the future as this board is reaching it's
[FPGA][], new boards will be targeted in the future as this board is reaching it's
end of life. The [VHDL][] is written in a generic way, with hardware components
end of life. The [VHDL][] is written in a generic way, with hardware components
being inferred instead of explicitly instantiated, this should make the code
being inferred instead of explicitly instantiated, this should make the code
fairly portable, although the interfaces to the [Nexys3][] board components are
fairly portable, although the interfaces to the [Nexys3][] board components are
specific to the peripherals on that board.
specific to the peripherals on that board.
A video of the project in action, on the hardware, can be viewed here:
A video of the project in action, on the hardware, can be viewed here:
![Nexys-3 Board](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/107.mp4)
![Nexys-3 Board](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/107.mp4)
And a lower quality version of the same video that should play automatically:
And a lower quality version of the same video that should play automatically:
![Nexys-3 Board](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/107.gif)
![Nexys-3 Board](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/107.gif)
The SoC can also be simulated with a simulator written in C, as shown below:
The SoC can also be simulated with a simulator written in C, as shown below:
![GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/sim2.gif)
![GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/sim2.gif)
The System Architecture is as follows:
The System Architecture is as follows:
 
 
![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.svg)
 
![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.png)
![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.png)
# License
# License
The licenses used by the project are mixed and are on a per file basis. For my
The licenses used by the project are mixed and are on a per file basis. For my
code I use the [MIT][] license - so feel free to use it as you wish. The other
code I use the [MIT][] license - so feel free to use it as you wish. The other
licenses used are the [LGPL][], they are confined to single modules so could be
licenses used are the [LGPL][] and the [Apache 2.0][] license, they are confined
removed if you have some aversion to [LGPL][] code.
to single modules so could be removed if you have some aversion to [LGPL][] code.
 
 
# Target Board
# Target Board
The only target board available at the moment is the [Nexys3][], this should
The only target board available at the moment is the [Nexys3][], this should
change in the future as the board is currently at it's End Of Life. The next
change in the future as the board is currently at it's End Of Life. The next
boards I am looking to support are it's successor, the Nexys 4, and the myStorm
boards I am looking to support are it's successor, the Nexys 4, and the myStorm
BlackIce (). The myStorm board uses a completely open
BlackIce (). The myStorm board uses a completely open
source toolchain for synthesis, place and route and bit file generation.
source toolchain for synthesis, place and route and bit file generation.
# Build and Running requirements
# Build and Running requirements
The build has been tested under [Debian][] [Linux][], version 8.
The build has been tested under [Debian][] [Linux][], version 8.
You will require:
You will require:
* [GCC][], or a suitable [C][] compiler capable of compiling [C99][]
* [GCC][], or a suitable [C][] compiler capable of compiling [C99][]
* [Make][]
* [Make][]
* [Xilinx ISE][] version 14.7
* [Xilinx ISE][] version 14.7
* [GHDL][]
* [GHDL][]
* [GTKWave][]
* [GTKWave][]
* [tcl][] version 8.6
* [tcl][] version 8.6
* Digilent Adept2 runtime and Digilent Adept2 utilities available at
* Digilent Adept2 runtime and Digilent Adept2 utilities available at
  
  
* [freeglut][] (for the GUI simulator only)
* [freeglut][] (for the GUI simulator only)
* [pandoc][] for building the documentation
* [pandoc][] for building the documentation
* [picocom][] (or an alternative terminal client)
* [picocom][] (or an alternative terminal client)
Hardware:
Hardware:
 
 
* VGA Monitor
* VGA Monitor, and cable (Optional)
* USB Keyboard (plugs into the Nexys3 USB to PS/2 bridge)
* USB Keyboard (Optional) (plugs into the Nexys3 USB to PS/2 bridge)
* [Nexys3][] development board
* [Nexys3][] development board (if communication via UART only is
 
desired, the VGA Monitor and USB and Keyboard are not needed).
 
* USB Cables!
 
 
[Xilinx ISE][] can (or could be) downloaded for free, but requires
[Xilinx ISE][] can (or could be) downloaded for free, but requires
registration. ISE needs to be on your path:
registration. ISE needs to be on your path:
        PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64;
        PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64;
        PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/lib/lin64;
        PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/lib/lin64;
# Building and Running
# Building and Running
To make the [C][] based toolchain:
To make the [C][] based toolchain:
 
 
        make h2
        make embed.hex
 
 
To make a bit file that can be flashed to the target board:
To make a bit file that can be flashed to the target board:
        make simulation synthesis implementation bitfile
        make simulation synthesis implementation bitfile
To upload the bitfile to the target board:
To upload the bitfile to the target board:
        make upload
        make upload
To view the wave form generated by "make simulation":
To view the wave form generated by "make simulation":
        make viewer
        make viewer
The [C][] based CLI simulator can be invoked with:
The [C][] based CLI simulator can be invoked with:
        make run
        make run
 
 
Which will assemble the H2 Forth source file [h2.fth][], and run the assembled
Which will assemble the H2 Forth source file [embed.fth][], and run the assembled
object file under the H2 simulator with the debugger activated. A graphical
object file under the H2 simulator with the debugger activated. A graphical
simulator can be run with:
simulator can be run with:
        make gui-run
        make gui-run
Which requires [freeglut][] as well as a [C][] compiler.
Which requires [freeglut][] as well as a [C][] compiler.
# Related Projects
# Related Projects
The original [J1][] project is available at:
The original [J1][] project is available at:
* 
* 
This project targets the original [J1][] core and provides a eForth
This project targets the original [J1][] core and provides a eForth
implementation (written using [Gforth][] as for meta-compilation/cross
implementation (written using [Gforth][] as for meta-compilation/cross
compilation to the [J1][] core). It also provides a simulator for the system
compilation to the [J1][] core). It also provides a simulator for the system
written in [C][].
written in [C][].
* 
* 
 
 
 
The eForth interpreter which the meta-compiler is built on can be found at:
 
 
 
* 
 
 
# Manual
# Manual
 
 
The H2 processor and associated peripherals are subject to change, so the code
The H2 processor and associated peripherals are now quite stable, however the
is the definitive source what instructions are available, the register map, and
source is always the definitive guide as to how instructions and peripherals
how the peripherals behave.
behave, as well as the register map.
 
 
There are a few modifications to the [J1][] CPU which include:
There are a few modifications to the [J1][] CPU which include:
* New instructions
* New instructions
* A CPU hold line which keeps the processor in the same state so long as it is
* A CPU hold line which keeps the processor in the same state so long as it is
high.
high.
* Interrupt Service Routines have been added.
* Interrupt Service Routines have been added.
* Larger return and data stacks
* Larger (adjustable at time of synthesis) return and data stacks
 
 
The Interrupt Service Routines (ISR) have not been throughly tested and will be
 
subject to the most change.
 
 
 
### H2 CPU
### H2 CPU
The H2 CPU behaves very similarly to the [J1][] CPU, and the [J1 PDF][] can be
The H2 CPU behaves very similarly to the [J1][] CPU, and the [J1 PDF][] can be
read in order to better understand this processor. The processor is 16-bit with
read in order to better understand this processor. The processor is 16-bit with
instructions taking a single clock cycle. Most of the primitive Forth words can
instructions taking a single clock cycle. Most of the primitive Forth words can
also be executed in a single cycle as well, one notable exception is store ("!"),
also be executed in a single cycle as well, one notable exception is store ("!"),
which is split into two instructions.
which is split into two instructions.
The CPU has the following state within it:
The CPU has the following state within it:
* A 64 deep return stack (up from 32 in the original [J1][])
* A 64 deep return stack (up from 32 in the original [J1][])
* A 65 deep variable stack (up from 33 in the original [J1][])
* A 65 deep variable stack (up from 33 in the original [J1][])
* A program counter
* A program counter
* An interrupt enable and interrupt request bit
* An interrupt enable and interrupt request bit
* An interrupt address register
* An interrupt address register
 
* Registers to delay and hold the latest IRQ and hold-line values
 
 
Loads and stores into the block RAM that holds the H2 program discard the
Loads and stores into the block RAM that holds the H2 program discard the
lowest bit, every other memory operation uses the lower bit (such as jumps
lowest bit, every other memory operation uses the lower bit (such as jumps
and loads and stores to Input/Output peripherals). This is so applications can
and loads and stores to Input/Output peripherals). This is so applications can
use the lowest bit for character operations when accessing the program RAM.
use the lowest bit for character operations when accessing the program RAM.
The instruction set is decoded in the following manner:
The instruction set is decoded in the following manner:
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
        | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        | 1 |                    LITERAL VALUE                          |
        | 1 |                    LITERAL VALUE                          |
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        | 0 | 0 | 0 |            BRANCH TARGET ADDRESS                  |
        | 0 | 0 | 0 |            BRANCH TARGET ADDRESS                  |
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        | 0 | 0 | 1 |            CONDITIONAL BRANCH TARGET ADDRESS      |
        | 0 | 0 | 1 |            CONDITIONAL BRANCH TARGET ADDRESS      |
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        | 0 | 1 | 0 |            CALL TARGET ADDRESS                    |
        | 0 | 1 | 0 |            CALL TARGET ADDRESS                    |
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        | 0 | 1 | 1 |   ALU OPERATION   |T2N|T2R|N2A|R2P| RSTACK| DSTACK|
        | 0 | 1 | 1 |   ALU OPERATION   |T2N|T2R|N2A|R2P| RSTACK| DSTACK|
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
        | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
        +---------------------------------------------------------------+
        +---------------------------------------------------------------+
        T   : Top of data stack
        T   : Top of data stack
        N   : Next on data stack
        N   : Next on data stack
        PC  : Program Counter
        PC  : Program Counter
        LITERAL VALUES : push a value onto the data stack
        LITERAL VALUES : push a value onto the data stack
        CONDITIONAL    : BRANCHS pop and test the T
        CONDITIONAL    : BRANCHS pop and test the T
        CALLS          : PC+1 onto the return stack
        CALLS          : PC+1 onto the return stack
        T2N : Move T to N
        T2N : Move T to N
        T2R : Move T to top of return stack
        T2R : Move T to top of return stack
        N2A : STORE T to memory location addressed by N
        N2A : STORE T to memory location addressed by N
        R2P : Move top of return stack to PC
        R2P : Move top of return stack to PC
        RSTACK and DSTACK are signed values (twos compliment) that are
        RSTACK and DSTACK are signed values (twos compliment) that are
        the stack delta (the amount to increment or decrement the stack
        the stack delta (the amount to increment or decrement the stack
        by for their respective stacks: return and data)
        by for their respective stacks: return and data)
#### ALU operations
#### ALU operations
All ALU operations replace T:
All ALU operations replace T:
| Value |   Operation    |     Description       |
| Value |   Operation    |     Description       |
|-------|----------------|-----------------------|
|-------|----------------|-----------------------|
|   0   |       T        |  Top of Stack         |
|   0   |       T        |  Top of Stack         |
|   1   |       N        |  Copy T to N          |
|   1   |       N        |  Copy T to N          |
|   2   |     T + N      |  Addition             |
|   2   |     T + N      |  Addition             |
|   3   |     T & N      |  Bitwise AND          |
|   3   |     T & N      |  Bitwise AND          |
|   4   |     T or N     |  Bitwise OR           |
|   4   |     T or N     |  Bitwise OR           |
|   5   |     T ^ N      |  Bitwise XOR          |
|   5   |     T ^ N      |  Bitwise XOR          |
|   6   |      ~T        |  Bitwise Inversion    |
|   6   |      ~T        |  Bitwise Inversion    |
|   7   |     T = N      |  Equality test        |
|   7   |     T = N      |  Equality test        |
|   8   |     N < T      |  Signed comparison    |
|   8   |     N < T      |  Signed comparison    |
|   9   |     N >> T     |  Logical Right Shift  |
|   9   |     N >> T     |  Logical Right Shift  |
|  10   |     T - 1      |  Decrement            |
|  10   |     T - 1      |  Decrement            |
|  11   |       R        |  Top of return stack  |
|  11   |       R        |  Top of return stack  |
|  12   |      [T]       |  Load from address    |
|  12   |      [T]       |  Load from address    |
|  13   |     N << T     |  Logical Left Shift   |
|  13   |     N << T     |  Logical Left Shift   |
|  14   |     depth      |  Depth of stack       |
|  14   |     depth      |  Depth of stack       |
|  15   |     N u< T     |  Unsigned comparison  |
|  15   |     N u< T     |  Unsigned comparison  |
|  16   | set interrupts |  Enable interrupts    |
|  16   | Set CPU State  |  Enable interrupts    |
|  17   | interrupts on? |  Are interrupts on?   |
|  17   | Get CPU State  |  Are interrupts on?   |
|  18   |     rdepth     |  Depth of return stk  |
|  18   |     rdepth     |  Depth of return stk  |
|  19   |      0=        |  T == 0?              |
|  19   |      0=        |  T == 0?              |
|  20   |     CPU ID     |  CPU Identifier       |
|  20   |     CPU ID     |  CPU Identifier       |
 
|  21   |     LITERAL    |  Internal Instruction |
 
 
### Peripherals and registers
### Peripherals and registers
Registers marked prefixed with an 'o' are output registers, those with an 'i'
Registers marked prefixed with an 'o' are output registers, those with an 'i'
prefix are input registers. Registers are divided into an input and output
prefix are input registers. Registers are divided into an input and output
section of registers and the addresses of the input and output registers do not
section of registers and the addresses of the input and output registers do not
correspond to each other in all cases. Unlike for RAM reads, the I/O registers
correspond to each other in all cases.
are indexed by word aligned addresses, without the lowest bit being discarded
 
(this should be fixed at a later date).
 
 
 
The following peripherals have been implemented in the [VHDL][] SoC to
The following peripherals have been implemented in the [VHDL][] SoC to
interface with devices on the [Nexys3][] board:
interface with devices on the [Nexys3][] board:
* [VGA][] output device, text mode only, 80 by 40 characters from
* [VGA][] output device, text mode only, 80 by 40 characters from
  
  . This has
* Timer
been heavily modified from the original, which now implements most of a
* [UART][] (Rx/Tx) with a [FIFO][]
[VT100][] terminal emulator. This has two fonts available to it:
from 
  - [Terminus][]/[KOI8-R][] (Default)
 
  - Latin [ISO-8859-15][] (Secondary Font) from
 
  
 
* [Timer][] in [timer.vhd][].
 
* [UART][] (Rx/Tx) in [uart.vhd][].
* [PS/2][] Keyboard
* [PS/2][] Keyboard
from 
from 
* [LED][] next to a bank of switches
* [LED][] next to a bank of switches
* An [8 Segment LED Display][] driver (a 7 segment display with a decimal point)
* A [7 Segment LED Display][] driver (a 7 segment display with a decimal point)
 
 
The SoC also features a limited set of interrupts that can be enabled or
The SoC also features a limited set of interrupts that can be enabled or
disabled.
disabled.
The output register map:
The output register map:
| Register    | Address | Description                     |
| Register    | Address | Description                     |
|-------------|---------|---------------------------------|
|-------------|---------|---------------------------------|
| oUart       | 0x4000  | UART register                   |
| oUart       | 0x4000  | UART register                   |
| oVT100      | 0x4002  | VT100 Terminal Write            |
| oVT100      | 0x4002  | VT100 Terminal Write            |
| oLeds       | 0x4004  | LED outputs                     |
| oLeds       | 0x4004  | LED outputs                     |
| oTimerCtrl  | 0x4006  | Timer control                   |
| oTimerCtrl  | 0x4006  | Timer control                   |
| oMemDout    | 0x4008  | Memory Data Output              |
| oMemDout    | 0x4008  | Memory Data Output              |
| oMemControl | 0x400A  | Memory Control / Hi Address     |
| oMemControl | 0x400A  | Memory Control / Hi Address     |
| oMemAddrLow | 0x400C  | Memory Lo Address               |
| oMemAddrLow | 0x400C  | Memory Lo Address               |
| o7SegLED    | 0x400E  | 4 x LED 8 Segment display       |
| o7SegLED    | 0x400E  | 4 x LED 7 Segment display       |
| oIrcMask    | 0x4010  | CPU Interrupt Mask              |
| oIrcMask    | 0x4010  | CPU Interrupt Mask              |
 
| oUartBaudTx | 0x4012  | UART Tx Baud Clock Setting      |
 
| oUartBaudRx | 0x4014  | UART Rx Baud Clock Setting      |
 
 
The input registers:
The input registers:
| Register    | Address | Description                     |
| Register    | Address | Description                     |
|-------------|---------|---------------------------------|
|-------------|---------|---------------------------------|
| iUart       | 0x4000  | UART register                   |
| iUart       | 0x4000  | UART register                   |
| iVT100      | 0x4002  | Terminal status & PS/2 Keyboard |
| iVT100      | 0x4002  | Terminal status & PS/2 Keyboard |
| iSwitches   | 0x4004  | Buttons and switches            |
| iSwitches   | 0x4004  | Buttons and switches            |
| iTimerDin   | 0x4006  | Current Timer Value             |
| iTimerDin   | 0x4006  | Current Timer Value             |
| iMemDin     | 0x4008  | Memory Data Input               |
| iMemDin     | 0x4008  | Memory Data Input               |
The following description of the registers should be read in order and describe
The following description of the registers should be read in order and describe
how the peripherals work as well.
how the peripherals work as well.
#### oUart
#### oUart
A UART with a fixed baud rate and format (115200, 8 bits, 1 stop bit) is
A UART with a fixed baud rate and format (115200, 8 bits, 1 stop bit) is
present on the SoC. The UART has a FIFO of depth 8 on both the RX and TX
present on the SoC. The UART has a FIFO of depth 8 on both the RX and TX
channels. The control of the UART is split across oUart and iUart.
channels. The control of the UART is split across oUart and iUart.
To write a value to the UART assert TXWE along with putting the data in TXDO.
To write a value to the UART assert TXWE along with putting the data in TXDO.
The FIFO state can be analyzed by looking at the iUart register.
The FIFO state can be analyzed by looking at the iUart register.
To read a value from the UART: iUart can be checked to see if data is present
To read a value from the UART: iUart can be checked to see if data is present
in the FIFO, if it is assert RXRE in the oUart register, on the next clock
in the FIFO, if it is assert RXRE in the oUart register, on the next clock
cycle the data will be present in the iUart register.
cycle the data will be present in the iUart register.
The baud rate of the UART can be changed by rebuilding the VHDL project, bit
The baud rate of the UART can be changed by rebuilding the VHDL project, bit
length, parity bits and stop bits can only be changed with modifications to
length, parity bits and stop bits can only be changed with modifications to
[uart.vhd][]
[uart.vhd][]
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |
        |  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        TXWE: UART TX Write Enable
        TXWE: UART TX Write Enable
        RXRE: UART RX Read Enable
        RXRE: UART RX Read Enable
        TXDO: UART TX Data Output
        TXDO: UART TX Data Output
#### oVT100
#### oVT100
The VGA Text device emulates a terminal which the user can talk to by writing
The VGA Text device emulates a terminal which the user can talk to by writing
to the oVT100 register. It supports a subset of the [VT100][] terminal
to the oVT100 register. It supports a subset of the [VT100][] terminal
functionality. The interface behaves much like writing to a UART with the same
functionality. The interface behaves much like writing to a UART with the same
busy and control signals. The input is taken from a [PS/2][] keyboard available
busy and control signals. The input is taken from a [PS/2][] keyboard available
on the board, this behaves like the RX mechanism of the UART.
on the board, this behaves like the RX mechanism of the UART.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |
        |  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        TXWE: VT100 TX Write Enable
        TXWE: VT100 TX Write Enable
        RXRE: UART RX Read Enable
        RXRE: UART RX Read Enable
        TXDO: UART TX Data Output
        TXDO: UART TX Data Output
#### oLeds
#### oLeds
On the [Nexys3][] board there is a bank of LEDs that are situated next to the
On the [Nexys3][] board there is a bank of LEDs that are situated next to the
switches, these LEDs can be turned on (1) or off (0) by writing to LEDO. Each
switches, these LEDs can be turned on (1) or off (0) by writing to LEDO. Each
LED here corresponds to the switch it is next to.
LED here corresponds to the switch it is next to.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |  X |  X |  X |  X |  X |  X |              LEDO                     |
        |  X |  X |  X |  X |  X |  X |  X |  X |              LEDO                     |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        LEDO: LED Output
        LEDO: LED Output
#### oTimerCtrl
#### oTimerCtrl
The timer is controllable by the oTimerCtrl register, it is a 13-bit timer
The timer is controllable by the oTimerCtrl register, it is a 13-bit timer
running at 100MHz, it can optionally generate interrupts and the current timers
running at 100MHz, it can optionally generate interrupts and the current timers
internal count can be read back in with the iTimerDin register.
internal count can be read back in with the iTimerDin register.
The timer counts once the TE bit is asserted, once the timer reaches TCMP value
The timer counts once the TE bit is asserted, once the timer reaches TCMP value
it wraps around and can optionally generate an interrupt by asserting INTE.
it wraps around and can optionally generate an interrupt by asserting INTE.
This also toggles the Q and NQ lines that come out of the timer and are routed
This also toggles the Q and NQ lines that come out of the timer and are routed
to pins on the board (see the constraints file [top.ucf][] for the pins).
to pins on the board (see the constraints file [top.ucf][] for the pins).
The timer can be reset by writing to RST.
The timer can be reset by writing to RST.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | TE | RST|INTE|                      TCMP                                      |
        | TE | RST|INTE|                      TCMP                                      |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        TE:   Timer Enable
        TE:   Timer Enable
        RST:  Timer Reset
        RST:  Timer Reset
        INTE: Interrupt Enable
        INTE: Interrupt Enable
        TCMP: Timer Compare Value
        TCMP: Timer Compare Value
#### oIrcMask
#### oIrcMask
The H2 core has a mechanism for interrupts, interrupts have to be enabled or
The H2 core has a mechanism for interrupts, interrupts have to be enabled or
disabled with an instruction. Each interrupt can be masked off with a bit in
disabled with an instruction. Each interrupt can be masked off with a bit in
IMSK to enable that specific interrupt. A '1' in a bit of IMSK enables that
IMSK to enable that specific interrupt. A '1' in a bit of IMSK enables that
specific interrupt, which will be delivered to the CPU if interrupts are
specific interrupt, which will be delivered to the CPU if interrupts are
enabled within it.
enabled within it.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |  X |  X |  X |  X |  X |  X |                 IMSK                  |
        |  X |  X |  X |  X |  X |  X |  X |  X |                 IMSK                  |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        IMSK: Interrupt Mask
        IMSK: Interrupt Mask
 
 
 
#### oUartBaudTx
 
 
 
This register is used to set the baud and sample clock frequency for
 
transmission only.
 
 
 
        +-------------------------------------------------------------------------------+
 
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
 
        +-------------------------------------------------------------------------------+
 
        |                                    BTXC                                       |
 
        +-------------------------------------------------------------------------------+
 
 
 
        BTXC: Baud Clock Settings
 
 
 
#### oUartBaudRx
 
 
 
This register is used to set the baud and sample clock frequency for
 
reception only.
 
 
 
        +-------------------------------------------------------------------------------+
 
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
 
        +-------------------------------------------------------------------------------+
 
        |                                    BRXC                                       |
 
        +-------------------------------------------------------------------------------+
 
 
 
        BRXC: Baud Clock Settings
 
 
 
 
#### oMemDout
#### oMemDout
Data to be output to selected address when write enable (WE) issued in
Data to be output to selected address when write enable (WE) issued in
oMemControl.
oMemControl.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |                           Data Ouput                                          |
        |                           Data Ouput                                          |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
#### oMemControl
#### oMemControl
This register contains the control registers for the onboard memory on the
This register contains the control registers for the onboard memory on the
[Nexys3][] board. The board contains three memory devices, two non-volatile
[Nexys3][] board. The board contains three memory devices, two non-volatile
memory devices and a volatile RAM based device. The two devices accessible by a
memory devices and a volatile RAM based device. The two devices accessible by a
simple SRAM interface (one volatile M45W8MW16, one non-volatile - a
simple SRAM interface (one volatile M45W8MW16, one non-volatile - a
NP8P128A13T1760E) are both accessible, the third is an SPI based memory device,
NP8P128A13T1760E) are both accessible, the third is an SPI based memory device,
NP5Q128A13ESFC0E) and is currently not accessible.
NP5Q128A13ESFC0E) and is currently not accessible.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | OE | WE | RST|WAIT| RCS| FCS|                 Address Hi                      |
        | OE | WE | RST|WAIT| RCS| FCS|                 Address Hi                      |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        OE:  Output Enable - enable reading from current address into iMemDin
        OE:  Output Enable - enable reading from current address into iMemDin
        WE:  Write Enable  - enable writing oMemDout into ram at current address
        WE:  Write Enable  - enable writing oMemDout into ram at current address
        RST: Reset the Flash memory controller
        RST: Reset the Flash memory controller
        RCS: RAM Chip Select, Enable Volatile Memory
        RCS: RAM Chip Select, Enable Volatile Memory
        FCS: Flash Chip Select, Enable Non-Volatile Memory
        FCS: Flash Chip Select, Enable Non-Volatile Memory
        Address Hi: High Bits of RAM address
        Address Hi: High Bits of RAM address
OE and WE are mutually exclusive, if both are set then there is no effect.
OE and WE are mutually exclusive, if both are set then there is no effect.
The memory controller is in active development, and the interface to it might
The memory controller is in active development, and the interface to it might
change.
change.
#### oMemAddrLow
#### oMemAddrLow
This is the lower address bits of the RAM.
This is the lower address bits of the RAM.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |                           Address Lo                                          |
        |                           Address Lo                                          |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
#### o7SegLED
#### o7SegLED
 
 
On the [Nexys3][] board there is a bank of 7 segment displays, with a dot
On the [Nexys3][] board there is a bank of 7 segment displays, with a decimal
(8-segment really), which can be used for numeric output. The LED segments
point (8-segment really), which can be used for numeric output. The LED segments
cannot be directly addressed. Instead the value stored in L8SD is mapped
cannot be directly addressed. Instead the value stored in L8SD is mapped
to a hexadecimal display value (or a BCD value, but this requires regeneration
to a hexadecimal display value (or a BCD value, but this requires regeneration
of the SoC and modification of a generic in the VHDL).
of the SoC and modification of a generic in the VHDL).
The value '0' corresponds to a zero displayed on the LED segment, '15' to an
The value '0' corresponds to a zero displayed on the LED segment, '15' to an
'F', etcetera.
'F', etcetera.
There are 4 displays in a row.
There are 4 displays in a row.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |      L7SD0        |       L7SD1       |       L7SD2       |       L7SD3       |
        |      L7SD0        |       L7SD1       |       L7SD2       |       L7SD3       |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        L7SD0: LED 7 Segment Display (leftmost display)
        L7SD0: LED 7 Segment Display (leftmost display)
        L7SD1: LED 7 Segment Display
        L7SD1: LED 7 Segment Display
        L7SD2: LED 7 Segment Display
        L7SD2: LED 7 Segment Display
        L7SD3: LED 7 Segment Display (right most display)
        L7SD3: LED 7 Segment Display (right most display)
#### iUart
#### iUart
The iUart register works in conjunction with the oUart register. The status of
The iUart register works in conjunction with the oUart register. The status of
the FIFO that buffers both transmission and reception of bytes is available in
the FIFO that buffers both transmission and reception of bytes is available in
the iUart register, as well as any received bytes.
the iUart register, as well as any received bytes.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|                RXDI                   |
        |  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|                RXDI                   |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        TFFL: UART TX FIFO Full
        TFFL: UART TX FIFO Full
        TFEM: UART TX FIFO Empty
        TFEM: UART TX FIFO Empty
        RFFL: UART RX FIFO Full
        RFFL: UART RX FIFO Full
        RFEM: UART RX FIFO Empty
        RFEM: UART RX FIFO Empty
        RXDI: UART RX Data Input
        RXDI: UART RX Data Input
#### iVT100
#### iVT100
The iVT100 register works in conjunction with the oVT100 register. The status of
The iVT100 register works in conjunction with the oVT100 register. The status of
the FIFO that buffers both transmission and reception of bytes is available in
the FIFO that buffers both transmission and reception of bytes is available in
the iVT100 register, as well as any received bytes. It works the same as the
the iVT100 register, as well as any received bytes. It works the same as the
iUart/oUart registers.
iUart/oUart registers.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|  0 |           ACHR                   |
        |  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|  0 |           ACHR                   |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        TFFL: VGA VT100 TX FIFO Full
        TFFL: VGA VT100 TX FIFO Full
        TFEM: VGA VT100 TX FIFO Empty
        TFEM: VGA VT100 TX FIFO Empty
        RFFL: PS2 VT100 RX FIFO Full
        RFFL: PS2 VT100 RX FIFO Full
        RFEM: PS2 VT100 RX FIFO Empty
        RFEM: PS2 VT100 RX FIFO Empty
        ACHR: New character available on PS2 Keyboard
        ACHR: New character available on PS2 Keyboard
#### iTimerDin
#### iTimerDin
This register contains the current value of the timers counter.
This register contains the current value of the timers counter.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |  X |                       TCNT                                     |
        |  X |  X |  X |                       TCNT                                     |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        TCNT: Timer Counter Value
        TCNT: Timer Counter Value
#### iSwitches
#### iSwitches
iSwitches contains input lines from multiple sources. The buttons
iSwitches contains input lines from multiple sources. The buttons
(BUP, BDWN, BLFT, BRGH, and BCNT) correspond to a [D-Pad][] on the [Nexys3][]
(BUP, BDWN, BLFT, BRGH, and BCNT) correspond to a [D-Pad][] on the [Nexys3][]
board. The switches (TSWI) are the ones mentioned in oLeds, each have an LED
board. The switches (TSWI) are the ones mentioned in oLeds, each have an LED
next to them.
next to them.
The switches and the buttons are already debounced in hardware so they do not
The switches and the buttons are already debounced in hardware so they do not
have to be further processed once read in from these registers.
have to be further processed once read in from these registers.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |  X |  X |  X | BUP|BDWN|BLFT|BRGH|BCNT|               TSWI                    |
        |  X |  X |  X | BUP|BDWN|BLFT|BRGH|BCNT|               TSWI                    |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        BUP:  Button Up
        BUP:  Button Up
        BDWN: Button Down
        BDWN: Button Down
        BLFT: Button Left
        BLFT: Button Left
        BRGH: Button Right
        BRGH: Button Right
        BCNT: Button Center
        BCNT: Button Center
        TSWI: Two Position Switches
        TSWI: Two Position Switches
#### iMemDin
#### iMemDin
Memory input, either from the SRAM or Flash, indexed by oMemControl and
Memory input, either from the SRAM or Flash, indexed by oMemControl and
oMemAddrLow. When reading from flash this might actually be status information
oMemAddrLow. When reading from flash this might actually be status information
or information from the query table.
or information from the query table.
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
        |                           Data Input                                          |
        |                           Data Input                                          |
        +-------------------------------------------------------------------------------+
        +-------------------------------------------------------------------------------+
### Interrupt Service Routines
### Interrupt Service Routines
The following interrupt service routines are defined:
The following interrupt service routines are defined:
|       Name        | Number |         Description           |
|       Name        | Number |         Description           |
|-------------------|--------|-------------------------------|
|-------------------|--------|-------------------------------|
| isrNone           |   0    | Not used                      |
| isrNone           |   0    | Not used                      |
| isrRxFifoNotEmpty |   1    | UART RX FIFO Is Not Empty     |
| isrRxFifoNotEmpty |   1    | UART RX FIFO Is Not Empty     |
| isrRxFifoFull     |   2    | UART RX FIFI Is Full          |
| isrRxFifoFull     |   2    | UART RX FIFI Is Full          |
| isrTxFifoNotEmpty |   3    | UART TX FIFO Is Not Empty     |
| isrTxFifoNotEmpty |   3    | UART TX FIFO Is Not Empty     |
| isrTxFifoFull     |   4    | UART TX FIFO Is Full          |
| isrTxFifoFull     |   4    | UART TX FIFO Is Full          |
| isrKbdNew         |   5    | New PS/2 Keyboard Character   |
| isrKbdNew         |   5    | New PS/2 Keyboard Character   |
| isrTimer          |   6    | Timer Counter                 |
| isrTimer          |   6    | Timer Counter                 |
| isrDPadButton     |   7    | Any D-Pad Button Change State |
| isrDPadButton     |   7    | Any D-Pad Button Change State |
When an interrupt occurs, and interrupts are enabled within the processor, then
When an interrupt occurs, and interrupts are enabled within the processor, then
a call to the location in memory is performed - the location is the same as the
a call to the location in memory is performed - the location is the same as the
ISR number. An ISR with a number of '4' will perform a call (not a jump) to the
ISR number. An ISR with a number of '4' will perform a call (not a jump) to the
location '4' within memory, for example.
location '4' within memory, for example.
Interrupts have a latency of at least 4-5 cycles before they are acted on, there
Interrupts have a latency of at least 4-5 cycles before they are acted on, there
is a two to three cycle delay in the interrupt request handler, then the call
is a two to three cycle delay in the interrupt request handler, then the call
to the ISR location in memory has to be done, then the call to the word that
to the ISR location in memory has to be done, then the call to the word that
implements the ISR itself.
implements the ISR itself.
If two interrupts occur at the same time they are processed from the lowest
If two interrupts occur at the same time they are processed from the lowest
interrupt number to the highest.
interrupt number to the highest.
Interrupts are lost when an interrupt with the same number occurs that has not
Interrupts are lost when an interrupt with the same number occurs that has not
been processed.
been processed.
# The Toolchain
# The Toolchain
 
 
The Assembler, Disassembler and [C][] based simulator for the H2 is in a single
The Disassembler and [C][] based simulator for the H2 is in a single
program (see [h2.c][]). This simulator complements the [VHDL][] test bench
program (see [h2.c][]). This simulator complements the [VHDL][] test bench
[tb.vhd][] and is not a replacement for it.
[tb.vhd][] and is not a replacement for it. The meta-compiler runs on top of an
 
eForth interpreter and it contained within the files [embed.c][] and
 
[embed.blk][]. The meta-compiler (Forth parlance for a cross-compiler) is a
 
Forth program which is used to create the eForth image that runs on the target.
 
 
 
The toolchain is currently in flux, going forward there is liable to more
 
integration between [h2.c][] and [embed.c][], along with changing the Embed
 
Virtual Machine into one that more closely resembles the H2 CPU with the long
 
term goal of creating a self hosting system.
 
 
To build it a [C][] compiler is needed, the build target "h2" will build the
To build both, a [C][] compiler is needed, the build target "h2" will build the
executable:
executable, h2, and "embed" will build the meta-compiler:
 
 
        make h2
        make h2 embed
 
 
And it can be run on the source file [h2.fth][] with the make target:
And it can be run on the source file [embed.fth][] with the make target:
 
 
        make run
        make run
The make file is not needed:
The make file is not needed:
        Linux:
        Linux:
        cc -std=c99 h2.c -o h2  # To build the h2 executable
        cc -std=c99 h2.c -o h2  # To build the h2 executable
 
        cc -std=c99 embed.c -o embed  # To build the embed VM executable
 
        ./embed embed.blk embed.hex embed.fth # Create the target eForth image
        ./h2 -h                 # For a list of options
        ./h2 -h                 # For a list of options
        ./h2 -T -R h2.fth       # Assemble h2.fth and run it
        ./h2 -r embed.hex           # Run the assembled file
 
 
        Windows:
        Windows:
        gcc -std=c99 h2.c -o h2.exe # Builds the h2.exe executable
        gcc -std=c99 h2.c -o h2.exe # Builds the h2.exe executable
 
        gcc -std=c99 embed.c -o embed.exe # Builds the embed.exe executable
 
        embed.exe embed.blk embed.hex embed.fth # Create the target eForth iamge
        h2.exe -h                   # For a list of options
        h2.exe -h                   # For a list of options
        h2.exe -T -R h2.fth         # Assemble h2.fth and run it
        h2.exe -r embed.hex         # Run the assembled file
 
 
A list of command line options available:
A list of command line options available:
        -       stop processing options, following arguments are files
        -       stop processing options, following arguments are files
        -h      print a help message and exit
        -h      print a help message and exit
        -v      increase logging level
        -v      increase logging level
        -d      disassemble input files (default)
        -d      disassemble input files (default)
        -D      full disassembly of input files
        -D      full disassembly of input files
        -T      Enter debug mode when running simulation
        -T      Enter debug mode when running simulation
        -a      assemble file
 
        -r      run hex file
        -r      run hex file
        -R      assemble file then run it
 
        -L #    load symbol file
        -L #    load symbol file
        -S #    save symbols to file
 
        -s #    number of steps to run simulation (0 = forever)
        -s #    number of steps to run simulation (0 = forever)
        -n #    specify NVRAM block file (default is nvram.blk)
        -n #    specify NVRAM block file (default is nvram.blk)
        file*   file to process
        file*   file to process
This program is released under the [MIT][] license, feel free to use it and
This program is released under the [MIT][] license, feel free to use it and
modify it as you please. With minimal modification it should be able to
modify it as you please. With minimal modification it should be able to
assemble programs for the original [J1][] core.
assemble programs for the original [J1][] core.
 
 
## Assembler
## Meta-Compiler
 
 
The assembler is actually a compiler for a pseudo Forth like language with a
The meta-compiler runs on top of the [embed][] virtual machine, it is a 16-bit
fixed grammar. It is a much more restricted language than Forth and cannot be
virtual machine that originally descended from the H2 CPU. The project includes
extended within itself like Forth can.
a meta-compilation scheme that allows an eForth image to generate a new eForth
 
image with modifications. That system has been adapted for use with the H2,
The main program can be found in [h2.fth][], which is still currently in
which replaced the cross compiler written in C, which allowed the first image
testing.
for the H2 to be created.
 
 
The assembler/compiler reads in a text file containing a program and produces a
The meta-compiler is an ordinary Forth program, it is contained within
hex file which can be read in by the simulator, disassembler, the VHDL test
[embed.fth][]. The meta-compiler Forth program is then used to build up an
bench or read in by the [Xilinx ISE][] toolchain when it generates the bit file
eForth image capable of running on the H2 target.
for the [Spartan 6][] on the [Nexys3][] board.
 
 
For more information about meta-compilation in Forth, see:
A rough [EBNF][] grammar for the language is as follows:
 
 
* 
        Program     := Statement* EOF
* 
        Statement   :=   Label | Branch | 0Branch | Call | Literal | Instruction
* 
                       | Identifier | Constant | Variable | Location | Definition | If
 
                       | Begin | Char | Set | Pc | Pwd | Break | Mode | String | BuiltIn
 
        Label       := Identifier ";"
 
        Branch      := "branch"  ( Identifier | Literal )
 
        0Branch     := "0branch" ( Identifier | Literal )
 
        Call        := "call"    ( Identifier | Literal )
 
        Set         := ".set"    ( Identifier | Literal | String ) ( Identifier | Literal | String )
 
        Pc          := ".pc"     ( Identifier | Literal )
 
        Pwd         := ".pwd"    ( Identifier | Literal )
 
        Break       := ".break"
 
        BuiltIn     := ".built-in"
 
        Mode        := ".mode"      Literal
 
        Allocate    := ".allocate" ( Identifier | Literal )
 
        Constant    := "constant" Identifier Literal "hidden"?
 
        Variable    := "variable" Identifier ( Literal | String ) "hidden"?
 
        Location    := "Location" Identifier ( Literal | String )
 
        Instruction := "@" | "store" | "exit" | ...
 
        Definition  := ":" ( Identifier | String) Statement* ";" ( "hidden" | "immediate" | "inline")
 
        If          := "if" Statement* [ "else" ] Statement* "then"
 
        Begin       := "begin" Statement* ("until" | "again" | "while" Statement* "repeat")
 
        For         := "for"   Statement* ("aft" Statement* "then" Statement* | "next")
 
        Literal     := [ "-" ] Number
 
        String      := '"' SChar* '"'
 
        Char        := "[char]" ASCII ","
 
        Number      := Hex | Decimal
 
        Decimal     := "0" ... "9" ("0" ... "9")*
 
        Hex         := "$" HexDigit HexDigit*
 
        HexDigit    := ( "a" ... "f" | "A" ... "F" )
 
        SChar       := Any character except quote
 
 
 
Literals have higher priority than Identifiers, and comments are '\'
 
until a new line is encountered, or '(' until a ')' is encountered.
 
 
 
The grammar allows for nested word definitions, however state is held in the
 
lexer to prevent this.
 
 
 
The assembler the following directives:
 
 
 
        .pc        Set the program counter
 
        .pwd       Set the previous word pointer
 
        .allocate  Increment the program counter
 
        .set       Set location in memory
 
        .mode      Change compiler mode
 
        .built-in  Assemble built words here
 
 
 
 
 
There are several optimizations that can be performed, the ".mode" directive
 
controls whether they are active, along with controlling whether word
 
definitions are compiled with their headers or not. Optimizations performed
 
include merging a call to exit with the previous instruction if it is possible
 
to do so and performing tail call optimization where possible.
 
 
 
The built in words, with their instruction encodings:
 
 
 
 
 
| Word   | 0 | 1 | 1 |   ALU OPERATION   |T2N|T2R|N2A|R2P| RSTACK| DSTACK|
 
|--------|---|---|---|-------------------|---|---|---|---|-------|-------|
 
| dup    | 0 | 1 | 1 |       T           | X |   |   |   |       |  +1   |
 
| over   | 0 | 1 | 1 |       N           | X |   |   |   |       |  +1   |
 
| invert | 0 | 1 | 1 |       ~ T         |   |   |   |   |       |       |
 
| +      | 0 | 1 | 1 |       T + N       |   |   |   |   |       |  -1   |
 
| swap   | 0 | 1 | 1 |       N           | X |   |   |   |       |       |
 
| nip    | 0 | 1 | 1 |       T           |   |   |   |   |       |  -1   |
 
| drop   | 0 | 1 | 1 |       N           |   |   |   |   |       |  -1   |
 
| exit   | 0 | 1 | 1 |       T           |   |   |   | X |   -1  |       |
 
| >r  | 0 | 1 | 1 |       N           |   | X |   |   |   +1  |  -1   |
 
| r>  | 0 | 1 | 1 |       R           | X |   |   |   |   -1  |  +1   |
 
| r@     | 0 | 1 | 1 |       R           | X |   |   |   |       |  +1   |
 
| @      | 0 | 1 | 1 |       [T]         |   |   |   |   |       |       |
 
| store  | 0 | 1 | 1 |       N           |   |   | X |   |       |  -1   |
 
| rshift | 0 | 1 | 1 |       N >> T      |   |   |   |   |       |  -1   |
 
| lshift | 0 | 1 | 1 |       N << T      |   |   |   |   |       |  -1   |
 
| =      | 0 | 1 | 1 |       N = T       |   |   |   |   |       |  -1   |
 
| u<     | 0 | 1 | 1 |       N u< T      |   |   |   |   |       |  -1   |
 
| <      | 0 | 1 | 1 |       N < T       |   |   |   |   |       |  -1   |
 
| and    | 0 | 1 | 1 |       T & N       |   |   |   |   |       |  -1   |
 
| xor    | 0 | 1 | 1 |       T ^ N       |   |   |   |   |       |  -1   |
 
| or     | 0 | 1 | 1 |       T or N      |   |   |   |   |       |  -1   |
 
| depth  | 0 | 1 | 1 |       depth       |   |   |   |   |       |  +1   |
 
| 1-     | 0 | 1 | 1 |       T - 1       |   |   |   |   |       |       |
 
| seti   | 0 | 1 | 1 |   set interrupts  |   |   |   |   |       |  -1   |
 
| iset?  | 0 | 1 | 1 |   interrupts on?  |   |   |   |   |       |  +1   |
 
| rdepth | 0 | 1 | 1 |      rdepth       |   |   |   |   |       |  +1   |
 
| 0=     | 0 | 1 | 1 |        0=         |   |   |   |   |       |       |
 
| up1    | 0 | 1 | 1 |        T          |   |   |   |   |       |  +1   |
 
| nop    | 0 | 1 | 1 |        T          |   |   |   |   |       |       |
 
| cpu-id | 0 | 1 | 1 |      CPU ID       |   |   |   |   |       |  +1   |
 
| rdrop  | 0 | 1 | 1 |        T          |   |   |   |   |  -1   |       |
 
 
 
 
 
The language used in the assembler is Forth like, the best example of how to
 
use it is in the file "h2.fth", which contains a working Forth interpreter and
 
many Forth definitions. New words can be defined in the usual manner:
 
 
 
        : 2+ 2 + ;
 
        : ?dup dup if dup then ;
 
 
 
Control structure mismatches cause the parser to terminate with an error
 
condition as they are handled with a parser, each ":" must have a corresponding
 
";", an "if" must have either an "else" and then "then", or just "then",
 
etcetera.
 
 
 
Variables and constants can also be defined, but the grammar is slightly
 
different to how it works in a normal Forth:
 
 
 
        variable x 55
 
        constant y 20
 
 
 
Constants take up no space unless they are used, whereas variables are
 
allocated a location and set to an initial value. The above example creates a
 
variable 'x' and sets the variable to '55'. It also adds a constant 'y' to the
 
current symbol table, which can be used in other function definitions.
 
 
 
Code that does not appear within a word definition is assembled at that
 
location.
 
 
 
The following control structures are available:
 
 
 
        T = value to consume off the top of the stack
 
        A = First clause
 
        B = Second clause
 
        C = Third clause
 
 
 
        T if     A    else    B then           If T != 0 execute A else execute B
 
        T if     A    then                     If T != 0 execute A
 
          begin  A T  until                    Execute T until T != 0
 
          begin  A    again                    Inifinite loop, execute A
 
          begin  A T  while   B repeat         Execute A, if T = 0 exit loop, else execute B
 
        T for    A    next                     Execute loop T times (stores
 
                                               loop parameter on the return stack)
 
        T for    A    aft     B then C next    Execute loop T times, skip B on first loop
 
          label: A    branch  label            Branch to label
 
          label: A T  0branch label            Branch to label if T = 0
 
 
 
Unlike in a normal Forth environment these control structures can be called
 
from outside functions definitions. They must also matched up correctly,
 
otherwise a syntax error will be raised.
 
 
 
## Disassembler
## Disassembler
The disassembler takes a text file containing the assembled program, which
The disassembler takes a text file containing the assembled program, which
consists of 16-bit hexadecimal numbers. It then attempts to disassemble the
consists of 16-bit hexadecimal numbers. It then attempts to disassemble the
instructions. It can also be fed a symbols file which can be generated by the
instructions. It can also be fed a symbols file which can be generated by the
assembler and attempt to find the locations jumps and calls point to.
assembler and attempt to find the locations jumps and calls point to.
The disassembler is used by a [tcl][] script called by [GTKwave][], it
The disassembler is used by a [tcl][] script called by [GTKwave][], it
turns the instruction trace of the H2 from a series of numbers into the
turns the instruction trace of the H2 from a series of numbers into the
instructions and branch destinations that they represent. This makes debugging
instructions and branch destinations that they represent. This makes debugging
the VHDL much easier.
the VHDL much easier.
![H2 Disassembly Results](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-wave.png "Dissembled Instructions in GTKWave")
![H2 Disassembly Results](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-wave.png "Dissembled Instructions in GTKWave")
The purple trace shows the disassembled instructions.
The purple trace shows the disassembled instructions.
## Simulator
## Simulator
The simulator in C implements the H2 core and most of the SoC. The IO for the
The simulator in C implements the H2 core and most of the SoC. The IO for the
simulator is not cycle accurate (and most likely will never be), but can be
simulator is not cycle accurate, but can be used for running and debugging
used for running and debugging programs with results that are very similar to
programs with results that are very similar to how the hardware behaves.
how the hardware behaves. This is much faster than rebuilding the bit file used
This is much faster than rebuilding the bit file used to flash the [FPGA][].
to flash the [FPGA][].
 
 
 
## Debugger
## Debugger
The simulator also includes a debugger, which is designed to be similar to the
The simulator also includes a debugger, which is designed to be similar to the
[DEBUG.COM][] program available in [DOS][]. The debugger can be used to
[DEBUG.COM][] program available in [DOS][]. The debugger can be used to
disassemble sections of memory, inspect the status of the peripherals and dump
disassemble sections of memory, inspect the status of the peripherals and dump
sections of memory to the screen. It can also be used to set breakpoints,
sections of memory to the screen. It can also be used to set breakpoints,
single step and run through the code until a breakpoint is hit.
single step and run through the code until a breakpoint is hit.
To run the debugger either a hex file or a source file must be given:
To run the debugger either a hex file or a source file must be given:
        # -T turns debugging mode on
        # -T turns debugging mode on
        ./h2 -T -r file.hex  # Run simulator
        ./h2 -T -r file.hex  # Run simulator
        ./h2 -T -R file.fth  # Assemble and run some code
 
 
 
Both modes of operation can be augmented with a symbols file, which lists where
Both modes of operation can be augmented with a symbols file, which lists where
variables, labels and functions are located with the assembled core.
variables, labels and functions are located with the assembled core.
When the "-T" option is given debug mode will be entered before the simulation
When the "-T" option is given debug mode will be entered before the simulation
is executed. A prompt should appear and the command line should look like this:
is executed. A prompt should appear and the command line should look like this:
        $ ./h2 -T -R h2.fth
        $ ./h2 -T -R h2.fth
        Debugger running, type 'h' for a list of command
        Debugger running, type 'h' for a list of command
        debug>
        debug>
Break points can be set either symbolically or by program location, the 'b'
Break points can be set either symbolically or by program location, the 'b'
command is used to set breakpoints:
command is used to set breakpoints:
Numbers can be entered in octal (prefix the number with '0'), hexadecimal
Numbers can be entered in octal (prefix the number with '0'), hexadecimal
(prefix with '0x') or in decimal. As an example, the following three debug
(prefix with '0x') or in decimal. As an example, the following three debug
commands all set a breakpoint at the same location:
commands all set a breakpoint at the same location:
        debug> b 16
        debug> b 16
        debug> b 0x10
        debug> b 0x10
        debug> b 020
        debug> b 020
'k' can be used to list the current break points that are set:
'k' can be used to list the current break points that are set:
        debug> k
        debug> k
                0x0010
                0x0010
This sets a breakpoint when the function "key?" is called:
This sets a breakpoint when the function "key?" is called:
        debug> b key?
        debug> b key?
Functions and labels can both be halted on, this requires either a
Functions and labels can both be halted on, this requires either a
symbols file to be specified on the command line or assemble and run
symbols file to be specified on the command line or assemble and run
to be used on a source file, not a hex file. Symbol files can be used
to be used on a source file, not a hex file. Symbol files can be used
on source or on hex files.
on source or on hex files.
To single step the 's' command can be given, although not much will happen if
To single step the 's' command can be given, although not much will happen if
tracing is turned off (tracing is off by default). Tracing can be toggled on or
tracing is turned off (tracing is off by default). Tracing can be toggled on or
off with the 't' command:
off with the 't' command:
        debug> s
        debug> s
        debug> s
        debug> s
        debug> t
        debug> t
        trace on
        trace on
        debug> s
        debug> s
        0001: pc(089a) inst(4889) sp(0) rp(0) tos(0000) r(0000) call 889 init
        0001: pc(089a) inst(4889) sp(0) rp(0) tos(0000) r(0000) call 889 init
        debug> s
        debug> s
        0002: pc(0889) inst(807a) sp(0) rp(1) tos(0000) r(089b) 7a
        0002: pc(0889) inst(807a) sp(0) rp(1) tos(0000) r(089b) 7a
        debug> s
        debug> s
        0003: pc(088a) inst(e004) sp(1) rp(1) tos(007a) r(089b) 6004
        0003: pc(088a) inst(e004) sp(1) rp(1) tos(007a) r(089b) 6004
It is advisable to turn tracing off when running issuing the 'c', or continue,
It is advisable to turn tracing off when running issuing the 'c', or continue,
command.
command.
The '.' command can be used to display the H2 cores internal state:
The '.' command can be used to display the H2 cores internal state:
        debug> .
        debug> .
        Return Stack:
        Return Stack:
        0000: 0000 08aa 0883 017b 0000 031b 0000 ffb0 0000 02eb ffb5 0210 0167 0167
        0000: 0000 08aa 0883 017b 0000 031b 0000 ffb0 0000 02eb ffb5 0210 0167 0167
        0167 0167
        0167 0167
        0010: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
        0010: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
        0000 0000
        0000 0000
        Variable Stack:
        Variable Stack:
        tos:  0000
        tos:  0000
        0001: 0000 0000 0000 0001 0004 0005 0000 ffb0 0000 0000 0000 0000 0000 0000
        0001: 0000 0000 0000 0001 0004 0005 0000 ffb0 0000 0000 0000 0000 0000 0000
        0000 0000
        0000 0000
        0011: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
        0011: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
        0000 0000
        0000 0000
        pc:   0538
        pc:   0538
        rp:   0001
        rp:   0001
        dp:   0000
        dp:   0000
        ie:   false
        ie:   false
And the 'p' command can be used to display the state of the simulated
And the 'p' command can be used to display the state of the simulated
peripherals:
peripherals:
        debug> p
        debug> p
        LEDS:          00
        LEDS:          00
        VGA Cursor:    0005
        VGA Cursor:    0005
        VGA Control:   007a
        VGA Control:   007a
        Timer Control: 8032
        Timer Control: 8032
        Timer:         001b
        Timer:         001b
        IRC Mask:      0000
        IRC Mask:      0000
        UART Input:    6c
        UART Input:    6c
        LED 7seg:      0005
        LED 7seg:      0005
        Switches:      00
        Switches:      00
        LFSR:          40ba
        LFSR:          40ba
        Waiting:       false
        Waiting:       false
For a complete list of commands, use the 'h' command.
For a complete list of commands, use the 'h' command.
Other ways to enter debug mode include putting the ".break" assembler directive
Other ways to enter debug mode include putting the ".break" assembler directive
into the source code (this only works if the assemble and run command is used
into the source code (this only works if the assemble and run command is used
on source files, not on hex files), and hitting the escape character when the
on source files, not on hex files), and hitting the escape character when the
simulator is trying to read data via the simulated UART or PS/2 keyboard (the
simulator is trying to read data via the simulated UART or PS/2 keyboard (the
escape will still be passed onto the simulator, but it also activates debug
escape will still be passed onto the simulator, but it also activates debug
mode).
mode).
## Graphical simulator
## Graphical simulator
A separate program can be compiled, tested under [Linux][] and [Windows][].
A separate program can be compiled, tested under [Linux][] and [Windows][].
This simulates the [Nexys3][] board peripherals that the SoC interfaces with,
This simulates the [Nexys3][] board peripherals that the SoC interfaces with,
but provides a graphical environment, unlike the command line utility. It is easier
but provides a graphical environment, unlike the command line utility. It is easier
to interact with the device and see what it is doing, but the debugging sessions
to interact with the device and see what it is doing, but the debugging sessions
are a less controlled. It requires [free glut][].
are a less controlled. It requires [free glut][].
 
 
* VGA output works
* VGA shown on screen.
* UART or PS/2 input (selectable by pressing F11) comes from typing in the screen,
* UART or PS/2 input (selectable by pressing F11) comes from typing in the screen,
and in the case of the UART this is buffered with a FIFO.
and in the case of the UART this is buffered with a FIFO.
* UART output gets written to a display box.
* UART output gets written to a display box.
* There are four 7-Segment displays as on the original board.
* There are four 7-Segment displays as on the original board.
* The switches and push buttons can take their input from either keyboard keys
* The switches and push buttons can take their input from either keyboard keys
or from mouse clicks.
or from mouse clicks.
* The LED indicators above the switches can be lit up.
* The LED indicators above the switches can be lit up.
Below is an image of a running session in the GUI simulator:
Below is an image of a running session in the GUI simulator:
![H2 GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-gui.png "Running GUI H2 SoC Simulator")
![H2 GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-gui.png "Running GUI H2 SoC Simulator")
Building can be done with
Building can be done with
        make gui
        make gui
And running:
And running:
        make gui-run
        make gui-run
Or:
Or:
        ./gui   h2.hex (on Linux)
        ./gui   h2.hex (on Linux)
        gui.exe h2.hex (on Windows)
        gui.exe h2.hex (on Windows)
The [Linux][] build should work when the development package for [free glut][]
The [Linux][] build should work when the development package for [free glut][]
is installed on your system, the [Windows][] build may require changes to the
is installed on your system, the [Windows][] build may require changes to the
build system and/or manual installation of the compiler, libraries and headers.
build system and/or manual installation of the compiler, libraries and headers.
The current key map is:
The current key map is:
        Up         Activate Up D-Pad Button, Release turns off
        Up         Activate Up D-Pad Button, Release turns off
        Down       Activate Down D-Pad Button, Release turns off
        Down       Activate Down D-Pad Button, Release turns off
        Left       Activate Left D-Pad Button, Release turns off
        Left       Activate Left D-Pad Button, Release turns off
        Right      Activate Right D-Pad Button, Release turns off
        Right      Activate Right D-Pad Button, Release turns off
        F1 - F8    Toggle Switch On/Off, F1 is left most, F8 Right Most
        F1 - F8    Toggle Switch On/Off, F1 is left most, F8 Right Most
        F11        Toggle UART/PS2 Keyboard Input
        F11        Toggle UART/PS2 Keyboard Input
        F12        Toggle Debugging Information
        F12        Toggle Debugging Information
        Escape     Quit simulator
        Escape     Quit simulator
All other keyboard keys are redirected to the UART or PS/2 Keyboard input.
All other keyboard keys are redirected to the UART or PS/2 Keyboard input.
The Switches and D-Pad buttons can be clicked on to turn them on, the switches
The Switches and D-Pad buttons can be clicked on to turn them on, the switches
turn on with left clicks and off with right clicks. The D-Pads buttons turn on
turn on with left clicks and off with right clicks. The D-Pads buttons turn on
with a click on top of them and turn off with a key release anywhere on the
with a click on top of them and turn off with a key release anywhere on the
screen.
screen.
# VHDL Components
# VHDL Components
The VHDL components used in this system are designed to be reusable and
The VHDL components used in this system are designed to be reusable and
portable across different toolchains and vendors. Hardware components, like block
portable across different toolchains and vendors. Hardware components, like block
RAM, are inferred and not explicitly instantiated. The components are also made
RAM, are inferred and not explicitly instantiated. The components are also made
to be as generic as possible, with most having selectable widths. This would be
to be as generic as possible, with most having selectable widths. This would be
taken to the extreme, but unfortunately many vendors still do not support the
taken to the extreme, but unfortunately many vendors still do not support the
VHDL-2008 standard.
VHDL-2008 standard.
| File     | License    | Author          | Description                         |
| File     | License    | Author          | Description                         |
| -------- | ---------- | --------------- | ----------------------------------- |
| -------- | ---------- | --------------- | ----------------------------------- |
| util.vhd | MIT        | Richard J Howe  | A collection of generic components  |
| util.vhd | MIT        | Richard J Howe  | A collection of generic components  |
| h2.vhd   | MIT        | Richard J Howe  | H2 Forth CPU Core                   |
| h2.vhd   | MIT        | Richard J Howe  | H2 Forth CPU Core                   |
 
| uart.vhd | MIT        | Richard J Howe  | UART TX/RX (Run time customizable)  |
| vga.vhd  | LGPL 3.0   | Javier V García | Text Mode VGA 80x40 Display         |
| vga.vhd  | LGPL 3.0   | Javier V García | Text Mode VGA 80x40 Display         |
| uart.vhd | Apache 2.0 | Peter A Bennett | UART, modified from original        |
|          |            | Richard J Howe  | (and VT100 terminal emulator)       |
| kbd.vhd  | ???        | Scott Larson    | PS/2 Keyboard                       |
| kbd.vhd  | ???        | Scott Larson    | PS/2 Keyboard                       |
| led.vhd  | MIT        | Richard J Howe  | LED 7-Segment + Dot Display Driver  |
 
 
 
# eForth on the H2
# eForth on the H2
The pseudo Forth like language used as an assembler is described above, the
The pseudo Forth like language used as an assembler is described above, the
application that actually runs on the Forth core is in itself a Forth
application that actually runs on the Forth core is in itself a Forth
interpreter. This section describes the Forth interpreter that runs on H2 Core,
interpreter. This section describes the Forth interpreter that runs on H2 Core,
it is contained within [h2.fth][].
it is contained within [embed.fth][].
 
 
TODO:
TODO:
- Fully implement the Forth interpreter
* Describe the Forth environment running on the H2 CPU.
- Describe and show its operation on here including memory layout, list of
 
  words, word layout, ...
 
 
 
# Using Forth as a bootloader
 
 
 
A running Forth environment can be quite easily used as a bootloader with no
 
further modification, a simple protocol for sending data and verification of it
 
can be built using only Forth primitives - although it is not the most
 
efficient use of bandwidth.
 
 
 
The sender can interrogate the running Forth environment over the serial link
 
to determine the amount of space left in memory, and then populate it with an
 
assembled binary.
 
 
 
The Forth words needed are:
 
 
 
 
 
| Word    | Description           |
 
| ------- | --------------------- |
 
| .free   | show free space       |
 
| cp      | compile pointer       |
 
| pwd     | previous word pointer |
 
| @       | load                  |
 
| !       | store                 |
 
| cr      | print new line        |
 
| execute | execute               |
 
| decimal | set decimal output    |
 
| cells   | size of cell          |
 
| .       | print number          |
 
 
 
 
 
And of course numeric input, all of which are provided by this interpreter. The
 
protocol is line oriented, the host with the program to transfer to the H2
 
(called PC) sends a line of text and expects a reply from the H2 board (called
 
H2),
 
 
 
        PC: decimal           ( set the H2 core to a known numeric output )
 
        PC: .free cp @ . cr   ( query how much space is left, and where to put it )
 
        H2: ADDR ADDR         ( H2 replies with both addresses )
 
        PC: 1 cells . cr      ( PC queries size of cells )
 
        H2: 2                 ( H2 responds, PC now knows to increment ADDR )
 
        PC: NUM  ADDR !       ( PC write NUM to ADDR )
 
        PC: ADDR @ . cr       ( optionally PC checks value )
 
        H2: NUM               ( H2 responds with value stored at ADDR )
 
        ...                   ( PC and H2 do this as often as necessary )
 
        PC: ADDR pwd !        ( PC optionally updates previous word register )
 
        PC  ADDR cp  !        ( PC optionally updated compile poiinter )
 
        PC: ADDR execute      ( Begin execution of word )
 
 
 
The advantage of this "protocol" is that is human readable, and includes a
 
debugger for the microcontroller it is operating on.
 
 
 
# A simple Forth block editor
 
 
 
TODO:
 
- Add an SPI master with Rx/Tx Fifos to the SoC, which can then be use
 
communicate with the memory on the [Nexys3][], this can then be used in
 
conjunction with a simple block editor for a full Forth experience.
 
- Talk about implementing a simple block editor in a few words of Forth.
 
 
 
 
 
 
 
# Coding standards
# Coding standards
There are several languages used throughout this project, all of which are
There are several languages used throughout this project, all of which are
radically different from each other and require their own set of coding
radically different from each other and require their own set of coding
standards and style guides.
standards and style guides.
## VHDL
## VHDL
Common signal names:
Common signal names:
        clk       - The system clock
        clk       - The system clock
        rst       - A reset signal for the module
        rst       - A reset signal for the module
        we        - Write Enable
        we        - Write Enable
        re        - Read  Enable
        re        - Read  Enable
        di        - Data  In
        di        - Data  In
        din       - Data  In
        din       - Data  In
        do        - Data  Out
        do        - Data  Out
        dout      - Data  Out
        dout      - Data  Out
        control   - Generally an input to a register, the documentation
        control   - Generally an input to a register, the documentation
                    for the module will need to be consulted to find out
                    for the module will need to be consulted to find out
                    what each bit means
                    what each bit means
        signal_we - The write enable for 'signal'
        signal_we - The write enable for 'signal'
        signal_i  - This is an input signal
        signal_i  - This is an input signal
        signal_o  - This is an output signal
        signal_o  - This is an output signal
Generally the use of the "\_i" and "\_o" suffixes are not used, modules are
Generally the use of the "\_i" and "\_o" suffixes are not used, modules are
kept short and names chosen so their meaning is obvious. This rule might be
kept short and names chosen so their meaning is obvious. This rule might be
revisited once the project grows.
revisited once the project grows.
Components should:
Components should:
* Be as generic as possible
* Be as generic as possible
* Use an asynchronous reset
* Use an asynchronous reset
* If a feature of a module can be made optional, by either ignoring outputs
* If a feature of a module can be made optional, by either ignoring outputs
or setting inputs to sensible values, it should be.
or setting inputs to sensible values, it should be.
* Where possible use a function, it is easy enough to turn a generic
* Where possible use a function, it is easy enough to turn a generic
component into a module that can be synthesized but not the other way around.
component into a module that can be synthesized but not the other way around.
* Use "downto" not "to" when specify variable ranges.
* Use "downto" not "to" when specify variable ranges.
* Use assertions throughout the code with the correct severity level ('failure'
* Use assertions throughout the code with the correct severity level ('failure'
for when something has seriously gone wrong or 'error' for debugging purposes)
for when something has seriously gone wrong or 'error' for debugging purposes)
* Constrain types and generic parameters if possible, as an example, if a generic
* Constrain types and generic parameters if possible, as an example, if a generic
value should never be zero, use "positive" not "natural".
value should never be zero, use "positive" not "natural".
* Try not to specify constants with fixed lengths where an expression using
* Try not to specify constants with fixed lengths where an expression using
"others" can be used instead, for example:
"others" can be used instead, for example:
        constant N: positive := 4;
        constant N: positive := 4;
        signal a: std_logic_vector(N - 1 downto 0) := (others => '1');
        signal a: std_logic_vector(N - 1 downto 0) := (others => '1');
Instead of:
Instead of:
        signal a: std_logic_vector(3 downto 0) := x"F";
        signal a: std_logic_vector(3 downto 0) := x"F";
The style rules are as follows:
The style rules are as follows:
* All words, including keywords, are to be in lower case. An underscore
* All words, including keywords, are to be in lower case. An underscore
will separate words in names.
will separate words in names.
* Tabs are to be used to indent text, a tab spacing of 8 has been used when
* Tabs are to be used to indent text, a tab spacing of 8 has been used when
making the VHDL code
making the VHDL code
* Do not repeat the name of a entity, component, function or architecture,
* Do not repeat the name of a entity, component, function or architecture,
there is little point of repeating this, it just means when a unit has to be
there is little point of repeating this, it just means when a unit has to be
renamed it has to be done in two places instead of one.
renamed it has to be done in two places instead of one.
* The ":" in definitions of signals belongs next to the signal name, not
* The ":" in definitions of signals belongs next to the signal name, not
some arbitrary amount of spaces after it.
some arbitrary amount of spaces after it.
* Group related signals.
* Group related signals.
* Try to line up rows of signals
* Try to line up rows of signals
* Trigger logic on the rising edge, and use the "rising\_edge" function not
* Trigger logic on the rising edge, and use the "rising\_edge" function not
"clk'event and clk ='1'"
"clk'event and clk ='1'"
* By and large, each warning produced by the synthesis tool should be
* By and large, each warning produced by the synthesis tool should be
justified, and there should be very few warnings in the entire project if any.
justified, and there should be very few warnings in the entire project if any.
* Do not use inferred latches.
* Do not use inferred latches.
* Load data from a file instead of generating VHDL files that contain the data,
* Load data from a file instead of generating VHDL files that contain the data,
synthesis tools can handle impure VHDL functions that can read the initial data
synthesis tools can handle impure VHDL functions that can read the initial data
(for a ROM or block RAM as an example) from textual files.
(for a ROM or block RAM as an example) from textual files.
An example of the formatting guidelines, this describes a simple arbitrary
An example of the formatting guidelines, this describes a simple arbitrary
width register:
width register:
        -- Lots of comments about what the unit does should go
        -- Lots of comments about what the unit does should go
        -- here. Describe the waveforms, states and use ASCII
        -- here. Describe the waveforms, states and use ASCII
        -- art where possible.
        -- art where possible.
        library ieee;
        library ieee, work;
        use ieee.std_logic_1164.all;
        use ieee.std_logic_1164.all;
        use ieee.numeric_std.all;    -- numeric_std not std_logic_arith
        use ieee.numeric_std.all;    -- numeric_std not std_logic_arith
        entity reg is -- generic and port indented one tab, their parameters two
        entity reg is -- generic and port indented one tab, their parameters two
                generic(
                generic (
                        N: positive); -- Generic parameters make for a generic component
                        N: positive); -- Generic parameters make for a generic component
                port(
                port (
                        clk: in  std_logic; -- standard signal names
                        clk: in  std_logic; -- standard signal names
                        rst: in  std_logic; --
                        rst: in  std_logic; --
                        we:  in  std_logic;
                        we:  in  std_logic;
                        di:  in  std_logic_vector(N - 1 downto 0);
                        di:  in  std_logic_vector(N - 1 downto 0);
                        do:  out std_logic_vector(N - 1 downto 0)); -- note the position of ");
                        do:  out std_logic_vector(N - 1 downto 0)); -- note the position of ");
        end entity; -- "end entity", not "end reg"
        end entity; -- "end entity", not "end reg"
        architecture rtl of reg is
        architecture rtl of reg is
                signal r_c, r_n: std_logic_vector(N - 1 downto 0) := (others => '0');
                signal r_c, r_n: std_logic_vector(N - 1 downto 0) := (others => '0');
        begin
        begin
                do <= r_c;
                do <= r_c;
                process(rst, clk)
                process(rst, clk)
                begin
                begin
                        if rst = '1' then -- asynchronous reset
                        if rst = '1' then -- asynchronous reset
                                r_c <= (others => '0');
                                r_c <= (others => '0');
                        elsif rising_edge(clk) then -- rising edge, not "clk'event and clk = '1'"
                        elsif rising_edge(clk) then -- rising edge, not "clk'event and clk = '1'"
                                r_c <= r_n;
                                r_c <= r_n;
                        end if;
                        end if;
                end process;
                end process;
                process(r_c, di, we)
                process(r_c, di, we)
                begin
                begin
                        r_n <= r_c;
                        r_n <= r_c;
                        if we = '1' then
                        if we = '1' then
                                r_n <= di;
                                r_n <= di;
                        end if;
                        end if;
                end process;
                end process;
        end; -- "end" or "end architecture"
        end; -- "end" or "end architecture"
## C
## C
There is quite a lot of [C][] code used within this project, used to make a
There is quite a lot of [C][] code used within this project, used to make a
tool chain for the H2 core and to simulate the system. It follows a fairly
tool chain for the H2 core and to simulate the system.
strict coding style.
 
 
 
 
* Usage of assertions for any pre or post condition, or invariant, are encouraged.
* Tabs are to be used instead of spaces, a tab width of 8 was used when coding
* Tabs are to be used instead of spaces, a tab width of 8 was used when coding
  the C, if this causes any code to go off screen then there is a problem with
  the C, if this causes any code to go off screen then there is a problem with
  the code and not the tab length.
  the code and not the tab length.
* Generally the [K&R][] style is followed.
* Generally the [K&R][] style is followed.
* Line lengths should ideally be limited to 80 characters, but this is
* Line lengths should ideally be limited to 80 characters, but this is
  definitely not an enforced limit.
  definitely not an enforced limit.
* Where there are two or more data structures that must be kept in sync, with a
* Where there are two or more data structures that must be kept in sync, with a
  one to one correspondence of elements, such as an enumeration and an array of
  one to one correspondence of elements, such as an enumeration and an array of
  strings that each enumeration maps onto, an [X-Macro][] should be used to
  strings that each enumeration maps onto, an [X-Macro][] should be used to
  keep the data in sync and to initialize the enumeration and array of strings.
  keep the data in sync and to initialize the enumeration and array of strings.
* Try to use only portable constructs and isolate the constructs that are not
* Try to use only portable constructs and isolate the constructs that are not
  portable.
  portable.
There is nothing too surprising about the [C][] code within here, so some of
There is nothing too surprising about the [C][] code within here, so some of
the exceptions should be dealt with.
the exceptions should be dealt with.
* Switch statements are formatted depending upon what the switch statement 'case'
* Switch statements are formatted depending upon what the switch statement 'case'
clauses look like, if they are a simple one liner such as an assignment or a
clauses look like, if they are a simple one liner such as an assignment or a
mapping then the entire statement should occupy only a single line, for
mapping then the entire statement should occupy only a single line, for
example:
example:
 
 
        static const char *alu_op_to_string(uint16_t instruction)
        static const char *alu_op_to_string(uint16_t instruction) {
        {
 
                /* notice also that the 'case' clauses are inline with the
                /* notice also that the 'case' clauses are inline with the
                 * switch selector */
                 * switch selector */
                switch(ALU_OP(instruction)) {
                switch (ALU_OP(instruction)) {
                case ALU_OP_T:                  return "T";
                case ALU_OP_T:                  return "T";
                case ALU_OP_N:                  return "N";
                case ALU_OP_N:                  return "N";
                case ALU_OP_T_PLUS_N:           return "T+N";
                case ALU_OP_T_PLUS_N:           return "T+N";
                case ALU_OP_T_AND_N:            return "T&N";
                case ALU_OP_T_AND_N:            return "T&N";
                case ALU_OP_T_OR_N:             return "T|N";
                case ALU_OP_T_OR_N:             return "T|N";
                case ALU_OP_T_XOR_N:            return "T^N";
                case ALU_OP_T_XOR_N:            return "T^N";
                case ALU_OP_T_INVERT:           return "~T";
                case ALU_OP_T_INVERT:           return "~T";
                case ALU_OP_T_EQUAL_N:          return "N=T";
                case ALU_OP_T_EQUAL_N:          return "N=T";
                case ALU_OP_N_LESS_T:           return "T>N";
                case ALU_OP_N_LESS_T:           return "T>N";
                case ALU_OP_N_RSHIFT_T:         return "N>>T";
                case ALU_OP_N_RSHIFT_T:         return "N>>T";
                case ALU_OP_T_DECREMENT:        return "T-1";
                case ALU_OP_T_DECREMENT:        return "T-1";
                case ALU_OP_R:                  return "R";
                case ALU_OP_R:                  return "R";
                case ALU_OP_T_LOAD:             return "[T]";
                case ALU_OP_T_LOAD:             return "[T]";
                case ALU_OP_N_LSHIFT_T:         return "N<
                case ALU_OP_N_LSHIFT_T:         return "N<
                case ALU_OP_DEPTH:              return "depth";
                case ALU_OP_DEPTH:              return "depth";
                case ALU_OP_N_ULESS_T:          return "Tu>N";
                case ALU_OP_N_ULESS_T:          return "Tu>N";
                case ALU_OP_ENABLE_INTERRUPTS:  return "seti";
                case ALU_OP_ENABLE_INTERRUPTS:  return "seti";
                case ALU_OP_INTERRUPTS_ENABLED: return "iset?";
                case ALU_OP_INTERRUPTS_ENABLED: return "iset?";
                case ALU_OP_RDEPTH:             return "rdepth";
                case ALU_OP_RDEPTH:             return "rdepth";
                case ALU_OP_T_EQUAL_0:          return "0=";
                case ALU_OP_T_EQUAL_0:          return "0=";
                case ALU_OP_CPU_ID:             return "cpu-id";
                case ALU_OP_CPU_ID:             return "cpu-id";
                default:                        return "unknown";
                default:                        return "unknown";
                }
                }
        }
        }
* Unnecessary braces are avoided:
* Unnecessary braces are avoided:
        if(foo)
        if (foo)
                bar();
                bar();
        else
        else
                baz();
                baz();
* "goto" can be used - it can be misused, but using it does not instantly make
* "goto" can be used - it can be misused, but using it does not instantly make
  code inscrutable contrary to popular belief.
  code inscrutable contrary to popular belief.
 
 
## FORTH
 
 
 
The Forth in [h2.fth][] used to build an actual Forth system for the target
 
core is not a proper Forth, but a compiler for a Forth like language, this
 
idiosyncratic language has its own way of doing things. The workings of the
 
language will not be described in this section, only the coding standards and
 
style guide.
 
 
 
Either type of comment can be used, although "( )" comments are preferred,
 
single line words should be short at only a few words, multi line words
 
should be indented properly
 
 
 
        : 1+ 1 + ;
 
        : negate invert 1+ ;
 
        : dnegate not >r not 1 um+ r> + ; ( d -- d )
 
 
 
Tabs should be used for indentation and a stack comment present for long or
 
complex words.
 
 
 
        : ?rx ( -- c -1 | 0 : read in a character of input from UART )
 
                iUart @ 0x0100 and 0= ( the value to test goes on one line )
 
                if                    ( the 'if' on another line )
 
                        0x0400 oUart ! iUart @ 0xff and -1
 
                else
 
                        0
 
                then ; ( ';' is part of the final statement )
 
 
 
        \ This word is too long for the stack comment and to be on a
 
        \ single line
 
        : parse ( c -- b u ;  )
 
                >r tib >in @ + #tib @ >in @ - r> parser >in +! ;
 
 
 
Space is seriously limited on the target device at only 8192 cells (16KiB), so
 
words kept as short as possible, and programs highly factored. Speed is not so
 
much of an issue as the board and core runs at 100MHz.
 
 
 
Stack comments describe what values and Forth word takes and returns, it is
 
good practice to make words that accept and return a fixed number of parameters
 
but in certain circumstances it is advantages to return a variable number of
 
arguments. The comments also describe the type of the arguments word accepts,
 
the Forth kernel will do no checking on the data it gets however.
 
 
 
Stack comments should be added with the following scheme:
 
 
 
| Comment        | Meaning                             |
 
|----------------|-------------------------------------|
 
| a              | cell address                        |
 
| n              | signed number                       |
 
| u              | unsigned number                     |
 
| b              | string address                      |
 
| c              | single character                    |
 
| d              | double width number (2 Cells)       |
 
| f              | boolean flag (-1 = true, 0 = false) |
 
| k              | block number                        |
 
| cfa            | code field address of a word        |
 
| nfa            | name field address of a word        |
 
| pwd            | previous word address of a word     |
 
| <string> | a parsing word                      |
 
 
 
Stack comments have the following format:
 
 
 
          Variable Stack Effects  Return stack Effects     Parsing    Description
 
        ( arguments -- returns;   R: arguments -- returns;  : comment     )
 
 
 
Examples of words and their stack comments:
 
 
 
        dup   ( n -- n n : duplicate a number )
 
        >r    ( n -- ; R: -- n : move a number to the return stack )
 
        r>    ( -- n ; R: n -- : move a number from the return stack )
 
        parse ( c -- b u;  : parse a word delimted by 'c' )
 
        over  ( n1 n2 -- n1 n2 n1 : duplicate next on stack over top )
 
 
 
Words can have their arguments numbered to make it clearer what the effects
 
are.
 
 
 
# To Do
# To Do
 
 
* My [embed][] project, which was derived from the simulator and Forth for this
* Even better than using the [embed][] project directly, would be to port the
project, has an improved version of Forth which could be reintegrated with
[embed][] project so the meta-compiler runs directly on the hardware. The
this project. The [embed][] project features a metacompiler suitable for 16-bit
simulator could then be used to assemble new images, making the system (much
systems like this one, it could be used in lieu of the Pseudo-Forth compiler.
more) self-hosting. Input/Output would be a problem, a possible solution is to
* Guide to reusing the VHDL in this project, and component listing
use one of the UARTs for reading the meta-compiler and meta-compiled eForth
* Turn the [h2.fth][] into a literate program file, describing how to build up
program, and writing status/error messages. A second UART could be used to
a Forth system like in "The Zen of eForth by C. H. Ting".
dump the binary as a stream of hexadecimal numbers, the simulator could
* Make a bootloader/program loader as a single, simple program
redirect the second UART output to a file.
* Make diagrams of the SoC layout, take GIFs and pictures of the simulators and
* Create a cut down version of the project; remove nearly everything apart from
the running board.
the H2 Core, Block RAM and timer components. The interrupt handler could be
* Make a javascript based simulator for the H2, perhaps with [emscripten][]
simplified as well. The UART could be handed in the H2 Core
* Move this file to "h2.md" and make a simpler "readme.md" with a short
* The GUI simulator could be written to be built against [SDL][], and include
description and flashy GIFs
proper textures for the buttons and displays, instead of the current simulator
 
which looks like an early 90s test application for OpenGL.
 
* Prepare more documentation. Specifically about the eForth interpreter that
 
runs on the target and the online help stored within the non-volatile storage
 
on the board.
 
* An IDE for resetting/uploading the image to the target board and then sending
 
a text buffer to it would help in developing code for the platform.
 
* A [Super Optimizer][] could be made for the H2.
 
* More instructions can be combined
 
* It might be possible to add a conditional exit instruction. Other
 
instructions which would be useful are: Add with Carry, Bit Count, Leading
 
Zeroes Count, Sign Extend, Arithmetic Right Shift, Rotate Left/Right, ...
* Add notes about picocom, and setting up the hardware:
* Add notes about picocom, and setting up the hardware:
* Add a [Wishbone interface][] for each component
 
* Put the project up on [opencores][]
 
* It should be possible to turn [h2.c][] into a Forth interpreter usable in
 
a hosted environment. Some of the remaining instructions could be used for
 
function calls and floating point operations and the "uint16\_t" would have to
 
be changed to "uintptr\_t". As the interpreter is so small a Forth to "C"
 
compiler could just spit out a copy of the interpreter. It should make for
 
a very compact system.
 
* Spin off the VT100 VHDL code into a separate project, and the C code in the
 
simulator into a simple terminal emulator for Unixen.
 
* Add some example games, any of the following: Space Invaders, Tetris, Pong,
 
Minesweeper, Sokoban, Sudoku, Hack, 2048, Breakout, Brain F\*ck, Conway's
 
Game of Life, and other terminal based games could be added, see
 
 for a
 
minimal version of Nethack, and  for a
 
cool 1 dimensional game.
 
* Other programs like a compressor, decompressor, ARC4, data base function based
 
around blocks, and a meta compiler (removing the need for the C assembler),
 
could be added.
 
 
 
 
 
 
 
        picocom --omap delbs -b 115200 -e b /dev/ttyUSB1
        picocom --omap delbs -b 115200 -e b /dev/ttyUSB1
# Resources
# Resources
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
* 
 
 
 
[j1eforth]: https://github.com/samawati/j1eforth
[javascript]: https://www.javascript.com/
[javascript]: https://www.javascript.com/
[emscripten]: https://github.com/kripken/emscripten
[emscripten]: https://github.com/kripken/emscripten
[DEBUG.COM]: https://en.wikipedia.org/wiki/Debug_%28command%29
[DEBUG.COM]: https://en.wikipedia.org/wiki/Debug_%28command%29
[DOS]: https://en.wikipedia.org/wiki/DOS
[DOS]: https://en.wikipedia.org/wiki/DOS
[h2.c]: h2.c
[h2.c]: h2.c
[h2.fth]: h2.fth
[embed.fth]: embed.fth
 
[embed.c]: embed.c
 
[embed.blk]: embed.blk
[tb.vhd]: tb.vhd
[tb.vhd]: tb.vhd
[uart.vhd]: uart.vhd
[uart.vhd]: uart.vhd
 
[timer.vhd]: timer.vhd
[top.ucf]: top.ucf
[top.ucf]: top.ucf
[font.bin]: font.bin
[font.bin]: font.bin
[text.bin]: text.bin
[text.bin]: text.bin
[J1]: http://www.excamera.com/sphinx/fpga-j1.html
[J1]: http://www.excamera.com/sphinx/fpga-j1.html
[J1 PDF]: http://excamera.com/files/j1.pdf
[J1 PDF]: http://excamera.com/files/j1.pdf
[PL/0]: https://github.com/howerj/pl0
[PL/0]: https://github.com/howerj/pl0
[libforth]: https://github.com/howerj/libforth/
[libforth]: https://github.com/howerj/libforth/
[MIT]: https://en.wikipedia.org/wiki/MIT_License
[MIT]: https://en.wikipedia.org/wiki/MIT_License
[LGPL]: https://www.gnu.org/licenses/lgpl-3.0.en.html
[LGPL]: https://www.gnu.org/licenses/lgpl-3.0.en.html
[VHDL]: https://en.wikipedia.org/wiki/VHDL
[VHDL]: https://en.wikipedia.org/wiki/VHDL
[Verilog]: https://en.wikipedia.org/wiki/Verilog
[Verilog]: https://en.wikipedia.org/wiki/Verilog
[UART]: https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter
[UART]: https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter
[FORTH]: https://en.wikipedia.org/wiki/Forth_%28programming_language%29
[FORTH]: https://en.wikipedia.org/wiki/Forth_%28programming_language%29
[Nexys3]: http://store.digilentinc.com/nexys-3-spartan-6-fpga-trainer-board-limited-time-see-nexys4-ddr/
[Nexys3]: http://store.digilentinc.com/nexys-3-spartan-6-fpga-trainer-board-limited-time-see-nexys4-ddr/
[Make]: https://en.wikipedia.org/wiki/Make_%28software%29
[Make]: https://en.wikipedia.org/wiki/Make_%28software%29
[C]: https://en.wikipedia.org/wiki/C_%28programming_language%29
[C]: https://en.wikipedia.org/wiki/C_%28programming_language%29
[Debian]: https://en.wikipedia.org/wiki/Debian
[Debian]: https://en.wikipedia.org/wiki/Debian
[Linux]: https://en.wikipedia.org/wiki/Linux
[Linux]: https://en.wikipedia.org/wiki/Linux
[GCC]: https://en.wikipedia.org/wiki/GNU_Compiler_Collection
[GCC]: https://en.wikipedia.org/wiki/GNU_Compiler_Collection
[Xilinx ISE]: https://www.xilinx.com/products/design-tools/ise-design-suite.html
[Xilinx ISE]: https://www.xilinx.com/products/design-tools/ise-design-suite.html
[Xilinx]: https://www.xilinx.com
[Xilinx]: https://www.xilinx.com
[GHDL]: http://ghdl.free.fr/
[GHDL]: http://ghdl.free.fr/
[GTKWave]: http://gtkwave.sourceforge.net/
[GTKWave]: http://gtkwave.sourceforge.net/
[C99]: https://en.wikipedia.org/wiki/C99
[C99]: https://en.wikipedia.org/wiki/C99
[tcl]: https://en.wikipedia.org/wiki/Tcl
[tcl]: https://en.wikipedia.org/wiki/Tcl
[Wishbone interface]: https://en.wikipedia.org/wiki/Wishbone_%28computer_bus%29
[Wishbone interface]: https://en.wikipedia.org/wiki/Wishbone_%28computer_bus%29
[D-Pad]: https://en.wikipedia.org/wiki/D-pad
[D-Pad]: https://en.wikipedia.org/wiki/D-pad
[FIFO]: https://en.wikipedia.org/wiki/FIFO_%28computing_and_electronics%29
[FIFO]: https://en.wikipedia.org/wiki/FIFO_%28computing_and_electronics%29
[VGA]: https://en.wikipedia.org/wiki/Video_Graphics_Array
[VGA]: https://en.wikipedia.org/wiki/Video_Graphics_Array
[PS/2]: https://en.wikipedia.org/wiki/PS/2_port
[PS/2]: https://en.wikipedia.org/wiki/PS/2_port
[LED]: https://en.wikipedia.org/wiki/Light-emitting_diode
[LED]: https://en.wikipedia.org/wiki/Light-emitting_diode
[8 Segment LED Display]: https://en.wikipedia.org/wiki/Seven-segment_display
[7 Segment LED Display]: https://en.wikipedia.org/wiki/Seven-segment_display
[ISO 8859-1 (Latin-1)]: https://cs.stanford.edu/people/miles/iso8859.html
[ISO 8859-1 (Latin-1)]: https://cs.stanford.edu/people/miles/iso8859.html
[Spartan 6]: https://www.xilinx.com/products/silicon-devices/fpga/spartan-6.html
[Spartan 6]: https://www.xilinx.com/products/silicon-devices/fpga/spartan-6.html
[FPGA]: https://en.wikipedia.org/wiki/Field-programmable_gate_array
[FPGA]: https://en.wikipedia.org/wiki/Field-programmable_gate_array
[ASCII]: https://en.wikipedia.org/wiki/ASCII
[ASCII]: https://en.wikipedia.org/wiki/ASCII
[free glut]: http://freeglut.sourceforge.net/
[free glut]: http://freeglut.sourceforge.net/
[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads
[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads
[LFSR]: https://en.wikipedia.org/wiki/Linear-feedback_shift_register
[LFSR]: https://en.wikipedia.org/wiki/Linear-feedback_shift_register
[freeglut]: http://freeglut.sourceforge.net/
[freeglut]: http://freeglut.sourceforge.net/
[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form
[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form
[K&R]: https://en.wikipedia.org/wiki/Indent_style#K.26R
[K&R]: https://en.wikipedia.org/wiki/Indent_style#K.26R
[X-Macro]: https://en.wikipedia.org/wiki/X_Macro
[X-Macro]: https://en.wikipedia.org/wiki/X_Macro
[Windows]: https://en.wikipedia.org/wiki/Windows_7
[Windows]: https://en.wikipedia.org/wiki/Windows_7
[pandoc]: https://pandoc.org
[pandoc]: https://pandoc.org
[picocom]: https://github.com/npat-efault/picocom
[picocom]: https://github.com/npat-efault/picocom
[Gforth]: https://www.gnu.org/software/gforth/
[Gforth]: https://www.gnu.org/software/gforth/
[opencores]: https://opencores.org
[opencores]: https://opencores.org
[VT100]: https://en.wikipedia.org/wiki/VT100
[VT100]: https://en.wikipedia.org/wiki/VT100
[embed]: https://github.com/howerj/embed
[embed]: https://github.com/howerj/embed
 
[SDL]: https://www.libsdl.org/
 
[Apache 2.0]: https://www.apache.org/licenses/LICENSE-2.0.html
 
[KOI8-R]: https://en.wikipedia.org/wiki/KOI8-R
 
[Terminus]: http://terminus-font.sourceforge.net/
 
[ISO-8859-15]: https://en.wikipedia.org/wiki/ISO/IEC_8859-15
 
[Super Optimizer]: https://en.wikipedia.org/wiki/Superoptimization
 
 
https://www.w3schools.com/css/css_table.asp
https://www.w3schools.com/css/css_table.asp
http://adis.ca/entry/2011/pretty-code-block-in-css/
http://adis.ca/entry/2011/pretty-code-block-in-css/
https://www.w3.org/Style/Examples/007/center.en.html
https://www.w3.org/Style/Examples/007/center.en.html
https://css-tricks.com/centering-css-complete-guide/
https://css-tricks.com/centering-css-complete-guide/
-->
-->
 
 
 
 
 
![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.svg)
 
-->
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.