README 3.77 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1
2
3
4
5
6
The INSTR16 project started with the question: Is it possible to
design a good instruction set with 16 general registers, and
16-bit opcodes?

I now think the answer is yes (but "good" is a bit subjective, of
course). The project has grown a bit beyond an afternoon hack, to the
Niels Möller's avatar
Niels Möller committed
7
point where I have a partial Verilog implementation of the cpu.
Niels Möller's avatar
Niels Möller committed
8
9
10

The instruction set features 16 64-bit registers, 8 of which can also
be used for floating point operations. There are very few
Niels Möller's avatar
Niels Möller committed
11
12
13
14
15
16
17
18
19
20
21
22
23
three-register instructions, most notably indexed load and store and
long shift. Most instructions have a source and destination register.
All memory accesses are full 64 bits, with some tricks to help
accessing individual fields of 8, 16 or 32 bits, assuming they are
naturally aligned. Immediate constants, and addressing offsets, are of
limited size. When a constant or offset doesn't fit in the immediate
field in an instruction, additional prefix instructions can be used to
build larger constants. (Sure, in some sense this makes opcodes
variable size rather than fixed to 16 bits. But the prefix
instructions are decoded independently. The closest alternative is
handle all but very small constants by loading a 64-bit value into a
register, using pc-relative addressing, like the ARM ldc instruction.
But using a prefix instruction is much more compact for the common
Niels Möller's avatar
Niels Möller committed
24
case of smallish constants).
Niels Möller's avatar
Niels Möller committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

The top directory contains instr16.tex, which is the main
specification, and some other text files with partly out-of-date
working notes.

The assembler/ directory contains a primitive assembler. There's no
linker and no real object file format. The .o files generated by the
assembler are raw machine code to be loaded at address 0 (the initial
pc). To organize assembly code in multiple files, enable m4
preprocessing with -m and use m4 include. The assembler syntax is a
bit inspired by ARM.

The simulator/ directory contains a simulator which is intended to
implement all instructions in the spec, plus halt (0xffff) and bkpt
(0xfffe). The simulator takes an object file, generated by the
assembler, as the first argument, and optionally initial values for
Niels Möller's avatar
Niels Möller committed
41
42
the registers. It also simulates memory mapped i/o registers for
terminal input and output.
Niels Möller's avatar
Niels Möller committed
43

Niels Möller's avatar
Niels Möller committed
44
45
46
47
48
49
50
51
52
53
54
55
The hw/ directory contains a Verilog implementation of the processor
(except floating point arithmetic), and some arithmetic modules I have
been playing with. The primary modules are instr-decode.vl and cpu.vl,
the simulator driver (including some RAM and i/o) is implemented in
main.vl.

I use Icarus Verilog for simulation, and it is likely that the very
latest development version is required. The cpu is also synthesizable
using yosys. At the time of this writing, the result is about 10% too
large to fit an iCE40-HX8K. See http://www.clifford.at/icestorm/ for
information about this fpga family and the free software tools to
program it.
Niels Möller's avatar
Niels Möller committed
56

Niels Möller's avatar
Niels Möller committed
57
Tests are collected in the testsuite/ directory.
Niels Möller's avatar
Niels Möller committed
58
59
60

To get started, try

Niels Möller's avatar
Niels Möller committed
61
  make
62
  make check
Niels Möller's avatar
Niels Möller committed
63
64
65
  ./simulator/instr16 examples/hello.o
  => Hello world.
  ./hw/main +quiet=1 +img=examples/hello.hex
Niels Möller's avatar
Niels Möller committed
66
67
  => Hello world.

68
For a more elaborate example, the (somewhat mis-named) program
69
putd-test.s converts the integer in r0 to ASCII using the base in r1.
Niels Möller's avatar
Niels Möller committed
70

Niels Möller's avatar
Niels Möller committed
71
  ./simulator/instr16 examples/putd-test.o
Niels Möller's avatar
Niels Möller committed
72
  => 0
Niels Möller's avatar
Niels Möller committed
73
  ./simulator/instr16 examples/putd-test.o 17
Niels Möller's avatar
Niels Möller committed
74
  => 17
Niels Möller's avatar
Niels Möller committed
75
  ./simulator/instr16 examples/putd-test.o 17 2
Niels Möller's avatar
Niels Möller committed
76
  => 10001
Niels Möller's avatar
Niels Möller committed
77
  ./simulator/instr16 examples/putd-test.o 17 3
78
  => 122
Niels Möller's avatar
Niels Möller committed
79
  ./simulator/instr16 examples/putd-test.o 17 17
80
81
  => 10

82
83
84
85
86
87
88
89
To try out the verilog implementation, first install Icarus verilog,
for simulation. To synthesize for ice40, these tools are needed (in
suggested install order):

  Icestorm
  Yosys
  next-pnr

90
91
Happy hacking,
Niels Möller, <nisse@lysator.liu.se>
92
93
94

 LocalWords: opcodes Verilog VHDL pc preprocessing testsuite Niels ldc
 LocalWords: putd tex bkpt Möller