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

Subversion Repositories forth-cpu

[/] [forth-cpu/] [trunk/] [readme.md] - Blame information for rev 3

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 howe.r.j.8
# Forth computing system
2
 
3
| Project   | Forth SoC written in VHDL |
4
| --------- | ------------------------- |
5
| Author    | Richard James Howe        |
6
| Copyright | 2013-2017 Richard Howe    |
7
| License   | MIT/LGPL                  |
8
| Email     | howe.r.j.89@gmail.com     |
9
 
10
![H2 build status](https://travis-ci.org/howerj/forth-cpu.svg?branch=master "Build status of the H2 Assembler")
11
 
12
# Introduction
13
 
14
This project implements a small stack computer tailored to executing Forth
15
based on the [J1][] CPU. The processor has been rewritten in [VHDL][] from
16
[Verilog][], and extended slightly.
17
 
18
The goals of the project are as follows:
19
 
20
* Create a working version of [J1][] processor (called the H2).
21
* Make a working toolchain for the processor.
22
* Create a [FORTH][] for the processor which can take its input either from a
23
  [UART][] or a USB keyboard and a [VGA][] adapter.
24
 
25
The H2 processor, like the [J1][], is a stack based processor that executes an
26
instruction set especially suited for [FORTH][].
27
 
28
The current target is the [Nexys3][] board, with a [Xilinx][] Spartan-6 XC6LX16-CS324
29
[FPGA][], new boards will be targeted in the future as this board is reaching it's
30
end of life. The [VHDL][] is written in a generic way, with hardware components
31
being inferred instead of explicitly instantiated, this should make the code
32
fairly portable, although the interfaces to the [Nexys3][] board components are
33
specific to the peripherals on that board.
34
 
35
A video of the project in action, on the hardware, can be viewed here:
36
![Nexys-3 Board](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/107.mp4)
37
 
38
And a lower quality version of the same video that should play automatically:
39
 
40
![Nexys-3 Board](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/107.gif)
41
 
42
The SoC can also be simulated with a simulator written in C, as shown below:
43
 
44
![GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/sim2.gif)
45
 
46
The System Architecture is as follows:
47
 
48
![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.svg)
49
![System Architecture](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/system.png)
50
 
51
# License
52
 
53
The licenses used by the project are mixed and are on a per file basis. For my
54
code I use the [MIT][] license - so feel free to use it as you wish. The other
55
licenses used are the [LGPL][], they are confined to single modules so could be
56
removed if you have some aversion to [LGPL][] code.
57
 
58
# Target Board
59
 
60
The only target board available at the moment is the [Nexys3][], this should
61
change in the future as the board is currently at it's End Of Life. The next
62
boards I am looking to support are it's successor, the Nexys 4, and the myStorm
63
BlackIce (). The myStorm board uses a completely open
64
source toolchain for synthesis, place and route and bit file generation.
65
 
66
# Build and Running requirements
67
 
68
The build has been tested under [Debian][] [Linux][], version 8.
69
 
70
You will require:
71
 
72
* [GCC][], or a suitable [C][] compiler capable of compiling [C99][]
73
* [Make][]
74
* [Xilinx ISE][] version 14.7
75
* [GHDL][]
76
* [GTKWave][]
77
* [tcl][] version 8.6
78
* Digilent Adept2 runtime and Digilent Adept2 utilities available at
79
  
80
* [freeglut][] (for the GUI simulator only)
81
* [pandoc][] for building the documentation
82
* [picocom][] (or an alternative terminal client)
83
 
84
Hardware:
85
 
86
* VGA Monitor
87
* USB Keyboard (plugs into the Nexys3 USB to PS/2 bridge)
88
* [Nexys3][] development board
89
 
90
[Xilinx ISE][] can (or could be) downloaded for free, but requires
91
registration. ISE needs to be on your path:
92
 
93
        PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64;
94
        PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/lib/lin64;
95
 
96
# Building and Running
97
 
98
To make the [C][] based toolchain:
99
 
100
        make h2
101
 
102
To make a bit file that can be flashed to the target board:
103
 
104
        make simulation synthesis implementation bitfile
105
 
106
To upload the bitfile to the target board:
107
 
108
        make upload
109
 
110
To view the wave form generated by "make simulation":
111
 
112
        make viewer
113
 
114
The [C][] based CLI simulator can be invoked with:
115
 
116
        make run
117
 
118
Which will assemble the H2 Forth source file [h2.fth][], and run the assembled
119
object file under the H2 simulator with the debugger activated. A graphical
120
simulator can be run with:
121
 
122
        make gui-run
123
 
124
Which requires [freeglut][] as well as a [C][] compiler.
125
 
126
# Related Projects
127
 
128
The original [J1][] project is available at:
129
 
130
* 
131
 
132
This project targets the original [J1][] core and provides a eForth
133
implementation (written using [Gforth][] as for meta-compilation/cross
134
compilation to the [J1][] core). It also provides a simulator for the system
135
written in [C][].
136
 
137
* 
138
 
139
 
140
# Manual
141
 
142
The H2 processor and associated peripherals are subject to change, so the code
143
is the definitive source what instructions are available, the register map, and
144
how the peripherals behave.
145
 
146
There are a few modifications to the [J1][] CPU which include:
147
 
148
* New instructions
149
* A CPU hold line which keeps the processor in the same state so long as it is
150
high.
151
* Interrupt Service Routines have been added.
152
* Larger return and data stacks
153
 
154
The Interrupt Service Routines (ISR) have not been throughly tested and will be
155
subject to the most change.
156
 
157
### H2 CPU
158
 
159
The H2 CPU behaves very similarly to the [J1][] CPU, and the [J1 PDF][] can be
160
read in order to better understand this processor. The processor is 16-bit with
161
instructions taking a single clock cycle. Most of the primitive Forth words can
162
also be executed in a single cycle as well, one notable exception is store ("!"),
163
which is split into two instructions.
164
 
165
The CPU has the following state within it:
166
 
167
* A 64 deep return stack (up from 32 in the original [J1][])
168
* A 65 deep variable stack (up from 33 in the original [J1][])
169
* A program counter
170
* An interrupt enable and interrupt request bit
171
* An interrupt address register
172
 
173
Loads and stores into the block RAM that holds the H2 program discard the
174
lowest bit, every other memory operation uses the lower bit (such as jumps
175
and loads and stores to Input/Output peripherals). This is so applications can
176
use the lowest bit for character operations when accessing the program RAM.
177
 
178
The instruction set is decoded in the following manner:
179
 
180
        +---------------------------------------------------------------+
181
        | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
182
        +---------------------------------------------------------------+
183
        | 1 |                    LITERAL VALUE                          |
184
        +---------------------------------------------------------------+
185
        | 0 | 0 | 0 |            BRANCH TARGET ADDRESS                  |
186
        +---------------------------------------------------------------+
187
        | 0 | 0 | 1 |            CONDITIONAL BRANCH TARGET ADDRESS      |
188
        +---------------------------------------------------------------+
189
        | 0 | 1 | 0 |            CALL TARGET ADDRESS                    |
190
        +---------------------------------------------------------------+
191
        | 0 | 1 | 1 |   ALU OPERATION   |T2N|T2R|N2A|R2P| RSTACK| DSTACK|
192
        +---------------------------------------------------------------+
193
        | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
194
        +---------------------------------------------------------------+
195
 
196
        T   : Top of data stack
197
        N   : Next on data stack
198
        PC  : Program Counter
199
 
200
        LITERAL VALUES : push a value onto the data stack
201
        CONDITIONAL    : BRANCHS pop and test the T
202
        CALLS          : PC+1 onto the return stack
203
 
204
        T2N : Move T to N
205
        T2R : Move T to top of return stack
206
        N2A : STORE T to memory location addressed by N
207
        R2P : Move top of return stack to PC
208
 
209
        RSTACK and DSTACK are signed values (twos compliment) that are
210
        the stack delta (the amount to increment or decrement the stack
211
        by for their respective stacks: return and data)
212
 
213
#### ALU operations
214
 
215
 
216
All ALU operations replace T:
217
 
218
| Value |   Operation    |     Description       |
219
|-------|----------------|-----------------------|
220
|   0   |       T        |  Top of Stack         |
221
|   1   |       N        |  Copy T to N          |
222
|   2   |     T + N      |  Addition             |
223
|   3   |     T & N      |  Bitwise AND          |
224
|   4   |     T or N     |  Bitwise OR           |
225
|   5   |     T ^ N      |  Bitwise XOR          |
226
|   6   |      ~T        |  Bitwise Inversion    |
227
|   7   |     T = N      |  Equality test        |
228
|   8   |     N < T      |  Signed comparison    |
229
|   9   |     N >> T     |  Logical Right Shift  |
230
|  10   |     T - 1      |  Decrement            |
231
|  11   |       R        |  Top of return stack  |
232
|  12   |      [T]       |  Load from address    |
233
|  13   |     N << T     |  Logical Left Shift   |
234
|  14   |     depth      |  Depth of stack       |
235
|  15   |     N u< T     |  Unsigned comparison  |
236
|  16   | set interrupts |  Enable interrupts    |
237
|  17   | interrupts on? |  Are interrupts on?   |
238
|  18   |     rdepth     |  Depth of return stk  |
239
|  19   |      0=        |  T == 0?              |
240
|  20   |     CPU ID     |  CPU Identifier       |
241
 
242
 
243
### Peripherals and registers
244
 
245
Registers marked prefixed with an 'o' are output registers, those with an 'i'
246
prefix are input registers. Registers are divided into an input and output
247
section of registers and the addresses of the input and output registers do not
248
correspond to each other in all cases. Unlike for RAM reads, the I/O registers
249
are indexed by word aligned addresses, without the lowest bit being discarded
250
(this should be fixed at a later date).
251
 
252
The following peripherals have been implemented in the [VHDL][] SoC to
253
interface with devices on the [Nexys3][] board:
254
 
255
* [VGA][] output device, text mode only, 80 by 40 characters from
256
  
257
* Timer
258
* [UART][] (Rx/Tx) with a [FIFO][]
259
from 
260
* [PS/2][] Keyboard
261
from 
262
* [LED][] next to a bank of switches
263
* An [8 Segment LED Display][] driver (a 7 segment display with a decimal point)
264
 
265
The SoC also features a limited set of interrupts that can be enabled or
266
disabled.
267
 
268
The output register map:
269
 
270
| Register    | Address | Description                     |
271
|-------------|---------|---------------------------------|
272
| oUart       | 0x4000  | UART register                   |
273
| oVT100      | 0x4002  | VT100 Terminal Write            |
274
| oLeds       | 0x4004  | LED outputs                     |
275
| oTimerCtrl  | 0x4006  | Timer control                   |
276
| oMemDout    | 0x4008  | Memory Data Output              |
277
| oMemControl | 0x400A  | Memory Control / Hi Address     |
278
| oMemAddrLow | 0x400C  | Memory Lo Address               |
279
| o7SegLED    | 0x400E  | 4 x LED 8 Segment display       |
280
| oIrcMask    | 0x4010  | CPU Interrupt Mask              |
281
 
282
 
283
The input registers:
284
 
285
| Register    | Address | Description                     |
286
|-------------|---------|---------------------------------|
287
| iUart       | 0x4000  | UART register                   |
288
| iVT100      | 0x4002  | Terminal status & PS/2 Keyboard |
289
| iSwitches   | 0x4004  | Buttons and switches            |
290
| iTimerDin   | 0x4006  | Current Timer Value             |
291
| iMemDin     | 0x4008  | Memory Data Input               |
292
 
293
 
294
The following description of the registers should be read in order and describe
295
how the peripherals work as well.
296
 
297
#### oUart
298
 
299
A UART with a fixed baud rate and format (115200, 8 bits, 1 stop bit) is
300
present on the SoC. The UART has a FIFO of depth 8 on both the RX and TX
301
channels. The control of the UART is split across oUart and iUart.
302
 
303
To write a value to the UART assert TXWE along with putting the data in TXDO.
304
The FIFO state can be analyzed by looking at the iUart register.
305
 
306
To read a value from the UART: iUart can be checked to see if data is present
307
in the FIFO, if it is assert RXRE in the oUart register, on the next clock
308
cycle the data will be present in the iUart register.
309
 
310
The baud rate of the UART can be changed by rebuilding the VHDL project, bit
311
length, parity bits and stop bits can only be changed with modifications to
312
[uart.vhd][]
313
 
314
        +-------------------------------------------------------------------------------+
315
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
316
        +-------------------------------------------------------------------------------+
317
        |  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |
318
        +-------------------------------------------------------------------------------+
319
 
320
        TXWE: UART TX Write Enable
321
        RXRE: UART RX Read Enable
322
        TXDO: UART TX Data Output
323
 
324
#### oVT100
325
 
326
The VGA Text device emulates a terminal which the user can talk to by writing
327
to the oVT100 register. It supports a subset of the [VT100][] terminal
328
functionality. The interface behaves much like writing to a UART with the same
329
busy and control signals. The input is taken from a [PS/2][] keyboard available
330
on the board, this behaves like the RX mechanism of the UART.
331
 
332
        +-------------------------------------------------------------------------------+
333
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
334
        +-------------------------------------------------------------------------------+
335
        |  X |  X |TXWE|  X |  X |RXRE|  X |  X |               TXDO                    |
336
        +-------------------------------------------------------------------------------+
337
 
338
        TXWE: VT100 TX Write Enable
339
        RXRE: UART RX Read Enable
340
        TXDO: UART TX Data Output
341
 
342
#### oLeds
343
 
344
On the [Nexys3][] board there is a bank of LEDs that are situated next to the
345
switches, these LEDs can be turned on (1) or off (0) by writing to LEDO. Each
346
LED here corresponds to the switch it is next to.
347
 
348
        +-------------------------------------------------------------------------------+
349
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
350
        +-------------------------------------------------------------------------------+
351
        |  X |  X |  X |  X |  X |  X |  X |  X |              LEDO                     |
352
        +-------------------------------------------------------------------------------+
353
 
354
        LEDO: LED Output
355
 
356
#### oTimerCtrl
357
 
358
The timer is controllable by the oTimerCtrl register, it is a 13-bit timer
359
running at 100MHz, it can optionally generate interrupts and the current timers
360
internal count can be read back in with the iTimerDin register.
361
 
362
The timer counts once the TE bit is asserted, once the timer reaches TCMP value
363
it wraps around and can optionally generate an interrupt by asserting INTE.
364
This also toggles the Q and NQ lines that come out of the timer and are routed
365
to pins on the board (see the constraints file [top.ucf][] for the pins).
366
 
367
The timer can be reset by writing to RST.
368
 
369
        +-------------------------------------------------------------------------------+
370
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
371
        +-------------------------------------------------------------------------------+
372
        | TE | RST|INTE|                      TCMP                                      |
373
        +-------------------------------------------------------------------------------+
374
 
375
        TE:   Timer Enable
376
        RST:  Timer Reset
377
        INTE: Interrupt Enable
378
        TCMP: Timer Compare Value
379
 
380
 
381
#### oIrcMask
382
 
383
The H2 core has a mechanism for interrupts, interrupts have to be enabled or
384
disabled with an instruction. Each interrupt can be masked off with a bit in
385
IMSK to enable that specific interrupt. A '1' in a bit of IMSK enables that
386
specific interrupt, which will be delivered to the CPU if interrupts are
387
enabled within it.
388
 
389
        +-------------------------------------------------------------------------------+
390
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
391
        +-------------------------------------------------------------------------------+
392
        |  X |  X |  X |  X |  X |  X |  X |  X |                 IMSK                  |
393
        +-------------------------------------------------------------------------------+
394
 
395
        IMSK: Interrupt Mask
396
 
397
#### oMemDout
398
 
399
Data to be output to selected address when write enable (WE) issued in
400
oMemControl.
401
 
402
        +-------------------------------------------------------------------------------+
403
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
404
        +-------------------------------------------------------------------------------+
405
        |                           Data Ouput                                          |
406
        +-------------------------------------------------------------------------------+
407
 
408
#### oMemControl
409
 
410
This register contains the control registers for the onboard memory on the
411
[Nexys3][] board. The board contains three memory devices, two non-volatile
412
memory devices and a volatile RAM based device. The two devices accessible by a
413
simple SRAM interface (one volatile M45W8MW16, one non-volatile - a
414
NP8P128A13T1760E) are both accessible, the third is an SPI based memory device,
415
NP5Q128A13ESFC0E) and is currently not accessible.
416
 
