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

Subversion Repositories tinycpu

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

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 30 earlz
 
10
BIG CHANGE:
11
So, apparently making a single-cycle CPU is extremely hard... so instead, we'll be striving for a 2-cycle CPU.
12
Usual cycles:
13
1-cycle: mov, jmp, etc general data movement
14
2-cycle: ALU operations
15
1-cycle with memory wait(so really 2 cycle): all instructions that reference memory
16
 
17
 
18 16 earlz
Relative moves:
19
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
20
A relative move differs in most of the opcodes in that the relative factor is treated as a signed value.
21
so for instance, a
22
mov r0,50
23
mov_relative r0, -10
24
 
25
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
26
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.
27
 
28 3 earlz
Register list:
29 5 earlz
r0-r5 general purpose registers
30
sp stack pointer (represented as r6)
31 4 earlz
ip instruction pointer register (represented as r7)
32 3 earlz
cs, ds, es, ss segment registers (code segment, data segment, extra segment, stack segment)
33
tr truth register for conditionals
34
 
35
general opcode format
36
 
37
first byte:
38
first 4 bits: actual instruction
39 4 earlz
next 3 bits: (target) register
40
last 1 bit: conditional
41 3 earlz
 
42 4 earlz
second byte:
43
first 1 bit: second portion of condition (if not immediate) (1 for only if false)
44 5 earlz
next 1 bit: use extra segment
45 25 earlz
next 3 bits: other register. If not 3rd register
46 4 earlz
last 3 bits: extra opcode information or third register. such as for ADD it could be target=source+third_register
47 3 earlz
 
48
...or second byte is immediate value
49
 
50
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
51
 
52
short list of instructions: (not final, still planning)
53 4 earlz
immediates:
54
1. move reg, immediate
55
2. move [reg], immediate
56
3. push and move reg, immediate (or call immediate)
57 19 earlz
4. move (relative) reg, immediate
58 4 earlz
 
59 19 earlz
mini-group 5. Root opcode is 5, register is to tell which opcode( up to 8). No register room, only immediate
60
push immedate
61
XX
62
XX
63
XX
64
XX
65
XX
66
XX
67
XX
68 16 earlz
 
69 19 earlz
 
70 4 earlz
groups: (limited to 2 registers and no immediates. each group has 8 opcodes)
71
group 1:
72
move(store) [reg],reg
73
move(load) reg,[reg]
74
out reg1,reg2 (output to port reg1 value reg2)
75
in reg1,reg2 (input from port reg2 and store in reg1)
76 19 earlz
XX
77
XX
78 5 earlz
move segmentreg,reg
79
move reg,segmentreg
80 4 earlz
 
81
group 2:
82
and reg1,reg2 (reg1=reg1 and reg2)
83
or reg, reg
84
xor reg,reg
85
not reg1,reg2 (reg1=not reg2)
86
left shift reg,reg
87
right shift reg,reg
88
rotate right reg,reg
89
rotate left reg,reg
90
 
91
group 3: compares
92
is greater than reg1,reg2 (TR=reg1>reg2)
93
is greater or equal to reg,reg
94
is less than reg,reg
95
is less than or equal to reg,reg
96
is equal to reg,reg
97
is not equal to reg,reg
98 5 earlz
equals 0 reg
99
not equals 0 reg
100 4 earlz
 
101 5 earlz
group 4:
102
push segmentreg
103
pop segmentreg
104
push and move reg, reg (or call reg)
105
exchange reg,reg
106
exchange reg,seg
107 19 earlz
XX
108
XX
109 4 earlz
 
110 5 earlz
group 5:
111 19 earlz
XX
112
XX
113 5 earlz
far jmp reg1, reg2 (CS=reg1 and IP=reg2)
114
far call reg1,reg2
115
far jmp [reg] (first byte is CS, second byte is IP)
116
push extended segmentreg, reg (equivalent to push seg; push reg)
117
pop extended segmentreg, reg (equivalent to pop reg; pop seg)
118
reset processor (will completely reset the processor to starting state, but not RAM or anything else)
119 4 earlz
 
