§ Описание пинов
- clock — тактовая частота, обычно 25 мгц
- reset_n — сброс процессора на 0
- ce — если 1, такты включены (chip enabled)
- in — входящие данные
- address — 16-битный адрес (в том числе порт)
- we — запись в память
- pw — запись в порт
- rd — чтение из порта
- out — значение на запись в память или порт
§ Ядро процессора
Процессор содержит почти все 256 инструкции, кроме отключенных EXX и EX AF,AF', если раскомментировать, то они активируются. Нет префиксов IX,IY, битовых префиксов и ED-инструкции.
1
2
3
4
5
6module kr580
7(
8
9 input clock,
10 input reset_n,
11 input ce,
12 input [ 7:0] in,
13 output [15:0] address,
14 output reg we,
15 output reg pw,
16 output reg rd,
17 output reg [ 7:0] out,
18
19
20 input wire irq
21);
22
23
24localparam
25 ALU_ADD = 0, ALU_ADC = 1, ALU_SUB = 2, ALU_SBC = 3,
26 ALU_AND = 4, ALU_XOR = 5, ALU_OR = 6, ALU_CP = 7,
27 ALU_RLC = 0, ALU_RRC = 1, ALU_RL = 2, ALU_RR = 3,
28 ALU_DAA = 4, ALU_CPL = 5, ALU_SCF = 6, ALU_CCF = 7;
29
30
31localparam
32 REG_B = 0, REG_C = 1, REG_D = 2, REG_E = 3,
33 REG_H = 4, REG_L = 5, REG_M = 6, REG_A = 7,
34 REG_BC = 0, REG_DE = 1, REG_HL = 2, REG_SP = 3;
35
36
37localparam CF = 0, NF = 1, PF = 2, AF = 4, ZF = 6, SF = 7;
38
39
40localparam
41 EX_DE_HL = 1, EX_AF = 2,
42 INCSP2 = 3, DECSP2 = 4,
43 EXX = 5;
44
45initial begin we = 0; out = 0; end
46
47
48assign address = alt ? cp : pc;
49
50
51reg [ 3:0] t = 0;
52reg [ 2:0] m = 0;
53reg ei = 0;
54reg ei_ = 0;
55reg [15:0] cp = 0;
56reg alt = 1'b0;
57
58
59reg [15:0] bc = 16'hAFB1, de = 16'h0305, hl = 16'hBEEF;
60reg [15:0] bc_ = 16'h0000, de_ = 16'h0000, hl_ = 16'h0000;
61reg [15:0] pc = 16'h0000, sp = 16'h0001;
62reg [ 1:0] im = 2'b00;
63reg [ 7:0] i = 8'h00,
64 a = 8'h0A, a_ = 8'hFF,
65 f = 8'b11000100, f_ = 8'h00;
66
67
68
69wire [ 7:0] opcode = t ? latch : in;
70reg [ 7:0] latch = 8'h00;
71reg irqp = 1'b0;
72
73
74reg _b = 1'b0;
75reg _w = 1'b0;
76reg [ 2:0] _n = 3'h0;
77reg [ 7:0] _l = 8'h00;
78reg [ 7:0] _u = 8'h00;
79reg [ 7:0] _f = 8'h00;
80reg fw;
81reg [ 2:0] spec;
82
83
84wire [15:0] pci = pc + 1;
85wire [15:0] pcn = pci + {{8{in[7]}}, in[7:0]};
86wire [7:0] ccc = {f[SF], ~f[SF], f[PF], ~f[PF], f[CF], ~f[CF], f[ZF], ~f[ZF]};
87wire ccx = ccc[op53] || opcode == 8'hC9 || opcode == 8'hC3 || opcode == 8'hCD;
88
89
90
91
92
93
94wire [2:0] op20 = opcode[2:0];
95wire [2:0] op53 = opcode[5:3];
96wire [1:0] op54 = opcode[5:4];
97
98
99wire [7:0] r20 =
100 op20 == REG_B ? bc[15:8] : op20 == REG_C ? bc[ 7:0] :
101 op20 == REG_D ? de[15:8] : op20 == REG_E ? de[ 7:0] :
102 op20 == REG_H ? hl[15:8] : op20 == REG_L ? hl[ 7:0] :
103 op20 == REG_M ? in : a;
104
105
106wire [7:0] r53 =
107 op53 == REG_B ? bc[15:8] : op53 == REG_C ? bc[ 7:0] :
108 op53 == REG_D ? de[15:8] : op53 == REG_E ? de[ 7:0] :
109 op53 == REG_H ? hl[15:8] : op53 == REG_L ? hl[ 7:0] :
110 op53 == REG_M ? in : a;
111
112
113wire [15:0] r16 =
114 op54 == REG_BC ? bc :
115 op54 == REG_DE ? de :
116 op54 == REG_HL ? hl : sp;
117
118
119wire [16:0] hladd = hl + r16;
120
121
122wire [8:0] incdec = opcode[0] ? r53 - 1 : r53 + 1;
123wire r53ido = r53 == (127 + opcode[0]);
124wire [7:0] idflag = {incdec[7], incdec[7:0] == 8'b0, 1'b0, incdec[4] ^ r53[4], 1'b0, r53ido, 1'b0, incdec[8]};
125
126
127
128
129
130always @(posedge clock)
131
132if (reset_n == 1'b0) begin t <= 0; pc <= 0; alt <= 0; end
133
134else if (ce) begin
135
136
137 alt <= 0;
138 _b <= 0;
139 _w <= 0;
140 we <= 0;
141 pw <= 0;
142 rd <= 0;
143 fw <= 0;
144 spec <= 0;
145
146
147 if (t == 0 && ei && (irqp != irq)) begin
148
149 t <= 1;
150 alt <= 1;
151 we <= 1;
152 cp <= sp - 1;
153 irqp <= irq;
154 out <= (in == 8'h76) ? pci[15:8] : pc[15:7];
155 latch <= 8'hFF;
156 {ei,ei_} <= 0;
157
158
159 if (in == 8'h76) pc <= pc + 1;
160
161 end
162
163 else begin
164
165 t <= t + 1;
166
167
168 if (t == 0) begin
169
170 latch <= in;
171 ei <= ei_;
172 pc <= pc + 1;
173
174 end
175
176
177 casex (opcode)
178
179
180 8'b00_000_000: t <= 0;
181
182
183 8'b00_001_000: begin t <= 0; spec <= EX_AF; end
184
185
186 8'b00_010_000: case (t)
187
188 0: begin
189
190 _b <= 1;
191 _n <= REG_B;
192 _l <= bc[15:8] - 1;
193
194 if (bc[15:8] == 1) pc <= pc + 2;
195
196 end
197 1: begin t <= 0; pc <= pcn; end
198
199 endcase
200
201
202 8'b00_011_000: if (t == 1) begin t <= 0; pc <= pcn; end
203
204
205 8'b00_1xx_000: case (t)
206
207 0: if (!ccc[opcode[4:3]]) begin t <= 0; pc <= pc + 2; end
208 1: begin t <= 0; pc <= pcn; end
209
210 endcase
211
212
213 8'b00_xx0_001: case (t)
214
215 0: begin _n <= opcode[5:4]; end
216 1: begin pc <= pc + 1; _l <= in; end
217 2: begin pc <= pc + 1; _u <= in; _w <= 1; t <= 0; end
218
219 endcase
220
221
222 8'b00_xx1_001: begin
223
224 t <= 0;
225 _w <= 1;
226 _n <= REG_HL;
227
228 {_u, _l} <= hladd;
229
230 _f[NF] <= 1'b0;
231 _f[CF] <= hladd[16];
232 _f[ZF] <= hladd[15:0] == 0;
233 _f[SF] <= hladd[15];
234
235 end
236
237
238 8'b00_0x0_010: case (t)
239
240 0: begin alt <= 1; cp <= opcode[4] ? de : bc; out <= a; we <= 1; end
241 1: begin alt <= 0; t <= 0; end
242
243 endcase
244
245
246 8'b00_0x1_010: case (t)
247
248 0: begin alt <= 1; cp <= opcode[4] ? de : bc; end
249 1: begin t <= 0; _n <= REG_A; _b <= 1; _l <= in; end
250
251 endcase
252
253
254 8'b00_100_010: case (t)
255
256 1: begin cp[ 7:0] <= in; pc <= pc + 1; end
257 2: begin cp[15:8] <= in; we <= 1; alt <= 1; out <= hl[ 7:0]; pc <= pc + 1; end
258 3: begin cp <= cp + 1; we <= 1; alt <= 1; out <= hl[15:8]; end
259 4: begin t <= 0; end
260
261 endcase
262
263
264 8'b00_101_010: case (t)
265
266 1: begin pc <= pc + 1; cp[ 7:0] <= in; end
267 2: begin pc <= pc + 1; cp[15:8] <= in; alt <= 1; end
268 3: begin _n <= REG_L; _b <= 1; _l <= in; alt <= 1; cp <= cp + 1; end
269 4: begin _n <= REG_H; _b <= 1; _l <= in; t <= 0; end
270
271 endcase
272
273
274 8'b00_110_010: case (t)
275
276 1: begin cp[ 7:0] <= in; pc <= pc + 1; out <= a; end
277 2: begin cp[15:8] <= in; pc <= pc + 1; we <= 1; alt <= 1; end
278 3: begin t <= 0; end
279
280 endcase
281
282
283 8'b00_111_010: case (t)
284
285 1: begin pc <= pc + 1; cp[ 7:0] <= in; end
286 2: begin pc <= pc + 1; cp[15:8] <= in; alt <= 1; end
287 3: begin _b <= 1; _n <= REG_A; _l <= in; t <= 0; end
288
289 endcase
290
291
292 8'b00_000_011: begin t <= 0; {_u, _l} <= bc + 1; _n <= 0; _w <= 1; end
293 8'b00_010_011: begin t <= 0; {_u, _l} <= de + 1; _n <= 1; _w <= 1; end
294 8'b00_100_011: begin t <= 0; {_u, _l} <= hl + 1; _n <= 2; _w <= 1; end
295 8'b00_110_011: begin t <= 0; {_u, _l} <= sp + 1; _n <= 3; _w <= 1; end
296
297
298 8'b00_001_011: begin t <= 0; {_u, _l} <= bc - 1; _n <= 0; _w <= 1; end
299 8'b00_011_011: begin t <= 0; {_u, _l} <= de - 1; _n <= 1; _w <= 1; end
300 8'b00_101_011: begin t <= 0; {_u, _l} <= hl - 1; _n <= 2; _w <= 1; end
301 8'b00_111_011: begin t <= 0; {_u, _l} <= sp - 1; _n <= 3; _w <= 1; end
302
303
304 8'b00_110_10x: case (t)
305
306 0: begin cp <= hl; alt <= 1; end
307 1: begin
308
309 _f <= idflag;
310 out <= incdec;
311 fw <= 1;
312 we <= 1;
313 alt <= 1;
314
315 end
316 2: t <= 0;
317
318 endcase
319
320
321 8'b00_xxx_10x: begin
322
323 t <= 0;
324 _n <= op53;
325 _b <= 1;
326 _l <= incdec;
327 _f <= idflag;
328 fw <= 1;
329
330 end
331
332
333 8'b00_xxx_110: case (t)
334
335 0: cp <= hl;
336 1: begin
337
338 t <= op53 == REG_M ? 2 : 0;
339 we <= op53 == REG_M;
340 alt <= op53 == REG_M;
341 _b <= op53 != REG_M;
342 _n <= op53;
343 _l <= in;
344 out <= in;
345 pc <= pc + 1;
346
347 end
348
349 2: t <= 0;
350
351 endcase
352
353
354 8'b00_xxx_111: begin
355
356 t <= 0;
357 fw <= 1;
358 _n <= REG_A;
359 _b <= 1;
360 _l <= alu_sr;
361 _f <= alu_sf;
362
363 end
364
365
366 8'b01_110_110: begin pc <= pc; t <= 0; end
367
368
369
370
371 8'b01_xxx_110: case (t)
372
373 0: begin alt <= 1; cp <= hl; end
374 1: begin t <= 0; _b <= 1; _n <= op53; _l <= in; end
375
376 endcase
377
378
379 8'b01_110_xxx: case (t)
380
381 0: begin alt <= 1; cp <= hl; we <= 1; out <= r20; end
382 1: begin t <= 0; end
383
384 endcase
385
386
387 8'b01_xxx_xxx: begin
388
389 t <= 0;
390 _b <= 1;
391 _n <= op53;
392 _l <= r20;
393
394 end
395
396
397 8'b10_xxx_110: case (t)
398
399 0: begin cp <= hl; alt <= 1; end
400 1: begin
401
402 t <= 0;
403 fw <= 1;
404 _b <= (op53 != ALU_CP);
405 _l <= alu_r;
406 _f <= alu_f;
407 _n <= REG_A;
408
409 end
410
411 endcase
412
413
414 8'b10_xxx_xxx: begin
415
416 t <= 0;
417 fw <= 1;
418 _b <= (op53 != ALU_CP);
419 _l <= alu_r;
420 _f <= alu_f;
421 _n <= REG_A;
422
423 end
424
425
426
427
428 8'b11_001_001,
429 8'b11_xxx_000: case (t)
430
431 0: begin t <= ccx; alt <= ccx; cp <= sp; end
432 1: begin pc[ 7:0] <= in; alt <= 1; cp <= cp + 1; end
433 2: begin pc[15:8] <= in; spec <= INCSP2; t <= 0; end
434
435 endcase
436
437
438 8'b11_xx0_001: case (t)
439
440 0: begin cp <= sp; alt <= 1; spec <= INCSP2; end
441 1: begin _l <= in; alt <= 1; cp <= cp + 1; end
442 2: begin
443
444 _u <= in;
445 t <= 0;
446
447 if (opcode[5:4] == 2'b11)
448 begin _n <= REG_A; _b <= 1; _l <= in; fw <= 1'b1; _f <= _l; end
449 else begin _n <= opcode[5:4]; _w <= 1; end
450
451 end
452
453 endcase
454
455
456
457
458 8'b11_011_001: begin t <= 0; spec <= EXX; end
459 8'b11_101_001: begin t <= 0; pc <= hl; end
460 8'b11_111_001: begin t <= 0; _w <= 1; _n <= REG_SP; {_u, _l} <= hl; end
461
462
463 8'b11_000_011,
464 8'b11_xxx_010: case (t)
465
466 0: if (!ccx) begin t <= 0; pc <= pc + 3; end
467 1: begin _l <= in; pc <= pc + 1'b1; end
468 2: begin pc <= {in, _l}; t <= 0; end
469
470 endcase
471
472
473 8'b11_010_011: case (t)
474
475 1: begin
476
477 pw <= 1;
478 alt <= 1;
479 cp <= in;
480 pc <= pc + 1;
481 out <= a;
482
483 end
484 2: t <= 0;
485
486 endcase
487
488
489 8'b11_011_011: case (t)
490
491 1: begin pc <= pc + 1; cp <= in; rd <= 1; alt <= 1; end
492 2: begin _b <= 1; _n <= REG_A; _l <= in; t <= 0; end
493
494 endcase
495
496
497 8'b11_100_011: case (t)
498
499 0: begin alt <= 1; cp <= sp; end
500 1: begin alt <= 1; _l <= in; out <= hl[ 7:0]; we <= 1; end
501 2: begin alt <= 1; cp <= cp + 1; end
502 3: begin alt <= 1; _u <= in; out <= hl[15:8]; we <= 1; _w <= 1; _n <= REG_HL; end
503 4: begin t <= 0; end
504
505 endcase
506
507
508
509 8'b11_101_011: begin t <= 0; spec <= EX_DE_HL; end
510 8'b11_11x_011: begin t <= 0; ei_ <= opcode[3]; end
511
512
513 8'b11_001_101,
514 8'b11_xxx_100: case (t)
515
516 0: if (!ccx) begin t <= 0; pc <= pc + 3; end
517 1: begin _l <= in; pc <= pc + 1; end
518 2: begin
519
520 alt <= 1;
521 we <= 1;
522 cp <= sp - 1;
523 out <= pci[15:8];
524 _u <= in;
525
526 end
527 3: begin
528
529 alt <= 1;
530 we <= 1;
531 out <= pci[ 7:0];
532 cp <= cp - 1;
533 pc <= {_u, _l};
534 spec <= DECSP2;
535
536 end
537 4: t <= 0;
538
539 endcase
540
541
542 8'b11_xx0_101: case (t)
543
544 0: begin
545
546 alt <= 1;
547 we <= 1;
548 cp <= sp - 1;
549 out <= (op54 == 2'b11) ? a : r16[15:8];
550 spec <= DECSP2;
551
552 end
553
554 1: begin
555
556 t <= 2;
557 alt <= 1;
558 we <= 1;
559 cp <= cp - 1;
560 out <= (op54 == 2'b11) ? f : r16[ 7:0];
561
562 end
563
564 2: t <= 0;
565
566 endcase
567
568
569 8'b11_xxx_110: case (t)
570
571
572 1: begin
573
574 t <= 0;
575 pc <= pc + 1;
576 fw <= 1;
577 _b <= (op53 != ALU_CP);
578 _l <= alu_r;
579 _f <= alu_f;
580 _n <= REG_A;
581
582 end
583
584 endcase
585
586
587 8'b11_xxx_111: case (t)
588
589 0: begin out <= pci[15:8]; cp <= sp - 1; we <= 1; alt <= 1; end
590 1: begin out <= pc [ 7:0]; cp <= cp - 1; we <= 1; alt <= 1; end
591 2: begin spec <= DECSP2; pc <= {op53, 3'b000}; t <= 0; end
592
593 endcase
594
595 endcase
596
597 end
598
599end
600
601
602
603
604
605wire is_add = (op53 == ALU_ADD) || (op53 == ALU_ADC);
606wire is_lgc = (op53 == ALU_AND) || (op53 == ALU_OR) || op53 == ALU_XOR;
607
608
609wire [16:0] alu_r =
610 op53 == ALU_ADD ? a + r20 :
611 op53 == ALU_ADC ? a + r20 + f[CF] :
612 op53 == ALU_SBC ? a - r20 - f[CF] :
613 op53 == ALU_AND ? a & r20 :
614 op53 == ALU_XOR ? a ^ r20 :
615 op53 == ALU_OR ? a | r20 : a - r20;
616
617
618wire carry = alu_r[8];
619wire sign = alu_r[7];
620wire zero = ~|alu_r[7:0];
621wire prty = ~^alu_r[7:0];
622wire aux = a[4] ^ r20[4] ^ alu_r[4];
623wire over = (a[7] ^ r20[7] ^ is_add) && (a[7] != alu_r[7]);
624
625wire [7:0] alu_f =
626
627 is_lgc? {sign, zero, alu_r[5], 1'b0, alu_r[3], prty, 1'b0, 1'b0} :
628 {sign, zero, alu_r[5], aux, alu_r[3], over, !is_add, carry};
629
630
631
632
633
634wire [7:0] daa =
635 (f[NF]) ? a - ((f[AF] | (a[3:0] > 4'h9)) ? 8'h06 : 0) - ((f[CF] | (a[7:0] > 8'h99)) ? 8'h60 : 0) :
636 a + ((f[AF] | (a[3:0] > 4'h9)) ? 8'h06 : 0) + ((f[CF] | (a[7:0] > 8'h99)) ? 8'h60 : 0);
637
638
639wire sr_prty = ~^alu_sr[7:0];
640wire sr_zero = alu_sr[7:0] == 8'b0;
641
642
643wire [7:0] alu_sr =
644 op53 == ALU_RLC ? {a[6:0], a[ 7]} :
645 op53 == ALU_RRC ? {a[0], a[7:1]} :
646 op53 == ALU_RL ? {a[6:0], f[ CF]} :
647 op53 == ALU_RR ? {f[CF], a[7:1]} :
648 op53 == ALU_DAA ? daa :
649 op53 == ALU_CPL ? ~a : a;
650
651
652wire [7:0] alu_sf =
653 op53 == ALU_RLC || op53 == ALU_RL ? {alu_sr[7], sr_zero, 3'b000, sr_prty, 1'b1, a[7]} :
654 op53 == ALU_RRC || op53 == ALU_RR ? {alu_sr[7], sr_zero, 3'b000, sr_prty, 1'b1, a[0]} :
655 op53 == ALU_DAA ? {daa[7], sr_zero, daa[5], a[4] ^ daa[4], daa[3], sr_prty, f[NF], f[CF] | (a > 8'h99)} :
656 op53 == ALU_CPL ? {f[SF], f[ZF], 1'b0, 1'b1, 1'b0, f[PF], 1'b1, f[CF]} :
657 op53 == ALU_SCF ? {f[SF], f[ZF], 1'b0, f[AF], 1'b0, f[PF], 1'b1, 1'b1} :
658 {f[SF], f[ZF], 1'b0, f[AF], 1'b0, f[PF], 1'b1, !f[CF]};
659
660
661
662
663
664always @(negedge clock)
665begin
666
667
668 if (fw) f <= _f;
669
670
671 case (spec)
672 INCSP2: sp <= sp + 2;
673 DECSP2: sp <= sp - 2;
674
675
676
677 EX_DE_HL: begin {de, hl} <= {hl, de}; end
678 default:
679
680
681 if (_w) case (_n)
682
683 REG_BC: bc <= {_u, _l};
684 REG_DE: de <= {_u, _l};
685 REG_HL: hl <= {_u, _l};
686 REG_SP: sp <= {_u, _l};
687
688 endcase
689
690 else if (_b) case (_n)
691
692 REG_B: bc[15:8] <= _l;
693 REG_C: bc[ 7:0] <= _l;
694 REG_D: de[15:8] <= _l;
695 REG_E: de[ 7:0] <= _l;
696 REG_H: hl[15:8] <= _l;
697 REG_L: hl[ 7:0] <= _l;
698 REG_A: a <= _l;
699
700 endcase
701
702 endcase
703
704end
705
706endmodule