417
        +-------------------------------------------------------------------------------+
418
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
419
        +-------------------------------------------------------------------------------+
420
        | OE | WE | RST|WAIT| RCS| FCS|                 Address Hi                      |
421
        +-------------------------------------------------------------------------------+
422
 
423
        OE:  Output Enable - enable reading from current address into iMemDin
424
        WE:  Write Enable  - enable writing oMemDout into ram at current address
425
        RST: Reset the Flash memory controller
426
        RCS: RAM Chip Select, Enable Volatile Memory
427
        FCS: Flash Chip Select, Enable Non-Volatile Memory
428
        Address Hi: High Bits of RAM address
429
 
430
OE and WE are mutually exclusive, if both are set then there is no effect.
431
 
432
The memory controller is in active development, and the interface to it might
433
change.
434
 
435
#### oMemAddrLow
436
 
437
This is the lower address bits of the RAM.
438
 
439
        +-------------------------------------------------------------------------------+
440
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
441
        +-------------------------------------------------------------------------------+
442
        |                           Address Lo                                          |
443
        +-------------------------------------------------------------------------------+
444
 
445
#### o7SegLED
446
 
447
On the [Nexys3][] board there is a bank of 7 segment displays, with a dot
448
(8-segment really), which can be used for numeric output. The LED segments
449
cannot be directly addressed. Instead the value stored in L8SD is mapped
450
to a hexadecimal display value (or a BCD value, but this requires regeneration
451
of the SoC and modification of a generic in the VHDL).
452
 