120 14 earlz
group 6:
121 16 earlz
set default register bank to 0 (can be condensed to 1 opcode)
122
set default register bank to 1
123 14 earlz
push extended reg, reg
124
pop extended reg,reg
125 16 earlz
enable carryover seg
126 17 earlz
disable carryover seg
127 16 earlz
mov relative reg, reg
128
exchange reg, reg
129 4 earlz
 
130 19 earlz
super group: Super groups only have room for 1 register argument. Each subgroup has 8 opcodes, capable of 8 subgroups.
131
subgroup 0:
132
push reg
133
pop reg
134
set TR
135
reset TR
136
increment reg
137
decrement reg
138
set register bank 0
139
set register bank 1
140
subgroup 1:
141
enable carryover seg
142
disable carryover seg
143
 
144
 
145
 
146 4 earlz
3 register instructions:
147
1. add reg1, reg2, reg3 (reg1=reg2+reg3)
148
2. sub reg1, reg2, reg3
149
 
150
 
151 19 earlz
opcodes used: 14 of 16. 2 more opcodes available. Decide what to do with the room later.
152 4 earlz
 
153 17 earlz
Possible canidates for opcode compression include
154 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
155 4 earlz
 
156 5 earlz
 
157 3 earlz
 
158
 
159
conditionals
160 4 earlz
 
161
1 -- only if true
162
for only if false, there should basically be another compare or if applicable an always afterwards
163 3 earlz
 
164 5 earlz
 
165
limitations that shouldn't be passed with instructions
166
* Doing 2 memory references
167
* pushing a memory reference (equates to 2 memory references)
168
 
169 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.
170 5 earlz
 
171
 
172
segments:
173
DS is used in all "normal" memory references
174
SS is used in all push and pop instructions
175
ES is used when the ExtraSegment bit is set for either push/pop or normal memory references
176
CS is only used for fetching instructions
177 14 earlz
 
178 16 earlz
Segment carryover:
179
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.
180
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.
181
you can continue as far as needed into the address space without having to do ugly far jumps at each of the borders.
182 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
183
it would only lead to unncessarily complex code
184 14 earlz
 
185 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.
186
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.
187 16 earlz
 
188 17 earlz
 
189
 
190 14 earlz
States needed:
191
0. reset
192
1. decode current instruction (All without memory capable within 1 clock cycle)
193
2. increment IP(and SP if needed) and fetch next instruction
194
3. Write 1 register to memory
195
4. Read 1 register from memory
196
5. Write 2 registers to memory
197
6. Read 2 registers from memory
198
7. Write 1 register to memory and setup increment of sp
199
8. Write 2 registers to memory and setup double increment of sp
200
9. Read 1 register from memory and setup decrement of sp
201
10. Read 2 registers from memory and setup double decrement of sp
202
11.
203
 
204
 
205
 
206
registerfile map:
207
0000: general r0
208
0001: general r1
209
0010: general r2
210
0011: general r3
211
0100: general r4
212
0101: general r5
213
0110: SP (r6)
214
0111: IP (r7)
215
1000: second bank r0
216
1001: second bank r1
217
1010: second bank r2
218
1011: second bank r3
219
1100: CS
220
1101: DS
221
1110: ES
222
1111: SS
223
 
224
Banking works like if(regnumber(2) = '0') then regnumber(3)=regbank; end if;
225
 
226
 
227
ALU operations
228
00000 and reg1,reg2 (reg1=reg1 and reg2)
229
00001 or reg, reg
230
00010 xor reg,reg
231
00011 not reg1,reg2 (reg1=not reg2)
232
00100 left shift reg,reg (logical)
233
00101 right shift reg,reg (logical)
234
00110 rotate right reg,reg
235
00111 rotate left reg,reg
236
 
