OpenCores
URL https://opencores.org/ocsvn/tinycpu/tinycpu/trunk

Subversion Repositories tinycpu

[/] [tinycpu/] [trunk/] [docs/] [design.md.txt] - Blame information for rev 23

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

Line No. Rev Author Line
1 3 earlz
This is the design of TinyCPU. It's goals are as follows:
2
 
3
1. 8-bit registers and operations (8 bit processor)
4
2. 16-bit address bus
5
3. fixed 16-bit instruction length
6
4. use a small amount of "rich" instructions to do powerful things
7
5. 1 instruction per clock cycle
8
 
9 16 earlz
Relative moves:
10
In order to provide uesfulness to the segment-carryover feature, there are a few options for moving a "relative" amount to a register, including IP and SP
11
A relative move differs in most of the opcodes in that the relative factor is treated as a signed value.
12
so for instance, a
13
mov r0,50
14
mov_relative r0, -10
15
 
16
in the ned, r0 will end up being 40. Although this feature won't see much use in general registers, IP and SP are special because of the option of using the
17
segment-carryover feature. This means that SP and IP, while being 8-bit registers, can function very similar to a 16-bit register, enabling full usage of the available address space.
18
 
19 3 earlz
Register list:
20 5 earlz
r0-r5 general purpose registers
21
sp stack pointer (represented as r6)
22 4 earlz
ip instruction pointer register (represented as r7)
23 3 earlz
cs, ds, es, ss segment registers (code segment, data segment, extra segment, stack segment)
24
tr truth register for conditionals
25
 
26
general opcode format
27
 
28
first byte:
29
first 4 bits: actual instruction
30 4 earlz
next 3 bits: (target) register
31
last 1 bit: conditional
32 3 earlz
 
33 4 earlz
second byte:
34
first 1 bit: second portion of condition (if not immediate) (1 for only if false)
35 5 earlz
next 1 bit: use extra segment
36 16 earlz
next 3 bits: other register. If not 3rd register, top bit specifies which register bank, others unused
37 4 earlz
last 3 bits: extra opcode information or third register. such as for ADD it could be target=source+third_register
38 3 earlz
 
39
...or second byte is immediate value
40
 
41
For opcodes requiring 3 registers but without room, the target opcode is assume to be the second operation. Such as for AND, target=source AND target
42
 
43
short list of instructions: (not final, still planning)
44 4 earlz
immediates:
45
1. move reg, immediate
46
2. move [reg], immediate
47
3. push and move reg, immediate (or call immediate)
48 19 earlz
4. move (relative) reg, immediate
49 4 earlz
 
50 19 earlz
mini-group 5. Root opcode is 5, register is to tell which opcode( up to 8). No register room, only immediate
51
push immedate
52
XX
53
XX
54
XX
55
XX
56
XX
57
XX
58
XX
59 16 earlz
 
60 19 earlz
 
61 4 earlz
groups: (limited to 2 registers and no immediates. each group has 8 opcodes)
62
group 1:
63
move(store) [reg],reg
64
move(load) reg,[reg]
65
out reg1,reg2 (output to port reg1 value reg2)
66
in reg1,reg2 (input from port reg2 and store in reg1)
67 19 earlz
XX
68
XX
69 5 earlz
move segmentreg,reg
70
move reg,segmentreg
71 4 earlz
 
72
group 2:
73
and reg1,reg2 (reg1=reg1 and reg2)
74
or reg, reg
75
xor reg,reg
76
not reg1,reg2 (reg1=not reg2)
77
left shift reg,reg
78
right shift reg,reg
79
rotate right reg,reg
80
rotate left reg,reg
81
 
82
group 3: compares
83
is greater than reg1,reg2 (TR=reg1>reg2)
84
is greater or equal to reg,reg
85
is less than reg,reg
86
is less than or equal to reg,reg
87
is equal to reg,reg
88
is not equal to reg,reg
89 5 earlz
equals 0 reg
90
not equals 0 reg
91 4 earlz
 