453
The value '0' corresponds to a zero displayed on the LED segment, '15' to an
454
'F', etcetera.
455
 
456
There are 4 displays in a row.
457
 
458
        +-------------------------------------------------------------------------------+
459
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
460
        +-------------------------------------------------------------------------------+
461
        |      L7SD0        |       L7SD1       |       L7SD2       |       L7SD3       |
462
        +-------------------------------------------------------------------------------+
463
 
464
        L7SD0: LED 7 Segment Display (leftmost display)
465
        L7SD1: LED 7 Segment Display
466
        L7SD2: LED 7 Segment Display
467
        L7SD3: LED 7 Segment Display (right most display)
468
 
469
#### iUart
470
 
471
The iUart register works in conjunction with the oUart register. The status of
472
the FIFO that buffers both transmission and reception of bytes is available in
473
the iUart register, as well as any received bytes.
474
 
475
        +-------------------------------------------------------------------------------+
476
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
477
        +-------------------------------------------------------------------------------+
478
        |  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|                RXDI                   |
479
        +-------------------------------------------------------------------------------+
480
 
481
        TFFL: UART TX FIFO Full
482
        TFEM: UART TX FIFO Empty
483
        RFFL: UART RX FIFO Full
484
        RFEM: UART RX FIFO Empty
485
        RXDI: UART RX Data Input
486
 
487
#### iVT100
488
 
489
The iVT100 register works in conjunction with the oVT100 register. The status of
490
the FIFO that buffers both transmission and reception of bytes is available in
491
the iVT100 register, as well as any received bytes. It works the same as the
492
iUart/oUart registers.
493
 
494
        +-------------------------------------------------------------------------------+
495
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
496
        +-------------------------------------------------------------------------------+
497
        |  X |  X |  X |TFFL|TFEM|  X |RFFL|RFEM|  0 |           ACHR                   |
498
        +-------------------------------------------------------------------------------+
499
 
500
        TFFL: VGA VT100 TX FIFO Full
501
        TFEM: VGA VT100 TX FIFO Empty
502
        RFFL: PS2 VT100 RX FIFO Full
503
        RFEM: PS2 VT100 RX FIFO Empty
504
        ACHR: New character available on PS2 Keyboard
505
 
506
#### iTimerDin
507
 
508
This register contains the current value of the timers counter.
509
 
510
        +-------------------------------------------------------------------------------+
511
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
512
        +-------------------------------------------------------------------------------+
513
        |  X |  X |  X |                       TCNT                                     |
514
        +-------------------------------------------------------------------------------+
515
 
516
        TCNT: Timer Counter Value
517
 
518
#### iSwitches
519
 
520
iSwitches contains input lines from multiple sources. The buttons
521
(BUP, BDWN, BLFT, BRGH, and BCNT) correspond to a [D-Pad][] on the [Nexys3][]
522
board. The switches (TSWI) are the ones mentioned in oLeds, each have an LED
523
next to them.
524
 
525
The switches and the buttons are already debounced in hardware so they do not
526
have to be further processed once read in from these registers.
527
 
528
        +-------------------------------------------------------------------------------+
529
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
530
        +-------------------------------------------------------------------------------+
531
        |  X |  X |  X | BUP|BDWN|BLFT|BRGH|BCNT|               TSWI                    |
532
        +-------------------------------------------------------------------------------+
533
 
534
        BUP:  Button Up
535
        BDWN: Button Down
536
        BLFT: Button Left
537
        BRGH: Button Right
538
        BCNT: Button Center
539
        TSWI: Two Position Switches
540
 
541
#### iMemDin
542
 
543
Memory input, either from the SRAM or Flash, indexed by oMemControl and
544
oMemAddrLow. When reading from flash this might actually be status information
545
or information from the query table.
546
 
547
        +-------------------------------------------------------------------------------+
548
        | 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0 |
549
        +-------------------------------------------------------------------------------+
550
        |                           Data Input                                          |
551
        +-------------------------------------------------------------------------------+
552
 
553
 
554
### Interrupt Service Routines
555
 
556
The following interrupt service routines are defined:
557
 
558
|       Name        | Number |         Description           |
559
|-------------------|--------|-------------------------------|
560
| isrNone           |   0    | Not used                      |
561
| isrRxFifoNotEmpty |   1    | UART RX FIFO Is Not Empty     |
562
| isrRxFifoFull     |   2    | UART RX FIFI Is Full          |
563
| isrTxFifoNotEmpty |   3    | UART TX FIFO Is Not Empty     |
564
| isrTxFifoFull     |   4    | UART TX FIFO Is Full          |
565
| isrKbdNew         |   5    | New PS/2 Keyboard Character   |
566
| isrTimer          |   6    | Timer Counter                 |
567
| isrDPadButton     |   7    | Any D-Pad Button Change State |
568
 
569
 
570
When an interrupt occurs, and interrupts are enabled within the processor, then
571
a call to the location in memory is performed - the location is the same as the
572
ISR number. An ISR with a number of '4' will perform a call (not a jump) to the
573
location '4' within memory, for example.
574
 
575
Interrupts have a latency of at least 4-5 cycles before they are acted on, there
576
is a two to three cycle delay in the interrupt request handler, then the call
577
to the ISR location in memory has to be done, then the call to the word that
578
implements the ISR itself.
579
 
580
If two interrupts occur at the same time they are processed from the lowest
581
interrupt number to the highest.
582
 
583
Interrupts are lost when an interrupt with the same number occurs that has not
584
been processed.
585
 
586
# The Toolchain
587
 
588
The Assembler, Disassembler and [C][] based simulator for the H2 is in a single
589
program (see [h2.c][]). This simulator complements the [VHDL][] test bench
590
[tb.vhd][] and is not a replacement for it.
591
 
592
To build it a [C][] compiler is needed, the build target "h2" will build the
593
executable:
594
 
595
        make h2