237
01000 is greater than reg1,reg2 (TR=reg1>reg2)
238
01001 is greater or equal to reg,reg
239
01010 is less than reg,reg
240
01011 is less than or equal to reg,reg
241
01100 is equal to reg,reg
242
01101 is not equal to reg,reg
243
01110 equals 0 reg
244
01111 not equals 0 reg
245
 
246
10000 Set TR
247
10001 Reset TR
248
10011 Increment
249
10010 Decrement
250
10100 Add
251
10101 Subtract
252
 
253 19 earlz
 
254
 
255
Alignment restrictions:
256
In general, their is very few times that a full 16-bit read or 16-bit write is done. These are the times:
257
 
258
* Extended push
259
* Extended pop
260
* instruction fetch
261
 
262
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
263
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.
264
Though I don't plan on putting any "real" restriction to setting it to an odd address, nothing will actually work right.
265
 
266
Stack Details:
267
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.
268
Stack is oppositely done from the 8086. push X will move X to SS:SP and then increment SP by 2.
269
Let's take an example program:
270
--SS is 0
271
mov sp, 10
272
push 0xff
273
 
274
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
275
 
276
 
277
 
278
On Reset:
279
 
280
On reset, all general registers are set to 0
281
CS is set to 1, IP is set to 0. SS is set to 2 and SP is set to 0.
282
Carryover is set on CS and not set on SS. DS and ES is 0. TR is false.
283
Register bank 0 is selected.
284
 
285 21 earlz
Electrical operation:
286
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.
287
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
288
When RESET is held low, the processor will execute. It takes 3 clock cycles for the processor to "catch up" to actually executing instructions
289 19 earlz
 
290
 
291
 
292 34 earlz
Register order:
293
The order of registers is read from left to right with left being the most significant bit of the 16-bit opcode.
294
So for instance,
295
0101_*000*0_0*111*_0010 is `mov [r0], IP/r7`. The register portions of the opcode are surrounded by astericks
296 21 earlz
 
297
 
298 19 earlz
Implemented opcode list:
299
legend:
300
r = register choice
301 29 earlz
R = register choice or opcode choice for sub groups
302 19 earlz
C = conditional portion
303
s = segment register choice
304
i = immediate data
305 27 earlz
N = not used
306
o = opcode choice (for groups)
307 34 earlz
_ = space for readability
308 19 earlz
 
309 34 earlz
0000_rrrC_iiii_iiii
310 19 earlz
mov reg, immediate
311
 
312 34 earlz
0001_rrrC_iiii_iiii
313 27 earlz
mov [reg], immediate
314 19 earlz
 
315 27 earlz
group 3 comparions
316 34 earlz
0011_rrrC_Crrr_Nooo
317 27 earlz
opcode choices
318
000: is greater than reg1,reg2 (TR=reg1>reg2)
319
001: is greater or equal to reg,reg
320
010: is less than reg,reg
321
011: is less than or equal to reg,reg
322
100: is equal to reg,reg
323
101: is not equal to reg,reg
324
110: equals 0 reg
325
111: not equals 0 reg
326 19 earlz
 
327 27 earlz
group 4 bitwise
328 34 earlz
0100_rrrC_Crrr_Nooo
329 27 earlz
opcode choices
330
000: and reg1,reg2 (reg1=reg1 and reg2)
331
001: or reg, reg
332
010: xor reg,reg
333
011: not reg1,reg2 (reg1=not reg2)
334
100: left shift reg,reg
335
101: right shift reg,reg
336
110: rotate right reg,reg
337
111: rotate left reg,reg
338 19 earlz
 
339 29 earlz
group 5 misc
340 34 earlz
0101_rrrC_CRRR_sooo
341 29 earlz
opcode choices:
342
000: subgroup 5-0
343
  RRR choices:
344
  000: push reg
345
  001: pop reg
346 33 earlz
001: mov reg, reg
347 34 earlz
010: mov reg, [reg]
348
011: mov [reg], reg
349 19 earlz
 

powered by: WebSVN 2.1.0

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