92 5 earlz
group 4:
93
push segmentreg
94
pop segmentreg
95
push and move reg, reg (or call reg)
96
exchange reg,reg
97
exchange reg,seg
98 19 earlz
XX
99
XX
100 4 earlz
 
101 5 earlz
group 5:
102 19 earlz
XX
103
XX
104 5 earlz
far jmp reg1, reg2 (CS=reg1 and IP=reg2)
105
far call reg1,reg2
106
far jmp [reg] (first byte is CS, second byte is IP)
107
push extended segmentreg, reg (equivalent to push seg; push reg)
108
pop extended segmentreg, reg (equivalent to pop reg; pop seg)
109
reset processor (will completely reset the processor to starting state, but not RAM or anything else)
110 4 earlz
 
111 14 earlz
group 6:
112 16 earlz
set default register bank to 0 (can be condensed to 1 opcode)
113
set default register bank to 1
114 14 earlz
push extended reg, reg
115
pop extended reg,reg
116 16 earlz
enable carryover seg
117 17 earlz
disable carryover seg
118 16 earlz
mov relative reg, reg
119
exchange reg, reg
120 4 earlz
 
121 19 earlz
super group: Super groups only have room for 1 register argument. Each subgroup has 8 opcodes, capable of 8 subgroups.
122
subgroup 0:
123
push reg
124
pop reg
125
set TR
126
reset TR
127
increment reg
128
decrement reg
129
set register bank 0
130
set register bank 1
131
subgroup 1:
132
enable carryover seg
133
disable carryover seg
134
 
135
 
136
 
137 4 earlz
3 register instructions:
138
1. add reg1, reg2, reg3 (reg1=reg2+reg3)
139
2. sub reg1, reg2, reg3
140
 
141
 
142 19 earlz
opcodes used: 14 of 16. 2 more opcodes available. Decide what to do with the room later.
143 4 earlz
 