596
 
597
And it can be run on the source file [h2.fth][] with the make target:
598
 
599
        make run
600
 
601
The make file is not needed:
602
 
603
        Linux:
604
 
605
        cc -std=c99 h2.c -o h2  # To build the h2 executable
606
        ./h2 -h                 # For a list of options
607
        ./h2 -T -R h2.fth       # Assemble h2.fth and run it
608
 
609
        Windows:
610
 
611
        gcc -std=c99 h2.c -o h2.exe # Builds the h2.exe executable
612
        h2.exe -h                   # For a list of options
613
        h2.exe -T -R h2.fth         # Assemble h2.fth and run it
614
 
615
A list of command line options available:
616
 
617
        -       stop processing options, following arguments are files
618
        -h      print a help message and exit
619
        -v      increase logging level
620
        -d      disassemble input files (default)
621
        -D      full disassembly of input files
622
        -T      Enter debug mode when running simulation
623
        -a      assemble file
624
        -r      run hex file
625
        -R      assemble file then run it
626
        -L #    load symbol file
627
        -S #    save symbols to file
628
        -s #    number of steps to run simulation (0 = forever)
629
        -n #    specify NVRAM block file (default is nvram.blk)
630
        file*   file to process
631
 
632
This program is released under the [MIT][] license, feel free to use it and
633
modify it as you please. With minimal modification it should be able to
634
assemble programs for the original [J1][] core.
635
 
636
## Assembler
637
 
638
The assembler is actually a compiler for a pseudo Forth like language with a
639
fixed grammar. It is a much more restricted language than Forth and cannot be
640
extended within itself like Forth can.
641
 
642
The main program can be found in [h2.fth][], which is still currently in
643
testing.
644
 
645
The assembler/compiler reads in a text file containing a program and produces a
646
hex file which can be read in by the simulator, disassembler, the VHDL test
647
bench or read in by the [Xilinx ISE][] toolchain when it generates the bit file
648
for the [Spartan 6][] on the [Nexys3][] board.
649
 
650
A rough [EBNF][] grammar for the language is as follows:
651
 
652
        Program     := Statement* EOF
653
        Statement   :=   Label | Branch | 0Branch | Call | Literal | Instruction
654
                       | Identifier | Constant | Variable | Location | Definition | If
655
                       | Begin | Char | Set | Pc | Pwd | Break | Mode | String | BuiltIn
656
        Label       := Identifier ";"
657
        Branch      := "branch"  ( Identifier | Literal )
658
        0Branch     := "0branch" ( Identifier | Literal )
659
        Call        := "call"    ( Identifier | Literal )
660
        Set         := ".set"    ( Identifier | Literal | String ) ( Identifier | Literal | String )
661
        Pc          := ".pc"     ( Identifier | Literal )
662
        Pwd         := ".pwd"    ( Identifier | Literal )
663
        Break       := ".break"
664
        BuiltIn     := ".built-in"
665
        Mode        := ".mode"      Literal
666
        Allocate    := ".allocate" ( Identifier | Literal )
667
        Constant    := "constant" Identifier Literal "hidden"?
668
        Variable    := "variable" Identifier ( Literal | String ) "hidden"?
669
        Location    := "Location" Identifier ( Literal | String )
670
        Instruction := "@" | "store" | "exit" | ...
671
        Definition  := ":" ( Identifier | String) Statement* ";" ( "hidden" | "immediate" | "inline")
672
        If          := "if" Statement* [ "else" ] Statement* "then"
673
        Begin       := "begin" Statement* ("until" | "again" | "while" Statement* "repeat")
674
        For         := "for"   Statement* ("aft" Statement* "then" Statement* | "next")
675
        Literal     := [ "-" ] Number
676
        String      := '"' SChar* '"'
677
        Char        := "[char]" ASCII ","
678
        Number      := Hex | Decimal
679
        Decimal     := "0" ... "9" ("0" ... "9")*
680
        Hex         := "$" HexDigit HexDigit*
681
        HexDigit    := ( "a" ... "f" | "A" ... "F" )
682
        SChar       := Any character except quote
683
 
684
Literals have higher priority than Identifiers, and comments are '\'
685
until a new line is encountered, or '(' until a ')' is encountered.
686
 
687
The grammar allows for nested word definitions, however state is held in the
688
lexer to prevent this.
689
 
690
The assembler the following directives:
691
 
692
        .pc        Set the program counter
693
        .pwd       Set the previous word pointer
694
        .allocate  Increment the program counter
695
        .set       Set location in memory
696
        .mode      Change compiler mode
697
        .built-in  Assemble built words here
698
 
699
 
700
There are several optimizations that can be performed, the ".mode" directive
701
controls whether they are active, along with controlling whether word
702
definitions are compiled with their headers or not. Optimizations performed
703
include merging a call to exit with the previous instruction if it is possible
704
to do so and performing tail call optimization where possible.
705
 
706
The built in words, with their instruction encodings:
707
 
708
 
709
| Word   | 0 | 1 | 1 |   ALU OPERATION   |T2N|T2R|N2A|R2P| RSTACK| DSTACK|
710
|--------|---|---|---|-------------------|---|---|---|---|-------|-------|
711
| dup    | 0 | 1 | 1 |       T           | X |   |   |   |       |  +1   |
712
| over   | 0 | 1 | 1 |       N           | X |   |   |   |       |  +1   |
713
| invert | 0 | 1 | 1 |       ~ T         |   |   |   |   |       |       |
714
| +      | 0 | 1 | 1 |       T + N       |   |   |   |   |       |  -1   |
715
| swap   | 0 | 1 | 1 |       N           | X |   |   |   |       |       |
716
| nip    | 0 | 1 | 1 |       T           |   |   |   |   |       |  -1   |
717
| drop   | 0 | 1 | 1 |       N           |   |   |   |   |       |  -1   |
718
| exit   | 0 | 1 | 1 |       T           |   |   |   | X |   -1  |       |
719
| >r  | 0 | 1 | 1 |       N           |   | X |   |   |   +1  |  -1   |
720
| r>  | 0 | 1 | 1 |       R           | X |   |   |   |   -1  |  +1   |
721
| r@     | 0 | 1 | 1 |       R           | X |   |   |   |       |  +1   |
722
| @      | 0 | 1 | 1 |       [T]         |   |   |   |   |       |       |
723
| store  | 0 | 1 | 1 |       N           |   |   | X |   |       |  -1   |
724
| rshift | 0 | 1 | 1 |       N >> T      |   |   |   |   |       |  -1   |
725
| lshift | 0 | 1 | 1 |       N << T      |   |   |   |   |       |  -1   |
726
| =      | 0 | 1 | 1 |       N = T       |   |   |   |   |       |  -1   |
727
| u<     | 0 | 1 | 1 |       N u< T      |   |   |   |   |       |  -1   |
728
| <      | 0 | 1 | 1 |       N < T       |   |   |   |   |       |  -1   |
729
| and    | 0 | 1 | 1 |       T & N       |   |   |   |   |       |  -1   |
730
| xor    | 0 | 1 | 1 |       T ^ N       |   |   |   |   |       |  -1   |
731
| or     | 0 | 1 | 1 |       T or N      |   |   |   |   |       |  -1   |
732
| depth  | 0 | 1 | 1 |       depth       |   |   |   |   |       |  +1   |
733
| 1-     | 0 | 1 | 1 |       T - 1       |   |   |   |   |       |       |
734
| seti   | 0 | 1 | 1 |   set interrupts  |   |   |   |   |       |  -1   |
735
| iset?  | 0 | 1 | 1 |   interrupts on?  |   |   |   |   |       |  +1   |
736
| rdepth | 0 | 1 | 1 |      rdepth       |   |   |   |   |       |  +1   |
737
| 0=     | 0 | 1 | 1 |        0=         |   |   |   |   |       |       |
738
| up1    | 0 | 1 | 1 |        T          |   |   |   |   |       |  +1   |
739
| nop    | 0 | 1 | 1 |        T          |   |   |   |   |       |       |
740
| cpu-id | 0 | 1 | 1 |      CPU ID       |   |   |   |   |       |  +1   |
741
| rdrop  | 0 | 1 | 1 |        T          |   |   |   |   |  -1   |       |
742
 
