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

Subversion Repositories tinycpu

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

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

powered by: WebSVN 2.1.0

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