§ Описание пинов

  • 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/* verilator lint_off WIDTH */
2/* verilator lint_off CASEX */
3/* verilator lint_off CASEOVERLAP */
4/* verilator lint_off CASEINCOMPLETE */
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,         // Port write
16    output  reg         rd,         // Port read (на IN значение порта address)
17    output  reg  [ 7:0] out,
18
19    // Interrupt
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;        // Это t-state
52reg  [ 2:0] m       = 0;        // Это m-state для префиксов
53reg         ei      = 0;        // Enabled Interrupt
54reg         ei_     = 0;        // Это необходимо для EI+RET конструкции
55reg  [15:0] cp      = 0;
56reg         alt     = 1'b0;     // =0 pc  =1 cp
57
58// Регистры. Есть также регистры AF'BC'DE'HL' из дополнительного набора
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                 //  SZ5A3PNC
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;      // Сигнал на запись 8 битного регистра
75reg         _w = 1'b0;      // Сигнал на запись 16 битного регистра (_u:_l)
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;           // Специальные операции; EX DE,HL; EX AF,AF'
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; // CCC; RET, JP, CALL
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// Вариант 1. Источник opcode[2:0]
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// Вариант 2. Источник opcode[5:3]
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// 16-битный регистр, источник opcode[5:4]
113wire [15:0] r16 =
114    op54 == REG_BC ? bc :
115    op54 == REG_DE ? de :
116    op54 == REG_HL ? hl : sp;
117
118// 16-битные операции HL + R16
119wire [16:0] hladd = hl + r16;
120
121// Инструкции INC и DEC
122wire [8:0] incdec = opcode[0] ? r53 - 1 : r53 + 1;  // Расчет результата
123wire       r53ido = r53 == (127 + opcode[0]);       // Флаг overflow
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    // Запуск прерывания RST #38; IM 2 режима нет
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]; // HALT?
155        latch   <= 8'hFF;
156        {ei,ei_} <= 0;
157
158        // HALT добавляет PC+1
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_;       // Сброс EI-триггера
172            pc    <= pc + 1;    // По умолчанию PC+1 на T=0
173
174        end
175
176        // Выполнять инструкции
177        casex (opcode)
178
179        // 1 NOP
180        8'b00_000_000: t <= 0;
181
182        // 1 EX AF,AF'
183        8'b00_001_000: begin t <= 0; spec <= EX_AF; end
184
185        // 1+ DJNZ *
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        // 2 JR *
202        8'b00_011_000: if (t == 1) begin t <= 0; pc <= pcn; end
203
204        // 1+ JR cc, *
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        // 3 LD r, i16
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        // 1 ADD HL, r
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        // 2 LD (BC|DE), A
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        // 2 LD A, (BC|DE)
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        // 5 LD (**), HL
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        // 5 LD HL, (**)
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        // 4 LD (**), A
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        // 4 LD A, (**)
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        // 1 INC r16
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        // 1 DEC r16
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        // 3 INC|DEC (HL)
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        // 1 INC|DEC r8
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        // 2+ LD r, i8
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        // 1 RLCA, RRCA, RLA, RRA, DAA, CPL, SCF, CCF
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        // 1 HALT: Остановить процессор
366        8'b01_110_110: begin pc <= pc; t <= 0; end
367
368        // --------------------------
369
370        // 2 LD r, (HL)
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        // 2 LD (HL), r
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        // 1 LD r, r
387        8'b01_xxx_xxx: begin
388
389            t  <= 0;
390            _b <= 1;
391            _n <= op53;
392            _l <= r20;
393
394        end
395
396        // 2 <ALU> A, (HL)
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        // 1 <ALU> A, r
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        // 1/3 RET c | RET
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        // 3 POP r16
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 // POP AF
449                else begin _n <= opcode[5:4];    _w <= 1; end
450
451            end
452
453        endcase
454
455        // 1 EXX
456        // 1 JP (HL)
457        // 1 LD SP, HL
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        // 1/3 JP c, ** | JP **
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        // 3 OUT (*), A
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        // 3 IN  A, (*)
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        // 5 EX (SP), HL
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        // 1 EX DE, HL
508        // 1 DI, EI
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        // 1/5 CALL c, **
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        // 3 PUSH r16
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        // 2 <ALU> A, i8
569        8'b11_xxx_110: case (t)
570
571            // Так как op20 равно 6, то в _r20 = in
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        // 3 RST #
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; // OR; SUB, CP
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//           SF    ZF    F5        AF    F3        PF/OF    NF    CF
627    is_lgc? {sign, zero, alu_r[5], 1'b0, alu_r[3], prty,    1'b0, 1'b0} : // AND, OR, XOR
628            {sign, zero, alu_r[5], aux,  alu_r[3], over, !is_add, carry}; // ADD, ADC, SUB, SBC, CP
629
630// -----------------------------------------------------------------------------
631// Сдвиги и работа над регистром A
632// -----------------------------------------------------------------------------
633
634wire [7:0] daa = // Коррекция BCD-чисел после сложения и вычитания
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    // Опциональная поддержка инструкции EX AF,AF`; EXX
675    // EXX:      begin {bc, de, hl, bc_, de_, hl_} <= {bc_, de_, hl_, bc, de, hl}; end
676    // EX_AF:    begin {a, f, a_, f_} <= {a_, f_, a, f}; end
677    EX_DE_HL: begin {de, hl} <= {hl, de}; end
678    default:
679
680        // Запись в 16-битные регистры
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        // Запись в 8 битные регистры
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