743
 
744
The language used in the assembler is Forth like, the best example of how to
745
use it is in the file "h2.fth", which contains a working Forth interpreter and
746
many Forth definitions. New words can be defined in the usual manner:
747
 
748
        : 2+ 2 + ;
749
        : ?dup dup if dup then ;
750
 
751
Control structure mismatches cause the parser to terminate with an error
752
condition as they are handled with a parser, each ":" must have a corresponding
753
";", an "if" must have either an "else" and then "then", or just "then",
754
etcetera.
755
 
756
Variables and constants can also be defined, but the grammar is slightly
757
different to how it works in a normal Forth:
758
 
759
        variable x 55
760
        constant y 20
761
 
762
Constants take up no space unless they are used, whereas variables are
763
allocated a location and set to an initial value. The above example creates a
764
variable 'x' and sets the variable to '55'. It also adds a constant 'y' to the
765
current symbol table, which can be used in other function definitions.
766
 
767
Code that does not appear within a word definition is assembled at that
768
location.
769
 
770
The following control structures are available:
771
 
772
        T = value to consume off the top of the stack
773
        A = First clause
774
        B = Second clause
775
        C = Third clause
776
 
777
        T if     A    else    B then           If T != 0 execute A else execute B
778
        T if     A    then                     If T != 0 execute A
779
          begin  A T  until                    Execute T until T != 0
780
          begin  A    again                    Inifinite loop, execute A
781
          begin  A T  while   B repeat         Execute A, if T = 0 exit loop, else execute B
782
        T for    A    next                     Execute loop T times (stores
783
                                               loop parameter on the return stack)
784
        T for    A    aft     B then C next    Execute loop T times, skip B on first loop
785
          label: A    branch  label            Branch to label
786
          label: A T  0branch label            Branch to label if T = 0
787
 
788
Unlike in a normal Forth environment these control structures can be called
789
from outside functions definitions. They must also matched up correctly,
790
otherwise a syntax error will be raised.
791
 
792
## Disassembler
793
 
794
The disassembler takes a text file containing the assembled program, which
795
consists of 16-bit hexadecimal numbers. It then attempts to disassemble the
796
instructions. It can also be fed a symbols file which can be generated by the
797
assembler and attempt to find the locations jumps and calls point to.
798
 
799
The disassembler is used by a [tcl][] script called by [GTKwave][], it
800
turns the instruction trace of the H2 from a series of numbers into the
801
instructions and branch destinations that they represent. This makes debugging
802
the VHDL much easier.
803
 
804
![H2 Disassembly Results](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-wave.png "Dissembled Instructions in GTKWave")
805
 
806
The purple trace shows the disassembled instructions.
807
 
808
## Simulator
809
 
810
The simulator in C implements the H2 core and most of the SoC. The IO for the
811
simulator is not cycle accurate (and most likely will never be), but can be
812
used for running and debugging programs with results that are very similar to
813
how the hardware behaves. This is much faster than rebuilding the bit file used
814
to flash the [FPGA][].
815
 
816
## Debugger
817
 
818
The simulator also includes a debugger, which is designed to be similar to the
819
[DEBUG.COM][] program available in [DOS][]. The debugger can be used to
820
disassemble sections of memory, inspect the status of the peripherals and dump
821
sections of memory to the screen. It can also be used to set breakpoints,
822
single step and run through the code until a breakpoint is hit.
823
 
824
To run the debugger either a hex file or a source file must be given:
825
 
826
        # -T turns debugging mode on
827
        ./h2 -T -r file.hex  # Run simulator
828
        ./h2 -T -R file.fth  # Assemble and run some code
829
 
830
Both modes of operation can be augmented with a symbols file, which lists where
831
variables, labels and functions are located with the assembled core.
832
 
833
When the "-T" option is given debug mode will be entered before the simulation
834
is executed. A prompt should appear and the command line should look like this:
835
 
836
        $ ./h2 -T -R h2.fth
837
        Debugger running, type 'h' for a list of command
838
        debug>
839
 
840
Break points can be set either symbolically or by program location, the 'b'
841
command is used to set breakpoints:
842
 
843
Numbers can be entered in octal (prefix the number with '0'), hexadecimal
844
(prefix with '0x') or in decimal. As an example, the following three debug
845
commands all set a breakpoint at the same location:
846
 
847
        debug> b 16
848
        debug> b 0x10
849
        debug> b 020
850
 
851
'k' can be used to list the current break points that are set:
852
 
853
        debug> k
854
                0x0010
855
 
856
This sets a breakpoint when the function "key?" is called:
857
 
858
        debug> b key?
859
 
860
Functions and labels can both be halted on, this requires either a
861
symbols file to be specified on the command line or assemble and run
862
to be used on a source file, not a hex file. Symbol files can be used
863
on source or on hex files.
864
 
865
To single step the 's' command can be given, although not much will happen if
866
tracing is turned off (tracing is off by default). Tracing can be toggled on or
867
off with the 't' command:
868
 
869
        debug> s
870
        debug> s
871
        debug> t
872
        trace on
873
        debug> s
874
        0001: pc(089a) inst(4889) sp(0) rp(0) tos(0000) r(0000) call 889 init
875
        debug> s
876
        0002: pc(0889) inst(807a) sp(0) rp(1) tos(0000) r(089b) 7a
877
        debug> s
878
        0003: pc(088a) inst(e004) sp(1) rp(1) tos(007a) r(089b) 6004
879
 
880
It is advisable to turn tracing off when running issuing the 'c', or continue,
881
command.
882
 
883
The '.' command can be used to display the H2 cores internal state:
884
 
885
        debug> .
886
        Return Stack:
887
        0000: 0000 08aa 0883 017b 0000 031b 0000 ffb0 0000 02eb ffb5 0210 0167 0167
888
        0167 0167
889
        0010: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
890
        0000 0000
891
 
892
        Variable Stack:
893
        tos:  0000
894
        0001: 0000 0000 0000 0001 0004 0005 0000 ffb0 0000 0000 0000 0000 0000 0000
895
        0000 0000
896
        0011: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
897
        0000 0000
898
 
899
        pc:   0538
900
        rp:   0001
901
        dp:   0000
902
        ie:   false
903
 
904
And the 'p' command can be used to display the state of the simulated
905
peripherals:
906
 
907
        debug> p
908
        LEDS:          00
909
        VGA Cursor:    0005
910
        VGA Control:   007a
911
        Timer Control: 8032
912
        Timer:         001b
913
        IRC Mask:      0000
914
        UART Input:    6c
915
        LED 7seg:      0005
916
        Switches:      00
917
        LFSR:          40ba
918
        Waiting:       false
919
 
920
For a complete list of commands, use the 'h' command.
921
 
922
Other ways to enter debug mode include putting the ".break" assembler directive
923
into the source code (this only works if the assemble and run command is used
924
on source files, not on hex files), and hitting the escape character when the
925
simulator is trying to read data via the simulated UART or PS/2 keyboard (the
926
escape will still be passed onto the simulator, but it also activates debug
927
mode).
928
 
929
## Graphical simulator
930
 
931
A separate program can be compiled, tested under [Linux][] and [Windows][].
932
This simulates the [Nexys3][] board peripherals that the SoC interfaces with,
933
but provides a graphical environment, unlike the command line utility. It is easier
934
to interact with the device and see what it is doing, but the debugging sessions
935
are a less controlled. It requires [free glut][].
936
 
937
* VGA output works
938
* UART or PS/2 input (selectable by pressing F11) comes from typing in the screen,
939
and in the case of the UART this is buffered with a FIFO.
940
* UART output gets written to a display box.
941
* There are four 7-Segment displays as on the original board.
942
* The switches and push buttons can take their input from either keyboard keys
943
or from mouse clicks.
944
* The LED indicators above the switches can be lit up.
945
 