144 17 earlz
Possible canidates for opcode compression include
145 19 earlz
* equals 0 and not equals 0 (room for 7 sub-opcodes each) (not doing that because it'd screw with the easy ALU code
146 4 earlz
 
147 5 earlz
 
148 3 earlz
 
149
 
150
conditionals
151 4 earlz
 
152
1 -- only if true
153
for only if false, there should basically be another compare or if applicable an always afterwards
154 3 earlz
 
155 5 earlz
 
156
limitations that shouldn't be passed with instructions
157
* Doing 2 memory references
158
* pushing a memory reference (equates to 2 memory references)
159
 
160 19 earlz
Note it is possible however to read and write 16bits at one time to the memory to consecutive addresses that are 16-bit aligned.
161 5 earlz
 
162
 
163
segments:
164
DS is used in all "normal" memory references
165
SS is used in all push and pop instructions
166
ES is used when the ExtraSegment bit is set for either push/pop or normal memory references
167
CS is only used for fetching instructions
168 14 earlz
 
169 16 earlz
Segment carryover:
170
In order to overcome the limitations of only having a 256 byte segment, there is a workaround option to "pretend" that IP is a 16 bit register.
171
When CS carryover is enabled, when IP rollover from 255 to 0 or whatever, CS will be incremented. This makes it so that if you start at address 0:0.
172
you can continue as far as needed into the address space without having to do ugly far jumps at each of the borders.
173 17 earlz
Carryover can only be done on CS and SS. The required circuitry is not implemented for DS or ES due to an extreme level of complexity required for it, also
174
it would only lead to unncessarily complex code
175 14 earlz
 
176 17 earlz
Also of note is that `move relative` implements a "carryover" component. This component will work on either IP or SP, and uses CS and SS respectively.
177
If used on other registers, there will be no carry over functionality, though it can be used as an easy way to add or subtract an immediate from a register.
178 16 earlz
 
179 17 earlz
 
180
 
181 14 earlz
States needed:
182
0. reset
183
1. decode current instruction (All without memory capable within 1 clock cycle)
184
2. increment IP(and SP if needed) and fetch next instruction
185
3. Write 1 register to memory
186
4. Read 1 register from memory
187
5. Write 2 registers to memory
188
6. Read 2 registers from memory
189
7. Write 1 register to memory and setup increment of sp
190
8. Write 2 registers to memory and setup double increment of sp
191
9. Read 1 register from memory and setup decrement of sp
192
10. Read 2 registers from memory and setup double decrement of sp
193
11.
194
 
195
 
196
 
197
registerfile map:
198
0000: general r0
199
0001: general r1
200
0010: general r2
201
0011: general r3
202
0100: general r4
203
0101: general r5
204
0110: SP (r6)
205
0111: IP (r7)
206
1000: second bank r0
207
1001: second bank r1
208
1010: second bank r2
209
1011: second bank r3
210
1100: CS
211
1101: DS
212
1110: ES
213
1111: SS
214
 
215
Banking works like if(regnumber(2) = '0') then regnumber(3)=regbank; end if;
216
 
217
 
218
ALU operations
219
00000 and reg1,reg2 (reg1=reg1 and reg2)
220
00001 or reg, reg
221
00010 xor reg,reg
222
00011 not reg1,reg2 (reg1=not reg2)
223
00100 left shift reg,reg (logical)
224
00101 right shift reg,reg (logical)
225
00110 rotate right reg,reg
226
00111 rotate left reg,reg
227
 
228
01000 is greater than reg1,reg2 (TR=reg1>reg2)
229
01001 is greater or equal to reg,reg
230
01010 is less than reg,reg
231
01011 is less than or equal to reg,reg
232
01100 is equal to reg,reg
233
01101 is not equal to reg,reg
234
01110 equals 0 reg
235
01111 not equals 0 reg
236
 
237
10000 Set TR
238
10001 Reset TR
239
10011 Increment
240
10010 Decrement
241
10100 Add
242
10101 Subtract
243
 
244 19 earlz
 
245
 
246
Alignment restrictions:
247
In general, their is very few times that a full 16-bit read or 16-bit write is done. These are the times:
248
 
249
* Extended push
250
* Extended pop
251
* instruction fetch
252
 
253
Because of this, and because I want for 2 clock cycles to be the longest instruction, I must place some alignment restrictions on the CPU
254
So, IP must be aligned to a 16-bit address (must be an even number). And SP must also be aligned to a 16-bit address.
255
Though I don't plan on putting any "real" restriction to setting it to an odd address, nothing will actually work right.
256
 
257
Stack Details:
258
Because of the need for 16-bit writes and reads of the stack, even though we're usually only using 8-bit values, we end up pushing 2 bytes at one time always.
259
Stack is oppositely done from the 8086. push X will move X to SS:SP and then increment SP by 2.
260
Let's take an example program:
261
--SS is 0
262
mov sp, 10
263
push 0xff
264
 
265
after this, 0x00FF will be moved to SS:SP (0x0010) and then sp will be incremented by 2. If we push an 8-bit value, the value is put in the least-significant byte, and the MSB is 0
266
 
267
 
268
 
269
On Reset:
270
 
271
On reset, all general registers are set to 0
272
CS is set to 1, IP is set to 0. SS is set to 2 and SP is set to 0.
273
Carryover is set on CS and not set on SS. DS and ES is 0. TR is false.
274
Register bank 0 is selected.
275
 
276 21 earlz
Electrical operation:
277
On power-on, RESET should be high for at least 2 clock cycles. HOLD can optionally be high as well after these two clock cycles.
278
When HOLD is no longer needed, it should just be turned low and an extra clock cycle should be waited on for it to return to RESET state
279
When RESET is held low, the processor will execute. It takes 3 clock cycles for the processor to "catch up" to actually executing instructions
280 19 earlz
 
281
 
282
 
283 21 earlz
 
284
 
285
 
286 19 earlz
Implemented opcode list:
287
legend:
288
r = register choice
289
C = conditional portion
290
s = segment register choice
291
i = immediate data
292
 
293
0000 rrrC iiii iiii
294
mov reg, immediate
295
 
296
 
297
 
298
 
299
 
300
 
301
 

powered by: WebSVN 2.1.0

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