§ Код ядра
Описание пинов:
-
clock
— тактовая частота, срабатывает на позитивном и негативном фронте, который записывает результаты в регистры -
reset_n
— при 0, сброс процессора -
pc
— указатель Program Counter -
ir
— данные 16 битные из rom[pc] -
address
— указатель в оперативную память, до 64К -
data_i
— входящие в процессор данные -
data_o
— данные на запись -
intr
— прерывание, срабатывает на перемене состояния -
vect
— номер прерывания от 0 до 7 -
we
— сигнал записи, длительность сигнала — 1 такт на 1 инструкцию -
read
— сигнал, что данные были именно прочитаны из памяти (тоже 1 такт на 1 инструкцию)
Ревизия обновлена: 14 янв 2024.
§ Код ядра
Ниже представлен готовый код ядра процессора.
1
2
3
4
5module avr
6(
7 input clock,
8 input reset_n,
9
10 output reg [15:0] pc,
11 input [15:0] ir,
12
13 output reg [15:0] address,
14 input [ 7:0] data_i,
15 output reg [ 7:0] data_o,
16 output reg we,
17 output reg read,
18
19 input intr,
20 input [ 2:0] vect
21);
22initial begin
23 address = 1'b0;
24 pc = 1'b0;
25 we = 1'b0;
26 data_o = 1'b0;
27 read = 1'b0;
28
29 r[0] = 8'h00; r[4] = 8'h00; r[8] = 8'h00; r[12] = 8'h01;
30 r[1] = 8'h00; r[5] = 8'h00; r[9] = 8'h00; r[13] = 8'h00;
31 r[2] = 8'h00; r[6] = 8'h00; r[10] = 8'h00; r[14] = 8'h00;
32 r[3] = 8'h00; r[7] = 8'h00; r[11] = 8'h00; r[15] = 8'h00;
33
34 r[16] = 8'h00; r[20] = 8'h00; r[24] = 8'h00; r[28] = 8'h00;
35 r[17] = 8'h00; r[21] = 8'h00; r[25] = 8'h00; r[29] = 8'h00;
36 r[18] = 8'h00; r[22] = 8'h00; r[26] = 8'h00; r[30] = 8'h05;
37 r[19] = 8'h00; r[23] = 8'h00; r[27] = 8'h00; r[31] = 8'hFA;
38end
39localparam
40 SPDEC = 1,
41 SPINC = 2;
42
43
44
45reg [7:0] din;
46always @* begin
47 casex (address)
48
49 16'b0000_0000_000x_xxxx: din = r[ address[4:0] ];
50
51 16'h005B: din = rampz;
52 16'h005D: din = sp[ 7:0];
53 16'h005E: din = sp[15:8];
54 16'h005F: din = sreg;
55
56 default: din = data_i;
57 endcase
58end
59
60
61
62
63reg [ 7:0] r[32];
64reg [ 1:0] tstate = 0;
65reg [15:0] latch = 0;
66reg [15:0] pclatch = 0;
67reg [15:0] sp = 16'h1FFF;
68reg [ 7:0] sreg = 8'b0000_0000;
69reg [ 4:0] alu = 0;
70
71reg reg_w = 0;
72reg sreg_w = 0;
73reg [ 4:0] reg_id = 0;
74reg [ 1:0] sp_mth = 0;
75
76reg reg_ww = 1'b0;
77reg reg_ws = 1'b0;
78reg reg_wm = 1'b0;
79reg [ 1:0] reg_idw = 1'b0;
80reg [15:0] wb2 = 1'b0;
81reg [ 7:0] rampz = 1'b0;
82
83wire [15:0] opcode = tstate ? latch : ir;
84wire [15:0] X = {r[27], r[26]};
85wire [15:0] Y = {r[29], r[28]};
86wire [15:0] Z = {r[31], r[30]};
87wire [15:0] Xm = X - 1'b1;
88wire [15:0] Xp = X + 1'b1;
89wire [15:0] Ym = Y - 1'b1;
90wire [15:0] Yp = Y + 1'b1;
91wire [15:0] Zm = Z - 1'b1;
92wire [15:0] Zp = Z + 1'b1;
93wire [ 5:0] q = {opcode[13], opcode[11:10], opcode[2:0]};
94wire [ 4:0] rd = opcode[8:4];
95wire [ 4:0] rr = {opcode[9], opcode[3:0]};
96wire [ 4:0] rdi = {1'b1, opcode[7:4]};
97wire [ 4:0] rri = {1'b1, opcode[3:0]};
98wire [ 7:0] K = {opcode[11:8], opcode[3:0]};
99
100reg skip_instr = 1'b0;
101wire [15:0] pcnext = pc + 1'h1;
102wire [15:0] pcnext2 = pc + 2'h2;
103wire is_call = {opcode[14], opcode[3:1]} == 4'b0111;
104
105
106
107reg [ 7:0] op1, op2, alu_res, alu_sreg;
108reg [15:0] op1w, resw;
109
110
111reg intr_trigger = 1'b0;
112reg intr_prev = 1'b0;
113reg [2:0] intr_vect = 1'b0;
114
115
116
117always @(posedge clock)
118
119if (reset_n == 1'b0) begin
120 pc <= 1'b0;
121 tstate <= 1'b0;
122end
123
124else begin
125 we <= 1'b0;
126 read <= 1'b0;
127 reg_w <= 1'b0;
128 sreg_w <= 1'b0;
129 sp_mth <= 1'b0;
130 reg_ww <= 1'b0;
131 reg_ws <= 1'b0;
132 reg_wm <= 1'b0;
133 if (tstate == 0) latch <= ir;
134
135 if (skip_instr) begin
136 casex (opcode)
137 16'b1001_010x_xxxx_11xx,
138 16'b1001_00xx_xxxx_0000:
139 pc <= pcnext + 1;
140 default:
141 pc <= pcnext;
142 endcase
143 skip_instr <= 0;
144 end
145
146
147 else if (intr_trigger) begin
148 case (tstate)
149
150 0: begin
151 tstate <= 1;
152 address <= sp;
153 data_o <= pc[7:0];
154 we <= 1'b1;
155 sp_mth <= SPDEC;
156 end
157
158 1: begin
159 tstate <= 0;
160 address <= sp;
161 data_o <= pc[15:8];
162 we <= 1'b1;
163 sp_mth <= SPDEC;
164 pc <= {intr_vect, 1'b0};
165 intr_trigger <= 0;
166
167 alu <= 11;
168 op2 <= {1'b0, sreg[6:0]};
169 sreg_w <= 1'b1;
170 end
171 endcase
172 end
173
174
175 else if (sreg[7] && tstate == 0 && intr ^ intr_prev) begin
176 intr_vect <= vect + 1;
177 intr_prev <= intr;
178 intr_trigger <= 1'b1;
179 end
180
181
182 else casex (opcode)
183
184 16'b0000_0000_0000_0000: pc <= pcnext;
185 16'b1001_0101_1001_1000: pc <= pcnext;
186
187 16'b1110_xxxx_xxxx_xxxx: begin
188 pc <= pcnext;
189 alu <= 0;
190 op2 <= K;
191 reg_w <= 1'b1;
192 reg_id <= rdi;
193 end
194
195 16'b1100_xxxx_xxxx_xxxx: pc <= pcnext + {{4{opcode[11]}}, opcode[11:0]};
196 16'b1001_0100_000x_1001: pc <= Z;
197
198 16'b1001_010x_xxxx_110x:
199 case (tstate)
200 0: begin tstate <= 1; pc <= pcnext; end
201 1: begin tstate <= 0; pc <= ir; end
202 endcase
203
204 16'b000x_01xx_xxxx_xxxx,
205 16'b000x_1xxx_xxxx_xxxx,
206 16'b0010_0xxx_xxxx_xxxx,
207 16'b0010_10xx_xxxx_xxxx:
208 begin
209 pc <= pcnext;
210 alu <= opcode[13:10];
211 op1 <= r[rd];
212 op2 <= r[rr];
213 reg_id <= rd;
214
215 reg_w <= (opcode[13:10] != 4'b0001 && opcode[13:10] != 4'b0101);
216 sreg_w <= 1'b1;
217 end
218
219 16'b1111_0xxx_xxxx_xxxx:
220 begin
221 if (sreg[ opcode[2:0] ] ^ opcode[10])
222 pc <= pcnext + {{9{opcode[9]}}, opcode[9:3]};
223 else
224 pc <= pcnext;
225 end
226
227 16'b0011_xxxx_xxxx_xxxx,
228 16'b0100_xxxx_xxxx_xxxx,
229 16'b0101_xxxx_xxxx_xxxx,
230 16'b0110_xxxx_xxxx_xxxx,
231 16'b0111_xxxx_xxxx_xxxx:
232 begin
233 pc <= pcnext;
234 op1 <= r[rdi];
235 op2 <= K;
236 reg_id <= rdi;
237 reg_w <= (opcode[15:12] != 4'b0011);
238 sreg_w <= 1'b1;
239 case (opcode[15:12])
240 4'b0011: alu <= 5;
241 4'b0100: alu <= 2;
242 4'b0101: alu <= 6;
243 4'b0110: alu <= 10;
244 4'b0111: alu <= 8;
245 endcase
246 end
247
248 16'b0010_11xx_xxxx_xxxx:
249 begin
250 pc <= pcnext;
251 alu <= 0;
252 op2 <= r[rr];
253 reg_id <= rd;
254 reg_w <= 1'b1;
255 end
256
257 16'b1101_xxxx_xxxx_xxxx,
258 16'b1001_0101_000x_1001,
259 16'b1001_010x_xxxx_111x:
260 case (tstate)
261
262 0: begin
263 tstate <= 1;
264 address <= sp;
265 data_o <= is_call ? pcnext2[7:0] : pcnext[7:0];
266 we <= 1'b1;
267 sp_mth <= SPDEC;
268 pc <= pcnext;
269 end
270
271 1: begin
272 tstate <= 0;
273 address <= sp;
274 data_o <= is_call ? pcnext[15:8] : pc[15:8];
275 we <= 1'b1;
276 sp_mth <= SPDEC;
277
278 if (is_call) pc <= ir;
279 else if (opcode[14]) pc <= (pc + {{4{opcode[11]}}, opcode[11:0]});
280 else pc <= Z;
281 end
282 endcase
283
284 16'b1001_0101_000x_1000:
285 case (tstate)
286
287 0: begin
288 tstate <= 1;
289 read <= 1;
290 address <= sp + 1;
291 sp_mth <= SPINC;
292 end
293
294 1: begin
295 tstate <= 2;
296 read <= 1;
297 pc[15:8] <= din;
298 address <= sp + 1;
299 sp_mth <= SPINC;
300 end
301
302 2: begin
303 tstate <= 0;
304 pc[ 7:0] <= din;
305 alu <= 11;
306 op2 <= {sreg[7] | opcode[4], sreg[6:0]};
307 sreg_w <= 1;
308 end
309 endcase
310
311
312 16'b1001_00xx_xxxx_1100,
313 16'b1001_00xx_xxxx_1101,
314 16'b1001_00xx_xxxx_1110,
315 16'b1001_00xx_xxxx_1001,
316 16'b1001_00xx_xxxx_1010,
317 16'b1001_00xx_xxxx_0001,
318 16'b1001_00xx_xxxx_0010:
319 case (tstate)
320
321 0: begin
322 tstate <= opcode[9] ? 0 : 1;
323 pc <= pcnext;
324 data_o <= r[rd];
325 we <= opcode[9];
326 read <= !opcode[9];
327
328 case (opcode[3:0])
329 4'b11_00: begin address <= X; end
330 4'b11_01: begin address <= X; wb2 <= Xp; reg_idw <= 2'b01; reg_ww <= 1; end
331 4'b11_10: begin address <= Xm; wb2 <= Xm; reg_idw <= 2'b01; reg_ww <= 1; end
332 4'b10_01: begin address <= Y; wb2 <= Yp; reg_idw <= 2'b10; reg_ww <= 1; end
333 4'b10_10: begin address <= Ym; wb2 <= Ym; reg_idw <= 2'b10; reg_ww <= 1; end
334 4'b00_01: begin address <= Z; wb2 <= Zp; reg_idw <= 2'b11; reg_ww <= 1; end
335 4'b00_10: begin address <= Zm; wb2 <= Zm; reg_idw <= 2'b11; reg_ww <= 1; end
336 endcase
337 end
338
339 1: begin
340 tstate <= 0;
341 alu <= 0;
342 op2 <= din;
343 reg_w <= 1;
344 reg_id <= rd;
345 end
346 endcase
347
348
349 16'b10x0_xxxx_xxxx_xxxx:
350 case (tstate)
351
352 0: begin
353 tstate <= opcode[9] ? 0 : 1;
354 pc <= pcnext;
355 address <= (opcode[3] ? Y : Z) + q;
356 data_o <= r[rd];
357 we <= opcode[9];
358 read <= !opcode[9];
359 end
360
361 1: begin
362 tstate <= 0;
363 alu <= 0;
364 op2 <= din;
365 reg_w <= 1;
366 reg_id <= rd;
367 end
368 endcase
369
370 16'b1001_010x_xxxx_00xx,
371 16'b1001_010x_xxxx_011x,
372 16'b1001_010x_xxxx_0101,
373 16'b1001_010x_xxxx_1010: begin
374 pc <= pcnext;
375 op1 <= r[rd];
376 reg_w <= 1;
377 sreg_w <= 1;
378 reg_id <= rd;
379 case (opcode[3:0])
380 4'b0000: alu <= 5'h0C;
381 4'b0001: alu <= 5'h0D;
382 4'b0010: alu <= 5'h0E;
383 4'b0011: alu <= 5'h0F;
384 4'b0101: alu <= 5'h10;
385 4'b0110: alu <= 5'h11;
386 4'b0111: alu <= 5'h12;
387 4'b1010: alu <= 5'h13;
388 endcase
389 end
390
391 16'b0000_0001_xxxx_xxxx:
392 case (tstate)
393
394 0: begin
395 tstate <= 1;
396 pc <= pcnext;
397 alu <= 0;
398 op2 <= r[ {opcode[3:0], 1'b0} ];
399 reg_id <= {opcode[7:4], 1'b0};
400 reg_w <= 1;
401 end
402
403 1: begin
404 tstate <= 0;
405 alu <= 0;
406 op2 <= r[ {opcode[3:0], 1'b1} ];
407 reg_id <= {opcode[7:4], 1'b1};
408 reg_w <= 1;
409 end
410 endcase
411
412 16'b1001_0110_xxxx_xxxx,
413 16'b1001_0111_xxxx_xxxx:
414 begin
415 pc <= pcnext;
416 alu <= opcode[8] ? 5'h15 : 5'h14;
417 case (opcode[5:4])
418 0: op1w <= {r[25], r[24]};
419 1: op1w <= {r[27], r[26]};
420 2: op1w <= {r[29], r[28]};
421 3: op1w <= {r[31], r[30]};
422 endcase
423 op2 <= {opcode[7:6], opcode[3:0]};
424 reg_idw <= opcode[5:4];
425 reg_ww <= 1;
426 reg_ws <= 1;
427 sreg_w <= 1;
428 end
429
430 16'b1001_0101_110x_1000,
431 16'b1001_000x_xxxx_01x0,
432 16'b1001_000x_xxxx_01x1:
433 case (tstate)
434
435 0: begin
436 tstate <= 1;
437 pclatch <= pcnext;
438
439 if (opcode[1] || (opcode[10] && opcode[4]))
440 pc <= {rampz[0], Z[15:1]};
441 else pc <= Z[15:1];
442 end
443
444 1: begin
445 tstate <= 0;
446 pc <= pclatch;
447 alu <= 0;
448 reg_idw <= 2'b11;
449 reg_ww <= (!opcode[10] & opcode[0]);
450 wb2 <= Zp;
451 reg_w <= 1;
452 reg_id <= opcode[10] ? 0 : rd;
453 op2 <= Z[0] ? ir[15:8] : ir[7:0];
454 end
455 endcase
456
457
458 16'b1011_xxxx_xxxx_xxxx:
459 case (tstate)
460
461 0: begin
462 tstate <= opcode[11] ? 0 : 1;
463 pc <= pcnext;
464 data_o <= r[rd];
465 we <= opcode[11];
466 read <= !opcode[11];
467 address <= {opcode[10:9], opcode[3:0]} + 16'h20;
468 end
469
470 1: begin
471 tstate <= 0;
472 alu <= 0;
473 op2 <= din;
474 reg_id <= rd;
475 reg_w <= 1;
476 end
477 endcase
478
479
480 16'b1111_11xx_xxxx_0xxx: begin
481 pc <= pcnext;
482 if (r[rd][ opcode[2:0] ] == opcode[9])
483 skip_instr <= 1;
484 end
485
486
487 16'b1001_10x1_xxxx_xxxx:
488 casex (tstate)
489
490 0: begin
491 tstate <= 1;
492 read <= 1;
493 address <= opcode[7:3] + 16'h20;
494 end
495
496 1: begin
497 tstate <= 0;
498 pc <= pcnext;
499 if (din[ opcode[2:0] ] == opcode[9])
500 skip_instr <= 1;
501 end
502 endcase
503
504 16'b0001_00xx_xxxx_xxxx: begin
505 if (r[rd] == r[rr]) skip_instr <= 1;
506 pc <= pcnext;
507 end
508
509
510 16'b1001_00xx_xxxx_0000:
511 case (tstate)
512
513 0: begin
514 tstate <= 1;
515 pc <= pcnext;
516 end
517
518 1: begin
519 tstate <= opcode[9] ? 0 : 2;
520 pc <= pcnext;
521 reg_id <= rd;
522 address <= ir;
523 data_o <= r[rd];
524 we <= opcode[9];
525 read <= !opcode[9];
526 end
527
528 2: begin
529 tstate <= 0;
530 alu <= 0;
531 reg_w <= 1;
532 op2 <= din;
533 end
534 endcase
535
536 16'b1001_0100_xxxx_1000: begin
537 case (opcode[6:4])
538 0: op2 <= {sreg[7:1], !opcode[7]};
539 1: op2 <= {sreg[7:2], !opcode[7], sreg[0]};
540 2: op2 <= {sreg[7:3], !opcode[7], sreg[1:0]};
541 3: op2 <= {sreg[7:4], !opcode[7], sreg[2:0]};
542 4: op2 <= {sreg[7:5], !opcode[7], sreg[3:0]};
543 5: op2 <= {sreg[7:6], !opcode[7], sreg[4:0]};
544 6: op2 <= {sreg[7], !opcode[7], sreg[5:0]};
545 7: op2 <= {!opcode[7], sreg[6:0]};
546 endcase
547 alu <= 11;
548 sreg_w <= 1;
549 pc <= pcnext;
550 end
551
552 16'b1001_001x_xxxx_1111: begin
553 pc <= pcnext;
554 data_o <= r[rd];
555 we <= 1'b1;
556 address <= sp;
557 sp_mth <= SPDEC;
558 end
559
560 16'b1001_000x_xxxx_1111:
561 case (tstate)
562
563 0: begin
564 tstate <= 1;
565 pc <= pcnext;
566 address <= sp + 1;
567 sp_mth <= SPINC;
568 read <= 1;
569 end
570
571 1: begin
572 tstate <= 0;
573 alu <= 0;
574 op2 <= din;
575 reg_id <= rd;
576 reg_w <= 1;
577 end
578 endcase
579
580 16'b1111_101x_xxxx_0xxx: begin
581 pc <= pcnext;
582 alu <= 11;
583 op2 <= {sreg[7], r[rd][ opcode[2:0] ], sreg[5:0]};
584 sreg_w <= 1;
585 end
586
587 16'b1111_100x_xxxx_0xxx: begin
588 pc <= pcnext;
589 alu <= 22;
590 op1 <= r[rd];
591 op2 <= opcode[2:0];
592 reg_id <= rd;
593 reg_w <= 1;
594 end
595
596 16'b1001_10x0_xxxx_xxxx:
597 case (tstate)
598
599 0: begin
600 tstate <= 1;
601 read <= 1;
602 pc <= pcnext;
603 address <= opcode[7:3] + 16'h20;
604 end
605
606 1: begin
607 tstate <= 1'b0;
608 we <= 1'b1;
609 case (opcode[2:0])
610 0: data_o <= {din[7:1], opcode[9]};
611 1: data_o <= {din[7:2], opcode[9], din[0]};
612 2: data_o <= {din[7:3], opcode[9], din[1:0]};
613 3: data_o <= {din[7:4], opcode[9], din[2:0]};
614 4: data_o <= {din[7:5], opcode[9], din[3:0]};
615 5: data_o <= {din[7:6], opcode[9], din[4:0]};
616 6: data_o <= {din[ 7], opcode[9], din[5:0]};
617 7: data_o <= { opcode[9], din[6:0]};
618 endcase
619 end
620 endcase
621
622 16'b1001_11xx_xxxx_xxxx: begin
623 pc <= pcnext;
624 alu <= 23;
625 op1 <= r[rd];
626 op2 <= r[rr];
627 reg_wm <= 1;
628 end
629
630 16'b0000_0010_xxxx_xxxx: begin
631 pc <= pcnext;
632 alu <= 24;
633 op1 <= r[ {1'b1, opcode[7:4]} ];
634 op2 <= r[ {1'b1, opcode[3:0]} ];
635 reg_wm <= 1;
636 end
637
638 16'b0000_0011_0xxx_0xxx: begin
639 pc <= pcnext;
640 alu <= 25;
641 op1 <= r[ {2'b10, opcode[6:4]} ];
642 op2 <= r[ {2'b10, opcode[2:0]} ];
643 reg_wm <= 1;
644 end
645 endcase
646end
647
648always @(negedge clock)
649begin
650
651 if (reg_w) r[ reg_id ] <= alu_res;
652
653 if (sreg_w) sreg <= alu_sreg;
654
655 case (sp_mth)
656 SPDEC: sp <= sp - 1'b1;
657 SPINC: sp <= sp + 1'b1;
658 endcase
659
660 if (reg_ww) begin
661 case (reg_idw)
662 0: {r[25], r[24]} <= reg_ws ? resw : wb2;
663 1: {r[27], r[26]} <= reg_ws ? resw : wb2;
664 2: {r[29], r[28]} <= reg_ws ? resw : wb2;
665 3: {r[31], r[30]} <= reg_ws ? resw : wb2;
666 endcase
667 end
668
669 if (reg_wm) {r[1], r[0]} <= resw;
670
671 if (we) begin
672 case (address)
673
674 16'h005B: rampz <= data_o;
675 16'h005D: sp[ 7:0] <= data_o;
676 16'h005E: sp[15:8] <= data_o;
677 16'h005F: sreg <= data_o;
678
679 default: if (address < 16'h20) r[ address[4:0] ] <= data_o;
680 endcase
681 end
682end
683
684
685
686
687
688
689
690
691
692
693
694
695
696wire [7:0] sub = op1 - op2;
697wire [7:0] add = op1 + op2;
698wire [8:0] sbc = op1 - op2 - sreg[0];
699wire [7:0] adc = op1 + op2 + sreg[0];
700wire [7:0] lsr = {1'b0, op1[7:1]};
701wire [7:0] ror = {sreg[0], op1[7:1]};
702wire [7:0] asr = {op1[7], op1[7:1]};
703wire [7:0] neg = -op1;
704wire [7:0] inc = op1 + 1;
705wire [7:0] dec = op1 - 1;
706wire [7:0] com = ~op1;
707wire [7:0] swap = {op1[3:0], op1[7:4]};
708
709wire [15:0] adiw = op1w + op2;
710wire [15:0] sbiw = op1w - op2;
711wire [15:0] mul = op1[7:0] * op2[7:0];
712wire [15:0] mulsu = {{8{op1[7]}}, op1[7:0]} * op2[7:0];
713wire [15:0] muls = {{8{op1[7]}}, op1[7:0]} * {{8{op2[7]}}, op2[7:0]};
714
715wire add_flag_v = (op1[7] & op2[7] & !alu_res[7]) | (!op1[7] & !op2[7] & alu_res[7]);
716wire sub_flag_v = (op1[7] & !op2[7] & !alu_res[7]) | (!op1[7] & op2[7] & alu_res[7]);
717wire neg_flag_v = alu_res == 8'h80;
718
719wire add_flag_h = ( op1[3] & op2[3]) | (op2[3] & !alu_res[3]) | (!alu_res[3] & op1[3]);
720wire sub_flag_h = (!op1[3] & op2[3]) | (op2[3] & alu_res[3]) | ( alu_res[3] & !op1[3]);
721wire neg_flag_h = op1[3] | (op1[3] & alu_res[3]) | alu_res[3];
722
723wire adiw_c = op1w[15] & !resw[15];
724wire adiw_v = !op1w[15] & resw[15];
725
726wire [7:0] set_logic_flag = {
727 sreg[7],
728 sreg[6],
729 sreg[5],
730 alu_res[7],
731 1'b0,
732 alu_res[7],
733 alu_res[7:0] == 0,
734 sreg[0]
735};
736
737wire [7:0] set_subcarry_flag = {
738 sreg[7],
739 sreg[6],
740 sub_flag_h,
741 sub_flag_v ^ alu_res[7],
742 sub_flag_v,
743 alu_res[7],
744 (alu_res[7:0] == 0) & sreg[1],
745 sbc[8]
746};
747
748wire [7:0] set_subtract_flag = {
749 sreg[7],
750 sreg[6],
751 sub_flag_h,
752 sub_flag_v ^ alu_res[7],
753 sub_flag_v,
754 alu_res[7],
755 (alu_res[7:0] == 0),
756 op1 < op2
757};
758
759wire [7:0] set_com_flag = {
760 sreg[7],
761 sreg[6],
762 sreg[5],
763 alu_res[7],
764 1'b0,
765 alu_res[7],
766 (alu_res[7:0] == 0),
767 1'b1
768};
769
770wire [7:0] set_neg_flag = {
771 sreg[7],
772 sreg[6],
773 neg_flag_h,
774 neg_flag_v ^ alu_res[7],
775 neg_flag_v,
776 alu_res[7],
777 (alu_res[7:0] == 0),
778 op1 != 0
779};
780
781wire [7:0] set_add_flag = {
782 sreg[7],
783 sreg[6],
784 add_flag_h,
785 add_flag_v ^ alu_res[7],
786 add_flag_v,
787 alu_res[7],
788 (alu_res[7:0] == 0),
789 op1 + op2 >= 9'h100
790};
791
792wire [7:0] set_adc_flag = {
793 sreg[7],
794 sreg[6],
795 add_flag_h,
796 add_flag_v ^ alu_res[7],
797 add_flag_v,
798 alu_res[7],
799 (alu_res[7:0] == 0),
800 op1 + op2 + sreg[0] >= 9'h100
801};
802
803wire [7:0] set_lsr_flag = {
804 sreg[7],
805 sreg[6],
806 sreg[5],
807 op1[0],
808 alu_res[7] ^ op1[0],
809 alu_res[7],
810 (alu_res[7:0] == 0),
811 op1[0]
812};
813
814wire [7:0] set_inc_flag = {
815 sreg[7],
816 sreg[6],
817 sreg[5],
818 (alu_res == 8'h80) ^ alu_res[7],
819 (alu_res == 8'h80),
820 alu_res[7],
821 (alu_res[7:0] == 0),
822 sreg[0]
823};
824
825wire [7:0] set_dec_flag = {
826 sreg[7],
827 sreg[6],
828 sreg[5],
829 (alu_res == 8'h7F) ^ alu_res[7],
830 (alu_res == 8'h7F),
831 alu_res[7],
832 (alu_res[7:0] == 0),
833 sreg[0]
834};
835
836wire [7:0] set_adiw_flag = {
837 sreg[7],
838 sreg[6],
839 sreg[5],
840 adiw_v ^ resw[15],
841 adiw_v,
842 resw[15],
843 (resw[15:0] == 0),
844 adiw_c
845};
846
847wire [7:0] set_sbiw_flag = {
848 sreg[7],
849 sreg[6],
850 sreg[5],
851 adiw_c ^ resw[15],
852 adiw_c,
853 resw[15],
854 (resw[15:0] == 0),
855 adiw_v
856};
857
858wire [7:0] set_mul_flag = {sreg[7:2], (mul [15:0] == 0), mul [15]};
859wire [7:0] set_muls_flag = {sreg[7:2], (muls [15:0] == 0), muls [15]};
860wire [7:0] set_mulsu_flag = {sreg[7:2], (mulsu[15:0] == 0), mulsu[15]};
861
862always @(*)
863begin
864
865 alu_sreg = sreg;
866 case (alu)
867 0: begin alu_res = op2; end
868 1: begin alu_res = sbc[7:0]; alu_sreg = set_subcarry_flag; end
869 2: begin alu_res = sbc[7:0]; alu_sreg = set_subcarry_flag; end
870 3: begin alu_res = add; alu_sreg = set_add_flag; end
871 5: begin alu_res = sub; alu_sreg = set_subtract_flag; end
872 6: begin alu_res = sub; alu_sreg = set_subtract_flag; end
873 7: begin alu_res = adc; alu_sreg = set_adc_flag; end
874 8: begin alu_res = op1 & op2; alu_sreg = set_logic_flag; end
875 9: begin alu_res = op1 ^ op2; alu_sreg = set_logic_flag; end
876 10: begin alu_res = op1 | op2; alu_sreg = set_logic_flag; end
877 11: begin alu_sreg = op2; end
878 12: begin alu_res = com; alu_sreg = set_com_flag; end
879 13: begin alu_res = neg; alu_sreg = set_neg_flag; end
880 14: begin alu_res = swap; end
881 15: begin alu_res = inc; alu_sreg = set_inc_flag; end
882 16: begin alu_res = asr; alu_sreg = set_lsr_flag; end
883 17: begin alu_res = lsr; alu_sreg = set_lsr_flag; end
884 18: begin alu_res = ror; alu_sreg = set_lsr_flag; end
885 19: begin alu_res = dec; alu_sreg = set_dec_flag; end
886 20: begin resw = adiw; alu_sreg = set_adiw_flag; end
887 21: begin resw = sbiw; alu_sreg = set_sbiw_flag; end
888 22: begin
889 case (op2[2:0])
890 0: alu_res = {op1[7:1], sreg[6]};
891 1: alu_res = {op1[7:2], sreg[6], op1[0]};
892 2: alu_res = {op1[7:3], sreg[6], op1[1:0]};
893 3: alu_res = {op1[7:4], sreg[6], op1[2:0]};
894 4: alu_res = {op1[7:5], sreg[6], op1[3:0]};
895 5: alu_res = {op1[7:6], sreg[6], op1[4:0]};
896 6: alu_res = {op1[ 7], sreg[6], op1[5:0]};
897 7: alu_res = { sreg[6], op1[6:0]};
898 endcase
899 end
900 23: begin resw = mul; alu_sreg = set_mul_flag; end
901 24: begin resw = muls; alu_sreg = set_muls_flag; end
902 25: begin resw = mulsu; alu_sreg = set_mulsu_flag; end
903 default: alu_res = 8'hFF;
904 endcase
905end
906endmodule