946
Below is an image of a running session in the GUI simulator:
947
 
948
![H2 GUI Simulator](https://raw.githubusercontent.com/howerj/howerj.github.io/master/h2/forth-cpu-gui.png "Running GUI H2 SoC Simulator")
949
 
950
Building can be done with
951
 
952
        make gui
953
 
954
And running:
955
 
956
        make gui-run
957
 
958
Or:
959
 
960
        ./gui   h2.hex (on Linux)
961
        gui.exe h2.hex (on Windows)
962
 
963
The [Linux][] build should work when the development package for [free glut][]
964
is installed on your system, the [Windows][] build may require changes to the
965
build system and/or manual installation of the compiler, libraries and headers.
966
 
967
The current key map is:
968
 
969
        Up         Activate Up D-Pad Button, Release turns off
970
        Down       Activate Down D-Pad Button, Release turns off
971
        Left       Activate Left D-Pad Button, Release turns off
972
        Right      Activate Right D-Pad Button, Release turns off
973
        F1 - F8    Toggle Switch On/Off, F1 is left most, F8 Right Most
974
        F11        Toggle UART/PS2 Keyboard Input
975
        F12        Toggle Debugging Information
976
        Escape     Quit simulator
977
 
978
All other keyboard keys are redirected to the UART or PS/2 Keyboard input.
979
 
980
The Switches and D-Pad buttons can be clicked on to turn them on, the switches
981
turn on with left clicks and off with right clicks. The D-Pads buttons turn on
982
with a click on top of them and turn off with a key release anywhere on the
983
screen.
984
 
985
# VHDL Components
986
 
987
The VHDL components used in this system are designed to be reusable and
988
portable across different toolchains and vendors. Hardware components, like block
989
RAM, are inferred and not explicitly instantiated. The components are also made
990
to be as generic as possible, with most having selectable widths. This would be
991
taken to the extreme, but unfortunately many vendors still do not support the
992
VHDL-2008 standard.
993
 
994
| File     | License    | Author          | Description                         |
995
| -------- | ---------- | --------------- | ----------------------------------- |
996
| util.vhd | MIT        | Richard J Howe  | A collection of generic components  |
997
| h2.vhd   | MIT        | Richard J Howe  | H2 Forth CPU Core                   |
998
| vga.vhd  | LGPL 3.0   | Javier V García | Text Mode VGA 80x40 Display         |
999
| uart.vhd | Apache 2.0 | Peter A Bennett | UART, modified from original        |
1000
| kbd.vhd  | ???        | Scott Larson    | PS/2 Keyboard                       |
1001
| led.vhd  | MIT        | Richard J Howe  | LED 7-Segment + Dot Display Driver  |
1002
 
1003
 
1004
# eForth on the H2
1005
 
1006
The pseudo Forth like language used as an assembler is described above, the
1007
application that actually runs on the Forth core is in itself a Forth
1008
interpreter. This section describes the Forth interpreter that runs on H2 Core,
1009
it is contained within [h2.fth][].
1010
 
1011
TODO:
1012
- Fully implement the Forth interpreter
1013
- Describe and show its operation on here including memory layout, list of
1014
  words, word layout, ...
1015
 
1016
# Using Forth as a bootloader
1017
 
1018
A running Forth environment can be quite easily used as a bootloader with no
1019
further modification, a simple protocol for sending data and verification of it
1020
can be built using only Forth primitives - although it is not the most
1021
efficient use of bandwidth.
1022
 
1023
The sender can interrogate the running Forth environment over the serial link
1024
to determine the amount of space left in memory, and then populate it with an
1025
assembled binary.
1026
 
1027
The Forth words needed are:
1028
 
1029
 
1030
| Word    | Description           |
1031
| ------- | --------------------- |
1032
| .free   | show free space       |
1033
| cp      | compile pointer       |
1034
| pwd     | previous word pointer |
1035
| @       | load                  |
1036
| !       | store                 |
1037
| cr      | print new line        |
1038
| execute | execute               |
1039
| decimal | set decimal output    |
1040
| cells   | size of cell          |
1041
| .       | print number          |
1042
 
1043
 
1044
And of course numeric input, all of which are provided by this interpreter. The
1045
protocol is line oriented, the host with the program to transfer to the H2
1046
(called PC) sends a line of text and expects a reply from the H2 board (called
1047
H2),
1048
 
1049
        PC: decimal           ( set the H2 core to a known numeric output )
1050
        PC: .free cp @ . cr   ( query how much space is left, and where to put it )
1051
        H2: ADDR ADDR         ( H2 replies with both addresses )
1052
        PC: 1 cells . cr      ( PC queries size of cells )
1053
        H2: 2                 ( H2 responds, PC now knows to increment ADDR )
1054
        PC: NUM  ADDR !       ( PC write NUM to ADDR )
1055
        PC: ADDR @ . cr       ( optionally PC checks value )
1056
        H2: NUM               ( H2 responds with value stored at ADDR )
1057
        ...                   ( PC and H2 do this as often as necessary )
1058
        PC: ADDR pwd !        ( PC optionally updates previous word register )
1059
        PC  ADDR cp  !        ( PC optionally updated compile poiinter )
1060
        PC: ADDR execute      ( Begin execution of word )
1061
 
1062
The advantage of this "protocol" is that is human readable, and includes a
1063
debugger for the microcontroller it is operating on.
1064
 
1065
# A simple Forth block editor
1066
 
1067
TODO:
1068
- Add an SPI master with Rx/Tx Fifos to the SoC, which can then be use
1069
communicate with the memory on the [Nexys3][], this can then be used in
1070
conjunction with a simple block editor for a full Forth experience.
1071
- Talk about implementing a simple block editor in a few words of Forth.
1072
 
1073
1074
 
1075
# Coding standards
1076
 
1077
There are several languages used throughout this project, all of which are
1078
radically different from each other and require their own set of coding
1079
standards and style guides.
1080
 
1081
## VHDL
1082
 
1083
Common signal names:
1084
 
1085
        clk       - The system clock
1086
        rst       - A reset signal for the module
1087
        we        - Write Enable
1088
        re        - Read  Enable
1089
        di        - Data  In
1090
        din       - Data  In
1091
        do        - Data  Out
1092
        dout      - Data  Out
1093
        control   - Generally an input to a register, the documentation
1094
                    for the module will need to be consulted to find out
1095
                    what each bit means
1096
        signal_we - The write enable for 'signal'
1097
        signal_i  - This is an input signal
1098
        signal_o  - This is an output signal
1099
 
1100
Generally the use of the "\_i" and "\_o" suffixes are not used, modules are
1101
kept short and names chosen so their meaning is obvious. This rule might be
1102
revisited once the project grows.
1103
 
1104
Components should:
1105
 
1106
* Be as generic as possible
1107
* Use an asynchronous reset
1108
* If a feature of a module can be made optional, by either ignoring outputs
1109
or setting inputs to sensible values, it should be.
1110
* Where possible use a function, it is easy enough to turn a generic
1111
component into a module that can be synthesized but not the other way around.
1112
* Use "downto" not "to" when specify variable ranges.
1113
* Use assertions throughout the code with the correct severity level ('failure'
1114
for when something has seriously gone wrong or 'error' for debugging purposes)
1115
* Constrain types and generic parameters if possible, as an example, if a generic
1116
value should never be zero, use "positive" not "natural".
1117
* Try not to specify constants with fixed lengths where an expression using
1118
"others" can be used instead, for example:
1119
 
1120
1121
 
1122
        constant N: positive := 4;
1123
        signal a: std_logic_vector(N - 1 downto 0) := (others => '1');
1124
 
1125
 
1126
 
1127
Instead of:
1128
 
1129
 
1130
        signal a: std_logic_vector(3 downto 0) := x"F";
1131
 
1132
 
1133
 
1134
The style rules are as follows:
1135
 
1136
* All words, including keywords, are to be in lower case. An underscore
1137
will separate words in names.
1138
* Tabs are to be used to indent text, a tab spacing of 8 has been used when
1139
making the VHDL code
1140
* Do not repeat the name of a entity, component, function or architecture,
1141
there is little point of repeating this, it just means when a unit has to be
1142
renamed it has to be done in two places instead of one.
1143
* The ":" in definitions of signals belongs next to the signal name, not
1144
some arbitrary amount of spaces after it.
1145
* Group related signals.
1146
* Try to line up rows of signals
1147
* Trigger logic on the rising edge, and use the "rising\_edge" function not
1148
"clk'event and clk ='1'"
1149
* By and large, each warning produced by the synthesis tool should be
1150
justified, and there should be very few warnings in the entire project if any.
1151
* Do not use inferred latches.
1152
* Load data from a file instead of generating VHDL files that contain the data,
1153
synthesis tools can handle impure VHDL functions that can read the initial data
1154
(for a ROM or block RAM as an example) from textual files.
1155
 
1156
1157
 
1158
An example of the formatting guidelines, this describes a simple arbitrary
1159
width register:
1160
 
1161
        -- Lots of comments about what the unit does should go
1162
        -- here. Describe the waveforms, states and use ASCII
1163
        -- art where possible.
1164
        library ieee;
1165
        use ieee.std_logic_1164.all;
1166
        use ieee.numeric_std.all;    -- numeric_std not std_logic_arith
1167
 
1168
        entity reg is -- generic and port indented one tab, their parameters two
1169
                generic(
1170
                        N: positive); -- Generic parameters make for a generic component
1171
                port(
1172
                        clk: in  std_logic; -- standard signal names
1173
                        rst: in  std_logic; --
1174
                        we:  in  std_logic;
1175
                        di:  in  std_logic_vector(N - 1 downto 0);
1176
                        do:  out std_logic_vector(N - 1 downto 0)); -- note the position of ");
1177
        end entity; -- "end entity", not "end reg"
1178
 
1179
        architecture rtl of reg is
1180
                signal r_c, r_n: std_logic_vector(N - 1 downto 0) := (others => '0');
1181
        begin
1182
                do <= r_c;
1183
 
1184
                process(rst, clk)
1185
                begin
1186
                        if rst = '1' then -- asynchronous reset
1187
                                r_c <= (others => '0');
1188
                        elsif rising_edge(clk) then -- rising edge, not "clk'event and clk = '1'"
1189
                                r_c <= r_n;
1190
                        end if;
1191
                end process;
1192
 
1193
                process(r_c, di, we)
1194
                begin
1195
                        r_n <= r_c;
1196
                        if we = '1' then
1197
                                r_n <= di;
1198
                        end if;
1199
                end process;
1200
        end; -- "end" or "end architecture"
1201
 
1202
 
1203
## C
1204
 
1205
There is quite a lot of [C][] code used within this project, used to make a
1206
tool chain for the H2 core and to simulate the system. It follows a fairly
1207
strict coding style.
1208
 
1209
* Tabs are to be used instead of spaces, a tab width of 8 was used when coding
1210
  the C, if this causes any code to go off screen then there is a problem with
1211
  the code and not the tab length.
1212
* Generally the [K&R][] style is followed.
1213
* Line lengths should ideally be limited to 80 characters, but this is
1214
  definitely not an enforced limit.
1215
* Where there are two or more data structures that must be kept in sync, with a
1216
  one to one correspondence of elements, such as an enumeration and an array of
1217
  strings that each enumeration maps onto, an [X-Macro][] should be used to
1218
  keep the data in sync and to initialize the enumeration and array of strings.
1219
* Try to use only portable constructs and isolate the constructs that are not
1220
  portable.
1221
 
1222
1223
 
1224
There is nothing too surprising about the [C][] code within here, so some of
1225
the exceptions should be dealt with.
1226
 
1227
* Switch statements are formatted depending upon what the switch statement 'case'
1228
clauses look like, if they are a simple one liner such as an assignment or a
1229
mapping then the entire statement should occupy only a single line, for
1230
example:
1231
 
1232
1233
 
1234
        static const char *alu_op_to_string(uint16_t instruction)
1235
        {
1236
                /* notice also that the 'case' clauses are inline with the
1237
                 * switch selector */
1238
                switch(ALU_OP(instruction)) {
1239
                case ALU_OP_T:                  return "T";
1240
                case ALU_OP_N:                  return "N";
1241
                case ALU_OP_T_PLUS_N:           return "T+N";
1242
                case ALU_OP_T_AND_N:            return "T&N";
1243
                case ALU_OP_T_OR_N:             return "T|N";
1244
                case ALU_OP_T_XOR_N:            return "T^N";
1245
                case ALU_OP_T_INVERT:           return "~T";
1246
                case ALU_OP_T_EQUAL_N:          return "N=T";
1247
                case ALU_OP_N_LESS_T:           return "T>N";
1248
                case ALU_OP_N_RSHIFT_T:         return "N>>T";
1249
                case ALU_OP_T_DECREMENT:        return "T-1";
1250
                case ALU_OP_R:                  return "R";
1251
                case ALU_OP_T_LOAD:             return "[T]";
1252
                case ALU_OP_N_LSHIFT_T:         return "N<
1253
                case ALU_OP_DEPTH:              return "depth";
1254
                case ALU_OP_N_ULESS_T:          return "Tu>N";
1255
                case ALU_OP_ENABLE_INTERRUPTS:  return "seti";
1256
                case ALU_OP_INTERRUPTS_ENABLED: return "iset?";
1257
                case ALU_OP_RDEPTH:             return "rdepth";
1258
                case ALU_OP_T_EQUAL_0:          return "0=";
1259
                case ALU_OP_CPU_ID:             return "cpu-id";
1260
                default:                        return "unknown";
1261
                }
1262
        }
1263
 
1264
* Unnecessary braces are avoided:
1265
 
1266
1267
 
1268
        if(foo)
1269
                bar();
1270
        else
1271
                baz();
1272
 
1273
* "goto" can be used - it can be misused, but using it does not instantly make
1274
  code inscrutable contrary to popular belief.
1275
 
1276
## FORTH
1277
 
1278
The Forth in [h2.fth][] used to build an actual Forth system for the target
1279
core is not a proper Forth, but a compiler for a Forth like language, this
1280
idiosyncratic language has its own way of doing things. The workings of the
1281
language will not be described in this section, only the coding standards and
1282
style guide.
1283
 
1284
Either type of comment can be used, although "( )" comments are preferred,
1285
single line words should be short at only a few words, multi line words
1286
should be indented properly
1287
 
1288
        : 1+ 1 + ;
1289
        : negate invert 1+ ;
1290
        : dnegate not >r not 1 um+ r> + ; ( d -- d )
1291
 
1292
Tabs should be used for indentation and a stack comment present for long or
1293
complex words.
1294
 
1295
        : ?rx ( -- c -1 | 0 : read in a character of input from UART )
1296
                iUart @ 0x0100 and 0= ( the value to test goes on one line )
1297
                if                    ( the 'if' on another line )
1298
                        0x0400 oUart ! iUart @ 0xff and -1
1299
                else
1300
 
1301
                then ; ( ';' is part of the final statement )
1302
 
1303
        \ This word is too long for the stack comment and to be on a
1304
        \ single line
1305
        : parse ( c -- b u ;  )
1306
                >r tib >in @ + #tib @ >in @ - r> parser >in +! ;
1307
 
1308
Space is seriously limited on the target device at only 8192 cells (16KiB), so
1309
words kept as short as possible, and programs highly factored. Speed is not so
1310
much of an issue as the board and core runs at 100MHz.
1311
 
1312
Stack comments describe what values and Forth word takes and returns, it is
1313
good practice to make words that accept and return a fixed number of parameters
1314
but in certain circumstances it is advantages to return a variable number of
1315
arguments. The comments also describe the type of the arguments word accepts,
1316
the Forth kernel will do no checking on the data it gets however.
1317
 
1318
Stack comments should be added with the following scheme:
1319
 
1320
| Comment        | Meaning                             |
1321
|----------------|-------------------------------------|
1322
| a              | cell address                        |
1323
| n              | signed number                       |
1324
| u              | unsigned number                     |
1325
| b              | string address                      |
1326
| c              | single character                    |
1327
| d              | double width number (2 Cells)       |
1328
| f              | boolean flag (-1 = true, 0 = false) |
1329
| k              | block number                        |
1330
| cfa            | code field address of a word        |
1331
| nfa            | name field address of a word        |
1332
| pwd            | previous word address of a word     |
1333
| <string> | a parsing word                      |
1334
 
1335
Stack comments have the following format:
1336
 
1337
          Variable Stack Effects  Return stack Effects     Parsing    Description
1338
        ( arguments -- returns;   R: arguments -- returns;  : comment     )
1339
 
1340
Examples of words and their stack comments:
1341
 
1342
        dup   ( n -- n n : duplicate a number )
1343
        >r    ( n -- ; R: -- n : move a number to the return stack )
1344
        r>    ( -- n ; R: n -- : move a number from the return stack )
1345
        parse ( c -- b u;  : parse a word delimted by 'c' )
1346
        over  ( n1 n2 -- n1 n2 n1 : duplicate next on stack over top )
1347
 
1348
Words can have their arguments numbered to make it clearer what the effects
1349
are.
1350
 
1351
# To Do
1352
 
1353
* My [embed][] project, which was derived from the simulator and Forth for this
1354
project, has an improved version of Forth which could be reintegrated with
1355
this project. The [embed][] project features a metacompiler suitable for 16-bit
1356
systems like this one, it could be used in lieu of the Pseudo-Forth compiler.
1357
* Guide to reusing the VHDL in this project, and component listing
1358
* Turn the [h2.fth][] into a literate program file, describing how to build up
1359
a Forth system like in "The Zen of eForth by C. H. Ting".
1360
* Make a bootloader/program loader as a single, simple program
1361
* Make diagrams of the SoC layout, take GIFs and pictures of the simulators and
1362
the running board.
1363
* Make a javascript based simulator for the H2, perhaps with [emscripten][]
1364
* Move this file to "h2.md" and make a simpler "readme.md" with a short
1365
description and flashy GIFs
1366
* Add notes about picocom, and setting up the hardware:
1367
* Add a [Wishbone interface][] for each component
1368
* Put the project up on [opencores][]
1369
* It should be possible to turn [h2.c][] into a Forth interpreter usable in
1370
a hosted environment. Some of the remaining instructions could be used for
1371
function calls and floating point operations and the "uint16\_t" would have to
1372
be changed to "uintptr\_t". As the interpreter is so small a Forth to "C"
1373
compiler could just spit out a copy of the interpreter. It should make for
1374
a very compact system.
1375
* Spin off the VT100 VHDL code into a separate project, and the C code in the
1376
simulator into a simple terminal emulator for Unixen.
1377
* Add some example games, any of the following: Space Invaders, Tetris, Pong,
1378
Minesweeper, Sokoban, Sudoku, Hack, 2048, Breakout, Brain F\*ck, Conway's
1379
Game of Life, and other terminal based games could be added, see
1380
 for a
1381
minimal version of Nethack, and  for a
1382
cool 1 dimensional game.
1383
* Other programs like a compressor, decompressor, ARC4, data base function based
1384
around blocks, and a meta compiler (removing the need for the C assembler),
1385
could be added.
1386
 
1387
 
1388
 
1389
1390
 
1391
        picocom --omap delbs -b 115200 -e b /dev/ttyUSB1
1392
 
1393
# Resources
1394
 
1395
* 
1396
* 
1397
* 
1398
* 
1399
* 
1400
* 
1401
* 
1402
* 
1403
 
1404
[javascript]: https://www.javascript.com/
1405
[emscripten]: https://github.com/kripken/emscripten
1406
[DEBUG.COM]: https://en.wikipedia.org/wiki/Debug_%28command%29
1407
[DOS]: https://en.wikipedia.org/wiki/DOS
1408
[h2.c]: h2.c
1409
[h2.fth]: h2.fth
1410
[tb.vhd]: tb.vhd
1411
[uart.vhd]: uart.vhd
1412
[top.ucf]: top.ucf
1413
[font.bin]: font.bin
1414
[text.bin]: text.bin
1415
[J1]: http://www.excamera.com/sphinx/fpga-j1.html
1416
[J1 PDF]: http://excamera.com/files/j1.pdf
1417
[PL/0]: https://github.com/howerj/pl0
1418
[libforth]: https://github.com/howerj/libforth/
1419
[MIT]: https://en.wikipedia.org/wiki/MIT_License
1420
[LGPL]: https://www.gnu.org/licenses/lgpl-3.0.en.html
1421
[VHDL]: https://en.wikipedia.org/wiki/VHDL
1422
[Verilog]: https://en.wikipedia.org/wiki/Verilog
1423
[UART]: https://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter
1424
[FORTH]: https://en.wikipedia.org/wiki/Forth_%28programming_language%29
1425
[Nexys3]: http://store.digilentinc.com/nexys-3-spartan-6-fpga-trainer-board-limited-time-see-nexys4-ddr/
1426
[Make]: https://en.wikipedia.org/wiki/Make_%28software%29
1427
[C]: https://en.wikipedia.org/wiki/C_%28programming_language%29
1428
[Debian]: https://en.wikipedia.org/wiki/Debian
1429
[Linux]: https://en.wikipedia.org/wiki/Linux
1430
[GCC]: https://en.wikipedia.org/wiki/GNU_Compiler_Collection
1431
[Xilinx ISE]: https://www.xilinx.com/products/design-tools/ise-design-suite.html
1432
[Xilinx]: https://www.xilinx.com
1433
[GHDL]: http://ghdl.free.fr/
1434
[GTKWave]: http://gtkwave.sourceforge.net/
1435
[C99]: https://en.wikipedia.org/wiki/C99
1436
[tcl]: https://en.wikipedia.org/wiki/Tcl
1437
[Wishbone interface]: https://en.wikipedia.org/wiki/Wishbone_%28computer_bus%29
1438
[D-Pad]: https://en.wikipedia.org/wiki/D-pad
1439
[FIFO]: https://en.wikipedia.org/wiki/FIFO_%28computing_and_electronics%29
1440
[VGA]: https://en.wikipedia.org/wiki/Video_Graphics_Array
1441
[PS/2]: https://en.wikipedia.org/wiki/PS/2_port
1442
[LED]: https://en.wikipedia.org/wiki/Light-emitting_diode
1443
[8 Segment LED Display]: https://en.wikipedia.org/wiki/Seven-segment_display
1444
[ISO 8859-1 (Latin-1)]: https://cs.stanford.edu/people/miles/iso8859.html
1445
[Spartan 6]: https://www.xilinx.com/products/silicon-devices/fpga/spartan-6.html
1446
[FPGA]: https://en.wikipedia.org/wiki/Field-programmable_gate_array
1447
[ASCII]: https://en.wikipedia.org/wiki/ASCII
1448
[free glut]: http://freeglut.sourceforge.net/
1449
[pthreads]: https://en.wikipedia.org/wiki/POSIX_Threads
1450
[LFSR]: https://en.wikipedia.org/wiki/Linear-feedback_shift_register
1451
[freeglut]: http://freeglut.sourceforge.net/
1452
[EBNF]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form
1453
[K&R]: https://en.wikipedia.org/wiki/Indent_style#K.26R
1454
[X-Macro]: https://en.wikipedia.org/wiki/X_Macro
1455
[Windows]: https://en.wikipedia.org/wiki/Windows_7
1456
[pandoc]: https://pandoc.org
1457
[picocom]: https://github.com/npat-efault/picocom
1458
[Gforth]: https://www.gnu.org/software/gforth/
1459
[opencores]: https://opencores.org
1460
[VT100]: https://en.wikipedia.org/wiki/VT100
1461
[embed]: https://github.com/howerj/embed
1462
1469
 
1470

powered by: WebSVN 2.1.0

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