URL
https://opencores.org/ocsvn/fpz8/fpz8/trunk
Subversion Repositories fpz8
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/CPU.bdf
21,7 → 21,7
(header "graphic" (version "1.3")) |
(pin |
(input) |
(rect 64 96 232 112) |
(rect 40 64 208 80) |
(text "INPUT" (rect 133 0 161 10)(font "Arial" (font_size 6))) |
(text "CLOCK" (rect 9 0 46 12)(font "Arial" )) |
(pt 168 8) |
34,11 → 34,11
(line (pt 117 12)(pt 121 8)(line_width 1)) |
) |
(text "VCC" (rect 136 7 156 17)(font "Arial" (font_size 6))) |
(annotation_block (location)(rect 16 112 64 128)) |
(annotation_block (location)(rect -8 64 40 80)) |
) |
(pin |
(input) |
(rect 64 112 232 128) |
(rect 40 80 208 96) |
(text "INPUT" (rect 133 0 161 10)(font "Arial" (font_size 6))) |
(text "RESET" (rect 9 0 44 12)(font "Arial" )) |
(pt 168 8) |
51,11 → 51,11
(line (pt 117 12)(pt 121 8)(line_width 1)) |
) |
(text "VCC" (rect 136 7 156 17)(font "Arial" (font_size 6))) |
(annotation_block (location)(rect 16 128 64 144)) |
(annotation_block (location)(rect -8 80 40 96)) |
) |
(pin |
(input) |
(rect 64 160 232 176) |
(rect 40 176 208 192) |
(text "INPUT" (rect 133 0 161 10)(font "Arial" (font_size 6))) |
(text "DBG_RX" (rect 5 0 48 12)(font "Arial" )) |
(pt 168 8) |
68,11 → 68,11
(line (pt 117 12)(pt 121 8)(line_width 1)) |
) |
(text "VCC" (rect 136 7 156 17)(font "Arial" (font_size 6))) |
(annotation_block (location)(rect 16 176 64 192)) |
(annotation_block (location)(rect -8 176 40 192)) |
) |
(pin |
(output) |
(rect 40 400 216 416) |
(rect 40 464 216 480) |
(text "OUTPUT" (rect 137 0 175 10)(font "Arial" (font_size 6))) |
(text "PAOUT[7..0]" (rect 5 0 67 12)(font "Arial" )) |
(pt 176 8) |
86,11 → 86,11
(line (pt 98 12)(pt 94 8)(line_width 1)) |
) |
(flipy) |
(annotation_block (location)(rect 216 416 264 528)) |
(annotation_block (location)(rect 48 480 96 592)) |
) |
(pin |
(output) |
(rect 56 176 232 192) |
(rect 40 160 216 176) |
(text "OUTPUT" (rect 137 6 175 16)(font "Arial" (font_size 6))) |
(text "DBG_TX" (rect 5 4 46 16)(font "Arial" )) |
(pt 176 8) |
104,323 → 104,338
(line (pt 98 4)(pt 94 8)(line_width 1)) |
) |
(rotate180) |
(annotation_block (location)(rect 232 192 280 208)) |
(annotation_block (location)(rect -8 160 40 176)) |
) |
(symbol |
(rect 968 88 1032 136) |
(text "AND2" (rect 39 38 63 48)(font "Arial" (font_size 6))) |
(text "inst8" (rect 38 -1 61 11)(font "Arial" )) |
(rect 608 -24 864 88) |
(text "altsyncram2" (rect 168 0 251 16)(font "Arial" (font_size 10))) |
(text "Program_Memory" (rect 8 100 95 112)(font "Arial" )) |
(port |
(pt 64 32) |
(pt 0 80) |
(input) |
(text "IN1" (rect 2 7 19 19)(font "Courier New" (bold))(invisible)) |
(text "IN1" (rect 45 29 62 41)(font "Courier New" (bold))(invisible)) |
(line (pt 64 32)(pt 50 32)(line_width 1)) |
(text "data[7..0]" (rect 0 0 53 14)(font "Arial" (font_size 8))) |
(text "data[7..0]" (rect 4 79 57 93)(font "Arial" (font_size 8))) |
(line (pt 0 80)(pt 112 80)(line_width 3)) |
) |
(port |
(pt 64 16) |
(pt 0 64) |
(input) |
(text "IN2" (rect 2 23 19 35)(font "Courier New" (bold))(invisible)) |
(text "IN2" (rect 45 13 62 25)(font "Courier New" (bold))(invisible)) |
(line (pt 64 16)(pt 50 16)(line_width 1)) |
(text "address[13..0]" (rect 0 0 82 14)(font "Arial" (font_size 8))) |
(text "address[13..0]" (rect 4 63 86 77)(font "Arial" (font_size 8))) |
(line (pt 0 64)(pt 112 64)(line_width 3)) |
) |
(port |
(pt 0 48) |
(input) |
(text "wren" (rect 0 0 30 14)(font "Arial" (font_size 8))) |
(text "wren" (rect 4 47 34 61)(font "Arial" (font_size 8))) |
(line (pt 0 48)(pt 112 48)(line_width 1)) |
) |
(port |
(pt 0 24) |
(input) |
(text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8))) |
(text "clock" (rect 4 23 33 37)(font "Arial" (font_size 8))) |
(line (pt 0 24)(pt 104 24)(line_width 1)) |
) |
(port |
(pt 256 80) |
(output) |
(text "OUT" (rect 48 15 65 27)(font "Courier New" (bold))(invisible)) |
(text "OUT" (rect -1 21 16 33)(font "Courier New" (bold))(invisible)) |
(line (pt 22 24)(pt 0 24)(line_width 1)) |
(text "q[7..0]" (rect 0 0 35 14)(font "Arial" (font_size 8))) |
(text "q[7..0]" (rect 223 79 258 93)(font "Arial" (font_size 8))) |
(line (pt 256 80)(pt 168 80)(line_width 3)) |
) |
(drawing |
(line (pt 50 36)(pt 34 36)(line_width 1)) |
(line (pt 50 11)(pt 33 11)(line_width 1)) |
(line (pt 50 36)(pt 50 11)(line_width 1)) |
(arc (pt 33 11)(pt 34 36)(rect 21 11 46 36)(line_width 1)) |
(text "16384 Word(s)" (rect 136 20 148 91)(font "Arial" )(vertical)) |
(text "RAM" (rect 149 47 161 70)(font "Arial" )(vertical)) |
(text "Block Type: AUTO" (rect 41 8 133 20)(font "Arial" )) |
(line (pt 128 88)(pt 168 88)(line_width 1)) |
(line (pt 168 88)(pt 168 32)(line_width 1)) |
(line (pt 168 32)(pt 128 32)(line_width 1)) |
(line (pt 128 32)(pt 128 88)(line_width 1)) |
(line (pt 112 85)(pt 120 85)(line_width 1)) |
(line (pt 120 85)(pt 120 73)(line_width 1)) |
(line (pt 120 73)(pt 112 73)(line_width 1)) |
(line (pt 112 73)(pt 112 85)(line_width 1)) |
(line (pt 112 78)(pt 114 76)(line_width 1)) |
(line (pt 114 76)(pt 112 74)(line_width 1)) |
(line (pt 104 76)(pt 112 76)(line_width 1)) |
(line (pt 120 80)(pt 128 80)(line_width 3)) |
(line (pt 112 69)(pt 120 69)(line_width 1)) |
(line (pt 120 69)(pt 120 57)(line_width 1)) |
(line (pt 120 57)(pt 112 57)(line_width 1)) |
(line (pt 112 57)(pt 112 69)(line_width 1)) |
(line (pt 112 62)(pt 114 60)(line_width 1)) |
(line (pt 114 60)(pt 112 58)(line_width 1)) |
(line (pt 104 60)(pt 112 60)(line_width 1)) |
(line (pt 120 64)(pt 128 64)(line_width 3)) |
(line (pt 112 53)(pt 120 53)(line_width 1)) |
(line (pt 120 53)(pt 120 41)(line_width 1)) |
(line (pt 120 41)(pt 112 41)(line_width 1)) |
(line (pt 112 41)(pt 112 53)(line_width 1)) |
(line (pt 112 46)(pt 114 44)(line_width 1)) |
(line (pt 114 44)(pt 112 42)(line_width 1)) |
(line (pt 104 44)(pt 112 44)(line_width 1)) |
(line (pt 120 48)(pt 128 48)(line_width 1)) |
(line (pt 104 76)(pt 104 23)(line_width 1)) |
) |
(rotate180) |
(flipx) |
) |
(symbol |
(rect 280 40 448 440) |
(rect 280 40 480 512) |
(text "fpz8_cpu_v1" (rect 5 0 68 12)(font "Arial" )) |
(text "inst" (rect 0 384 17 396)(font "Arial" )) |
(text "inst" (rect 8 456 25 468)(font "Arial" )) |
(port |
(pt 168 64) |
(pt 200 80) |
(input) |
(text "IDB[7..0]" (rect 0 0 44 12)(font "Arial" )) |
(text "IDB[7..0]" (rect 100 56 144 68)(font "Arial" )) |
(line (pt 152 64)(pt 168 64)(line_width 3)) |
(text "IDB[7..0]" (rect 132 72 176 84)(font "Arial" )) |
(line (pt 184 80)(pt 200 80)(line_width 3)) |
) |
(port |
(pt 168 144) |
(pt 200 160) |
(input) |
(text "MIDB[7..0]" (rect 0 0 53 12)(font "Arial" )) |
(text "MIDB[7..0]" (rect 96 136 149 148)(font "Arial" )) |
(line (pt 152 144)(pt 168 144)(line_width 3)) |
(text "FRIDB[7..0]" (rect 0 0 60 12)(font "Arial" )) |
(text "FRIDB[7..0]" (rect 116 152 176 164)(font "Arial" )) |
(line (pt 184 160)(pt 200 160)(line_width 3)) |
) |
(port |
(pt 168 176) |
(pt 200 224) |
(input) |
(text "RIDB[7..0]" (rect 0 0 53 12)(font "Arial" )) |
(text "RIDB[7..0]" (rect 96 168 149 180)(font "Arial" )) |
(line (pt 152 176)(pt 168 176)(line_width 3)) |
(text "RIDB[7..0]" (rect 123 216 176 228)(font "Arial" )) |
(line (pt 184 224)(pt 200 224)(line_width 3)) |
) |
(port |
(pt 168 368) |
(pt 200 432) |
(input) |
(text "INT0" (rect 0 0 23 12)(font "Arial" )) |
(text "INT0" (rect 121 360 144 372)(font "Arial" )) |
(line (pt 152 368)(pt 168 368)(line_width 1)) |
(text "INT0" (rect 153 424 176 436)(font "Arial" )) |
(line (pt 184 432)(pt 200 432)(line_width 1)) |
) |
(port |
(pt 168 352) |
(pt 200 416) |
(input) |
(text "INT1" (rect 0 0 23 12)(font "Arial" )) |
(text "INT1" (rect 121 344 144 356)(font "Arial" )) |
(line (pt 152 352)(pt 168 352)(line_width 1)) |
(text "INT1" (rect 153 408 176 420)(font "Arial" )) |
(line (pt 184 416)(pt 200 416)(line_width 1)) |
) |
(port |
(pt 168 336) |
(pt 200 400) |
(input) |
(text "INT2" (rect 0 0 23 12)(font "Arial" )) |
(text "INT2" (rect 121 328 144 340)(font "Arial" )) |
(line (pt 152 336)(pt 168 336)(line_width 1)) |
(text "INT2" (rect 153 392 176 404)(font "Arial" )) |
(line (pt 184 400)(pt 200 400)(line_width 1)) |
) |
(port |
(pt 168 320) |
(pt 200 384) |
(input) |
(text "INT3" (rect 0 0 23 12)(font "Arial" )) |
(text "INT3" (rect 121 312 144 324)(font "Arial" )) |
(line (pt 152 320)(pt 168 320)(line_width 1)) |
(text "INT3" (rect 153 376 176 388)(font "Arial" )) |
(line (pt 184 384)(pt 200 384)(line_width 1)) |
) |
(port |
(pt 168 304) |
(pt 200 368) |
(input) |
(text "INT4" (rect 0 0 23 12)(font "Arial" )) |
(text "INT4" (rect 121 296 144 308)(font "Arial" )) |
(line (pt 152 304)(pt 168 304)(line_width 1)) |
(text "INT4" (rect 153 360 176 372)(font "Arial" )) |
(line (pt 184 368)(pt 200 368)(line_width 1)) |
) |
(port |
(pt 168 288) |
(pt 200 352) |
(input) |
(text "INT5" (rect 0 0 23 12)(font "Arial" )) |
(text "INT5" (rect 121 280 144 292)(font "Arial" )) |
(line (pt 152 288)(pt 168 288)(line_width 1)) |
(text "INT5" (rect 153 344 176 356)(font "Arial" )) |
(line (pt 184 352)(pt 200 352)(line_width 1)) |
) |
(port |
(pt 168 272) |
(pt 200 336) |
(input) |
(text "INT6" (rect 0 0 23 12)(font "Arial" )) |
(text "INT6" (rect 121 264 144 276)(font "Arial" )) |
(line (pt 152 272)(pt 168 272)(line_width 1)) |
(text "INT6" (rect 153 328 176 340)(font "Arial" )) |
(line (pt 184 336)(pt 200 336)(line_width 1)) |
) |
(port |
(pt 0 128) |
(pt 200 320) |
(input) |
(text "INT7" (rect 0 0 23 12)(font "Arial" )) |
(text "INT7" (rect 153 312 176 324)(font "Arial" )) |
(line (pt 184 320)(pt 200 320)(line_width 1)) |
) |
(port |
(pt 0 144) |
(input) |
(text "DBG_RX" (rect 0 0 43 12)(font "Arial" )) |
(text "DBG_RX" (rect 21 123 64 135)(font "Arial" )) |
(line (pt 0 128)(pt 16 128)(line_width 1)) |
(text "DBG_RX" (rect 21 139 64 151)(font "Arial" )) |
(line (pt 0 144)(pt 16 144)(line_width 1)) |
) |
(port |
(pt 0 352) |
(pt 0 416) |
(input) |
(text "PAIN[7..0]" (rect 0 0 51 12)(font "Arial" )) |
(text "PAIN[7..0]" (rect 21 347 72 359)(font "Arial" )) |
(line (pt 0 352)(pt 16 352)(line_width 3)) |
(text "PAIN[7..0]" (rect 21 411 72 423)(font "Arial" )) |
(line (pt 0 416)(pt 16 416)(line_width 3)) |
) |
(port |
(pt 0 64) |
(pt 0 32) |
(input) |
(text "CLK" (rect 0 0 21 12)(font "Arial" )) |
(text "CLK" (rect 21 59 42 71)(font "Arial" )) |
(line (pt 0 64)(pt 16 64)(line_width 1)) |
(text "CLK" (rect 21 27 42 39)(font "Arial" )) |
(line (pt 0 32)(pt 16 32)(line_width 1)) |
) |
(port |
(pt 0 80) |
(pt 0 48) |
(input) |
(text "RESET" (rect 0 0 35 12)(font "Arial" )) |
(text "RESET" (rect 21 75 56 87)(font "Arial" )) |
(line (pt 0 80)(pt 16 80)(line_width 1)) |
(text "RESET" (rect 21 43 56 55)(font "Arial" )) |
(line (pt 0 48)(pt 16 48)(line_width 1)) |
) |
(port |
(pt 168 32) |
(pt 200 48) |
(output) |
(text "IAB[15..0]" (rect 0 0 49 12)(font "Arial" )) |
(text "IAB[15..0]" (rect 98 27 147 39)(font "Arial" )) |
(line (pt 168 32)(pt 152 32)(line_width 3)) |
(text "IAB[15..0]" (rect 24 0 73 12)(font "Arial" )) |
(text "IAB[15..0]" (rect 127 40 176 52)(font "Arial" )) |
(line (pt 200 48)(pt 184 48)(line_width 3)) |
) |
(port |
(pt 168 48) |
(pt 200 64) |
(output) |
(text "PWDB[7..0]" (rect 0 0 59 12)(font "Arial" )) |
(text "PWDB[7..0]" (rect 83 40 142 52)(font "Arial" )) |
(line (pt 168 48)(pt 152 48)(line_width 3)) |
(text "IWDB[7..0]" (rect 24 0 79 12)(font "Arial" )) |
(text "IWDB[7..0]" (rect 121 56 176 68)(font "Arial" )) |
(line (pt 200 64)(pt 184 64)(line_width 3)) |
) |
(port |
(pt 168 112) |
(pt 200 128) |
(output) |
(text "MAB[11..0]" (rect 0 0 54 12)(font "Arial" )) |
(text "MAB[11..0]" (rect 96 104 150 116)(font "Arial" )) |
(line (pt 168 112)(pt 152 112)(line_width 3)) |
(text "FRAB[11..0]" (rect 24 0 85 12)(font "Arial" )) |
(text "FRAB[11..0]" (rect 115 120 176 132)(font "Arial" )) |
(line (pt 200 128)(pt 184 128)(line_width 3)) |
) |
(port |
(pt 168 128) |
(pt 200 144) |
(output) |
(text "MODB[7..0]" (rect 0 0 57 12)(font "Arial" )) |
(text "MODB[7..0]" (rect 96 120 153 132)(font "Arial" )) |
(line (pt 168 128)(pt 152 128)(line_width 3)) |
(text "FRODB[7..0]" (rect 24 0 88 12)(font "Arial" )) |
(text "FRODB[7..0]" (rect 112 136 176 148)(font "Arial" )) |
(line (pt 200 144)(pt 184 144)(line_width 3)) |
) |
(port |
(pt 168 160) |
(pt 200 208) |
(output) |
(text "RODB[7..0]" (rect 0 0 57 12)(font "Arial" )) |
(text "RODB[7..0]" (rect 96 152 153 164)(font "Arial" )) |
(line (pt 168 160)(pt 152 160)(line_width 3)) |
(text "RODB[7..0]" (rect 24 0 81 12)(font "Arial" )) |
(text "RODB[7..0]" (rect 119 200 176 212)(font "Arial" )) |
(line (pt 200 208)(pt 184 208)(line_width 3)) |
) |
(port |
(pt 168 80) |
(pt 200 96) |
(output) |
(text "PGM_WR" (rect 0 0 48 12)(font "Arial" )) |
(text "PGM_WR" (rect 94 72 142 84)(font "Arial" )) |
(line (pt 168 80)(pt 152 80)(line_width 1)) |
(text "PGM_WR" (rect 24 0 72 12)(font "Arial" )) |
(text "PGM_WR" (rect 128 88 176 100)(font "Arial" )) |
(line (pt 200 96)(pt 184 96)(line_width 1)) |
) |
(port |
(pt 168 208) |
(pt 200 192) |
(output) |
(text "WR" (rect 0 0 18 12)(font "Arial" )) |
(text "WR" (rect 124 200 142 212)(font "Arial" )) |
(line (pt 168 208)(pt 152 208)(line_width 1)) |
(text "WR" (rect 24 0 42 12)(font "Arial" )) |
(text "WR" (rect 158 184 176 196)(font "Arial" )) |
(line (pt 200 192)(pt 184 192)(line_width 1)) |
) |
(port |
(pt 168 240) |
(pt 200 240) |
(output) |
(text "REG_SEL" (rect 0 0 49 12)(font "Arial" )) |
(text "REG_SEL" (rect 93 232 142 244)(font "Arial" )) |
(line (pt 168 240)(pt 152 240)(line_width 1)) |
(text "REG_SEL" (rect 24 0 73 12)(font "Arial" )) |
(text "REG_SEL" (rect 127 232 176 244)(font "Arial" )) |
(line (pt 200 240)(pt 184 240)(line_width 1)) |
) |
(port |
(pt 168 224) |
(pt 200 176) |
(output) |
(text "MEM_SEL" (rect 0 0 49 12)(font "Arial" )) |
(text "MEM_SEL" (rect 93 216 142 228)(font "Arial" )) |
(line (pt 168 224)(pt 152 224)(line_width 1)) |
(text "MEM_SEL" (rect 24 0 73 12)(font "Arial" )) |
(text "MEM_SEL" (rect 127 168 176 180)(font "Arial" )) |
(line (pt 200 176)(pt 184 176)(line_width 1)) |
) |
(port |
(pt 0 144) |
(pt 0 128) |
(output) |
(text "DBG_TX" (rect 0 0 41 12)(font "Arial" )) |
(text "DBG_TX" (rect 24 136 65 148)(font "Arial" )) |
(line (pt 16 144)(pt 0 144)(line_width 1)) |
(text "DBG_TX" (rect 24 0 65 12)(font "Arial" )) |
(text "DBG_TX" (rect 24 120 65 132)(font "Arial" )) |
(line (pt 16 128)(pt 0 128)(line_width 1)) |
) |
(port |
(pt 0 368) |
(pt 0 432) |
(output) |
(text "PAOUT[7..0]" (rect 0 0 62 12)(font "Arial" )) |
(text "PAOUT[7..0]" (rect 24 360 86 372)(font "Arial" )) |
(line (pt 16 368)(pt 0 368)(line_width 3)) |
(text "PAOUT[7..0]" (rect 24 0 86 12)(font "Arial" )) |
(text "PAOUT[7..0]" (rect 24 424 86 436)(font "Arial" )) |
(line (pt 16 432)(pt 0 432)(line_width 3)) |
) |
(port |
(pt 0 48) |
(pt 200 256) |
(output) |
(text "CLK_OUT" (rect 0 0 49 12)(font "Arial" )) |
(text "CLK_OUT" (rect 24 40 73 52)(font "Arial" )) |
(line (pt 16 48)(pt 0 48)(line_width 1)) |
(text "CLK_OUT" (rect 24 0 73 12)(font "Arial" )) |
(text "CLK_OUT" (rect 127 248 176 260)(font "Arial" )) |
(line (pt 200 256)(pt 184 256)(line_width 1)) |
) |
(port |
(pt 0 32) |
(pt 200 32) |
(output) |
(text "CLK_OUTN" (rect 0 0 57 12)(font "Arial" )) |
(text "CLK_OUTN" (rect 24 24 81 36)(font "Arial" )) |
(line (pt 16 32)(pt 0 32)(line_width 1)) |
(text "CLK_OUTN" (rect 24 0 81 12)(font "Arial" )) |
(text "CLK_OUTN" (rect 119 24 176 36)(font "Arial" )) |
(line (pt 200 32)(pt 184 32)(line_width 1)) |
) |
(port |
(pt 0 96) |
(pt 200 288) |
(output) |
(text "STOP" (rect 0 0 28 12)(font "Arial" )) |
(text "STOP" (rect 24 88 52 100)(font "Arial" )) |
(line (pt 16 96)(pt 0 96)(line_width 1)) |
(text "STOP" (rect 24 0 52 12)(font "Arial" )) |
(text "STOP" (rect 148 280 176 292)(font "Arial" )) |
(line (pt 200 288)(pt 184 288)(line_width 1)) |
) |
(port |
(pt 200 272) |
(output) |
(text "RESET_OUT" (rect 24 0 87 12)(font "Arial" )) |
(text "RESET_OUT" (rect 113 264 176 276)(font "Arial" )) |
(line (pt 200 272)(pt 184 272)(line_width 1)) |
) |
(drawing |
(rectangle (rect 16 16 152 384)(line_width 1)) |
(rectangle (rect 16 16 184 448)(line_width 1)) |
) |
) |
(symbol |
(rect 1000 -24 1256 88) |
(text "altsyncram1" (rect 93 1 176 17)(font "Arial" (font_size 10))) |
(text "File_Registers" (rect 8 96 78 108)(font "Arial" )) |
(rect 888 48 936 112) |
(text "AND2" (rect 0 39 10 63)(font "Arial" (font_size 6))(vertical)) |
(text "inst8" (rect 37 38 49 61)(font "Arial" )(vertical)) |
(port |
(pt 0 32) |
(pt 16 64) |
(input) |
(text "data[7..0]" (rect 0 0 53 14)(font "Arial" (font_size 8))) |
(text "data[7..0]" (rect 4 19 57 33)(font "Arial" (font_size 8))) |
(line (pt 0 32)(pt 112 32)(line_width 3)) |
(text "IN1" (rect 2 7 19 19)(font "Courier New" (bold))(invisible)) |
(text "IN1" (rect 7 45 19 62)(font "Courier New" (bold))(vertical)(invisible)) |
(line (pt 16 64)(pt 16 50)(line_width 1)) |
) |
(port |
(pt 0 48) |
(pt 32 64) |
(input) |
(text "address[10..0]" (rect 0 0 82 14)(font "Arial" (font_size 8))) |
(text "address[10..0]" (rect 4 35 86 49)(font "Arial" (font_size 8))) |
(line (pt 0 48)(pt 112 48)(line_width 3)) |
(text "IN2" (rect 2 23 19 35)(font "Courier New" (bold))(invisible)) |
(text "IN2" (rect 23 45 35 62)(font "Courier New" (bold))(vertical)(invisible)) |
(line (pt 32 64)(pt 32 50)(line_width 1)) |
) |
(port |
(pt 0 64) |
(input) |
(text "wren" (rect 0 0 30 14)(font "Arial" (font_size 8))) |
(text "wren" (rect 4 51 34 65)(font "Arial" (font_size 8))) |
(line (pt 0 64)(pt 112 64)(line_width 1)) |
) |
(port |
(pt 0 88) |
(input) |
(text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8))) |
(text "clock" (rect 4 75 33 89)(font "Arial" (font_size 8))) |
(line (pt 0 88)(pt 104 88)(line_width 1)) |
) |
(port |
(pt 256 32) |
(pt 24 0) |
(output) |
(text "q[7..0]" (rect 0 0 35 14)(font "Arial" (font_size 8))) |
(text "q[7..0]" (rect 223 19 258 33)(font "Arial" (font_size 8))) |
(line (pt 256 32)(pt 168 32)(line_width 3)) |
(text "OUT" (rect 48 15 65 27)(font "Courier New" (bold))(invisible)) |
(text "OUT" (rect 15 -1 27 16)(font "Courier New" (bold))(vertical)(invisible)) |
(line (pt 24 22)(pt 24 0)(line_width 1)) |
) |
(drawing |
(text "2048 Word(s)" (rect 136 24 148 90)(font "Arial" )(vertical)) |
(text "RAM" (rect 149 42 161 65)(font "Arial" )(vertical)) |
(text "Block Type: AUTO" (rect 41 92 133 104)(font "Arial" )) |
(line (pt 128 24)(pt 168 24)(line_width 1)) |
(line (pt 168 24)(pt 168 80)(line_width 1)) |
(line (pt 168 80)(pt 128 80)(line_width 1)) |
(line (pt 128 80)(pt 128 24)(line_width 1)) |
(line (pt 112 27)(pt 120 27)(line_width 1)) |
(line (pt 120 27)(pt 120 39)(line_width 1)) |
(line (pt 120 39)(pt 112 39)(line_width 1)) |
(line (pt 112 39)(pt 112 27)(line_width 1)) |
(line (pt 112 34)(pt 114 36)(line_width 1)) |
(line (pt 114 36)(pt 112 38)(line_width 1)) |
(line (pt 104 36)(pt 112 36)(line_width 1)) |
(line (pt 120 32)(pt 128 32)(line_width 3)) |
(line (pt 112 43)(pt 120 43)(line_width 1)) |
(line (pt 120 43)(pt 120 55)(line_width 1)) |
(line (pt 120 55)(pt 112 55)(line_width 1)) |
(line (pt 112 55)(pt 112 43)(line_width 1)) |
(line (pt 112 50)(pt 114 52)(line_width 1)) |
(line (pt 114 52)(pt 112 54)(line_width 1)) |
(line (pt 104 52)(pt 112 52)(line_width 1)) |
(line (pt 120 48)(pt 128 48)(line_width 3)) |
(line (pt 112 59)(pt 120 59)(line_width 1)) |
(line (pt 120 59)(pt 120 71)(line_width 1)) |
(line (pt 120 71)(pt 112 71)(line_width 1)) |
(line (pt 112 71)(pt 112 59)(line_width 1)) |
(line (pt 112 66)(pt 114 68)(line_width 1)) |
(line (pt 114 68)(pt 112 70)(line_width 1)) |
(line (pt 104 68)(pt 112 68)(line_width 1)) |
(line (pt 120 64)(pt 128 64)(line_width 1)) |
(line (pt 104 36)(pt 104 89)(line_width 1)) |
(line (pt 12 50)(pt 12 34)(line_width 1)) |
(line (pt 37 50)(pt 37 33)(line_width 1)) |
(line (pt 12 50)(pt 37 50)(line_width 1)) |
(arc (pt 37 33)(pt 12 34)(rect 12 21 37 46)(line_width 1)) |
) |
(rotate90) |
) |
(symbol |
(rect 608 -24 864 88) |
(text "altsyncram2" (rect 168 0 251 16)(font "Arial" (font_size 10))) |
(text "Program_Memory" (rect 8 100 95 112)(font "Arial" )) |
(rect 1000 -24 1256 88) |
(text "altsyncram1" (rect 168 0 251 16)(font "Arial" (font_size 10))) |
(text "File_Registers" (rect 8 100 78 112)(font "Arial" )) |
(port |
(pt 0 80) |
(input) |
431,8 → 446,8
(port |
(pt 0 64) |
(input) |
(text "address[13..0]" (rect 0 0 82 14)(font "Arial" (font_size 8))) |
(text "address[13..0]" (rect 4 63 86 77)(font "Arial" (font_size 8))) |
(text "address[10..0]" (rect 0 0 82 14)(font "Arial" (font_size 8))) |
(text "address[10..0]" (rect 4 63 86 77)(font "Arial" (font_size 8))) |
(line (pt 0 64)(pt 112 64)(line_width 3)) |
) |
(port |
457,7 → 472,7
(line (pt 256 80)(pt 168 80)(line_width 3)) |
) |
(drawing |
(text "16384 Word(s)" (rect 136 20 148 91)(font "Arial" )(vertical)) |
(text "2048 Word(s)" (rect 136 22 148 88)(font "Arial" )(vertical)) |
(text "RAM" (rect 149 47 161 70)(font "Arial" )(vertical)) |
(text "Block Type: AUTO" (rect 41 8 133 20)(font "Arial" )) |
(line (pt 128 88)(pt 168 88)(line_width 1)) |
492,199 → 507,424
) |
(flipx) |
) |
(symbol |
(rect 984 240 1160 496) |
(text "fpz8_timer" (rect 5 0 56 12)(font "Arial" )) |
(text "inst3" (rect 8 240 31 252)(font "Arial" )) |
(port |
(pt 0 48) |
(input) |
(text "RAB[11..0]" (rect 0 0 54 12)(font "Arial" )) |
(text "RAB[11..0]" (rect 21 40 75 52)(font "Arial" )) |
(line (pt 0 48)(pt 16 48)(line_width 3)) |
) |
(port |
(pt 0 64) |
(input) |
(text "RIDB[7..0]" (rect 0 0 53 12)(font "Arial" )) |
(text "RIDB[7..0]" (rect 21 56 74 68)(font "Arial" )) |
(line (pt 0 64)(pt 16 64)(line_width 3)) |
) |
(port |
(pt 176 80) |
(input) |
(text "SIDB[7..0]" (rect 0 0 51 12)(font "Arial" )) |
(text "SIDB[7..0]" (rect 101 72 152 84)(font "Arial" )) |
(line (pt 160 80)(pt 176 80)(line_width 3)) |
) |
(port |
(pt 0 96) |
(input) |
(text "REG_SEL" (rect 0 0 49 12)(font "Arial" )) |
(text "REG_SEL" (rect 21 88 70 100)(font "Arial" )) |
(line (pt 0 96)(pt 16 96)(line_width 1)) |
) |
(port |
(pt 0 32) |
(input) |
(text "WR" (rect 0 0 18 12)(font "Arial" )) |
(text "WR" (rect 21 24 39 36)(font "Arial" )) |
(line (pt 0 32)(pt 16 32)(line_width 1)) |
) |
(port |
(pt 0 112) |
(input) |
(text "CLK_IN" (rect 0 0 38 12)(font "Arial" )) |
(text "CLK_IN" (rect 21 104 59 116)(font "Arial" )) |
(line (pt 0 112)(pt 16 112)(line_width 1)) |
) |
(port |
(pt 0 144) |
(input) |
(text "STOP" (rect 0 0 28 12)(font "Arial" )) |
(text "STOP" (rect 21 136 49 148)(font "Arial" )) |
(line (pt 0 144)(pt 16 144)(line_width 1)) |
) |
(port |
(pt 176 216) |
(input) |
(text "TMR_IN" (rect 0 0 40 12)(font "Arial" )) |
(text "TMR_IN" (rect 112 208 152 220)(font "Arial" )) |
(line (pt 160 216)(pt 176 216)(line_width 1)) |
) |
(port |
(pt 176 32) |
(input) |
(text "TMR_ID[1..0]" (rect 0 0 66 12)(font "Arial" )) |
(text "TMR_ID[1..0]" (rect 86 24 152 36)(font "Arial" )) |
(line (pt 160 32)(pt 176 32)(line_width 3)) |
) |
(port |
(pt 0 128) |
(input) |
(text "RESET" (rect 0 0 35 12)(font "Arial" )) |
(text "RESET" (rect 21 120 56 132)(font "Arial" )) |
(line (pt 0 128)(pt 16 128)(line_width 1)) |
) |
(port |
(pt 0 80) |
(output) |
(text "RODB[7..0]" (rect 0 0 57 12)(font "Arial" )) |
(text "RODB[7..0]" (rect 24 72 81 84)(font "Arial" )) |
(line (pt 16 80)(pt 0 80)(line_width 3)) |
) |
(port |
(pt 0 216) |
(output) |
(text "INT" (rect 0 0 17 12)(font "Arial" )) |
(text "INT" (rect 24 208 41 220)(font "Arial" )) |
(line (pt 16 216)(pt 0 216)(line_width 1)) |
) |
(port |
(pt 176 200) |
(output) |
(text "TMR_OUT" (rect 0 0 50 12)(font "Arial" )) |
(text "TMR_OUT" (rect 105 195 155 207)(font "Arial" )) |
(line (pt 176 200)(pt 160 200)(line_width 1)) |
) |
(drawing |
(rectangle (rect 16 16 160 232)(line_width 1)) |
) |
) |
(symbol |
(rect 1184 280 1216 312) |
(text "GND" (rect 8 16 29 26)(font "Arial" (font_size 6))) |
(text "inst4" (rect 3 21 26 33)(font "Arial" )(invisible)) |
(port |
(pt 16 0) |
(output) |
(text "1" (rect 18 0 23 12)(font "Courier New" (bold))(invisible)) |
(text "1" (rect 18 0 23 12)(font "Courier New" (bold))(invisible)) |
(line (pt 16 8)(pt 16 0)(line_width 1)) |
) |
(drawing |
(line (pt 8 8)(pt 16 16)(line_width 1)) |
(line (pt 16 16)(pt 24 8)(line_width 1)) |
(line (pt 8 8)(pt 24 8)(line_width 1)) |
) |
) |
(connector |
(pt 280 72) |
(pt 208 72) |
) |
(connector |
(pt 280 88) |
(pt 208 88) |
) |
(connector |
(pt 216 472) |
(pt 280 472) |
(bus) |
) |
(connector |
(pt 280 168) |
(pt 216 168) |
) |
(connector |
(pt 280 184) |
(pt 208 184) |
) |
(connector |
(pt 1000 0) |
(pt 984 0) |
) |
(connector |
(pt 984 0) |
(pt 984 -48) |
) |
(connector |
(pt 984 -48) |
(pt 504 -48) |
) |
(connector |
(pt 504 72) |
(pt 480 72) |
) |
(connector |
(pt 608 0) |
(pt 504 0) |
) |
(connector |
(pt 504 -48) |
(pt 504 0) |
) |
(connector |
(pt 504 0) |
(pt 504 72) |
) |
(connector |
(pt 480 120) |
(pt 880 120) |
(bus) |
) |
(connector |
(pt 880 120) |
(pt 880 56) |
(bus) |
) |
(connector |
(pt 880 56) |
(pt 864 56) |
(bus) |
) |
(connector |
(pt 584 -40) |
(pt 888 -40) |
(pt 480 136) |
(pt 584 136) |
) |
(connector |
(pt 584 -40) |
(pt 584 0) |
(pt 584 136) |
(pt 584 24) |
) |
(connector |
(pt 968 112) |
(pt 928 112) |
(pt 608 24) |
(pt 584 24) |
) |
(connector |
(pt 888 -40) |
(pt 888 64) |
(pt 480 104) |
(pt 552 104) |
(bus) |
) |
(connector |
(pt 928 112) |
(pt 928 40) |
(pt 552 104) |
(pt 552 56) |
(bus) |
) |
(connector |
(pt 1328 8) |
(pt 1256 8) |
(pt 608 56) |
(pt 552 56) |
(bus) |
) |
(connector |
(pt 904 8) |
(pt 904 168) |
(pt 536 88) |
(pt 536 40) |
(bus) |
) |
(connector |
(pt 904 8) |
(pt 1000 8) |
(text "IAB[15..0]" (rect 480 72 529 84)(font "Arial" )) |
(pt 480 88) |
(pt 536 88) |
(bus) |
) |
(connector |
(text "MAB[10..0]" (rect 936 8 990 20)(font "Arial" )) |
(pt 920 24) |
(pt 1000 24) |
(text "IAB[13..0]" (rect 530 24 579 36)(font "Arial" )) |
(pt 608 40) |
(pt 536 40) |
(bus) |
) |
(connector |
(pt 928 40) |
(pt 1000 40) |
(pt 480 216) |
(pt 904 216) |
) |
(connector |
(pt 888 64) |
(pt 1000 64) |
(pt 904 216) |
(pt 904 112) |
) |
(connector |
(pt 232 120) |
(pt 280 120) |
(pt 480 232) |
(pt 920 232) |
) |
(connector |
(pt 256 0) |
(pt 584 0) |
(pt 1000 24) |
(pt 912 24) |
) |
(connector |
(pt 584 0) |
(pt 608 0) |
(pt 912 24) |
(pt 912 48) |
) |
(connector |
(pt 448 104) |
(pt 880 104) |
(pt 480 184) |
(pt 992 184) |
(bus) |
) |
(connector |
(pt 880 104) |
(pt 880 56) |
(pt 992 184) |
(pt 992 56) |
(bus) |
) |
(connector |
(pt 448 88) |
(pt 592 88) |
(pt 992 56) |
(pt 1000 56) |
(bus) |
) |
(connector |
(pt 592 88) |
(pt 592 56) |
(text "FRAB[10..0]" (rect 930 24 991 36)(font "Arial" )) |
(pt 1000 40) |
(pt 976 40) |
(bus) |
) |
(connector |
(pt 592 56) |
(pt 608 56) |
(pt 976 40) |
(pt 976 168) |
(bus) |
) |
(connector |
(pt 504 40) |
(pt 504 72) |
(pt 480 200) |
(pt 1272 200) |
(bus) |
) |
(connector |
(pt 448 120) |
(pt 568 120) |
(pt 1272 200) |
(pt 1272 56) |
(bus) |
) |
(connector |
(pt 568 120) |
(pt 568 24) |
(pt 1272 56) |
(pt 1256 56) |
(bus) |
) |
(connector |
(pt 568 24) |
(pt 608 24) |
(pt 480 248) |
(pt 872 248) |
(bus) |
) |
(connector |
(text "IAB[13..0]" (rect 514 24 563 36)(font "Arial" )) |
(pt 608 40) |
(pt 504 40) |
(pt 480 264) |
(pt 856 264) |
(bus) |
) |
(connector |
(pt 1032 120) |
(pt 1048 120) |
(pt 480 280) |
(pt 840 280) |
) |
(connector |
(pt 448 248) |
(pt 1048 248) |
(pt 480 296) |
(pt 824 296) |
) |
(connector |
(pt 1328 8) |
(pt 1328 184) |
(pt 480 312) |
(pt 808 312) |
) |
(connector |
(pt 480 328) |
(pt 792 328) |
) |
(connector |
(pt 776 360) |
(pt 480 360) |
) |
(connector |
(pt 888 168) |
(pt 888 288) |
(bus) |
) |
(connector |
(pt 920 24) |
(pt 920 152) |
(pt 872 248) |
(pt 872 304) |
(bus) |
) |
(connector |
(pt 448 168) |
(pt 904 168) |
(pt 856 264) |
(pt 856 320) |
(bus) |
) |
(connector |
(pt 448 184) |
(pt 1328 184) |
(pt 840 280) |
(pt 840 336) |
) |
(connector |
(pt 824 296) |
(pt 824 352) |
) |
(connector |
(pt 808 312) |
(pt 808 368) |
) |
(connector |
(pt 792 328) |
(pt 792 384) |
) |
(connector |
(pt 920 112) |
(pt 920 232) |
) |
(connector |
(pt 920 232) |
(pt 920 272) |
) |
(connector |
(text "FRAB[11..0]" (rect 490 152 551 164)(font "Arial" )) |
(pt 480 168) |
(pt 888 168) |
(bus) |
) |
(connector |
(pt 1032 104) |
(pt 1064 104) |
(pt 888 168) |
(pt 976 168) |
(bus) |
) |
(connector |
(pt 448 264) |
(pt 1064 264) |
(pt 888 288) |
(pt 984 288) |
(bus) |
) |
(connector |
(pt 216 408) |
(pt 280 408) |
(pt 872 304) |
(pt 984 304) |
(bus) |
) |
(connector |
(pt 232 168) |
(pt 280 168) |
(pt 840 336) |
(pt 984 336) |
) |
(connector |
(pt 232 184) |
(pt 280 184) |
(pt 920 272) |
(pt 984 272) |
) |
(connector |
(pt 232 104) |
(pt 280 104) |
(pt 824 352) |
(pt 984 352) |
) |
(connector |
(pt 280 72) |
(pt 256 72) |
(pt 792 384) |
(pt 984 384) |
) |
(connector |
(pt 256 72) |
(pt 256 0) |
(pt 808 368) |
(pt 984 368) |
) |
(connector |
(pt 1048 120) |
(pt 1048 248) |
(pt 856 320) |
(pt 984 320) |
(bus) |
) |
(connector |
(pt 1064 104) |
(pt 1064 264) |
(pt 984 456) |
(pt 776 456) |
) |
(connector |
(text "MAB[11..0]" (rect 458 136 512 148)(font "Arial" )) |
(pt 448 152) |
(pt 920 152) |
(pt 776 360) |
(pt 776 456) |
) |
(connector |
(pt 1200 272) |
(pt 1160 272) |
(bus) |
) |
(connector |
(text "IAB[15..0]" (rect 458 56 507 68)(font "Arial" )) |
(pt 504 72) |
(pt 448 72) |
(pt 1200 272) |
(pt 1200 280) |
(bus) |
) |
(junction (pt 584 0)) |
(junction (pt 504 0)) |
(junction (pt 920 232)) |
(junction (pt 888 168)) |
/FPz8.qpf
18,12 → 18,12
# |
# Quartus II |
# Version 9.1 Build 350 03/24/2010 Service Pack 2 SJ Web Edition |
# Date created = 09:51:04 November 11, 2016 |
# Date created = 18:30:06 November 12, 2016 |
# |
# -------------------------------------------------------------------------- # |
|
QUARTUS_VERSION = "9.1" |
DATE = "09:51:04 November 11, 2016" |
DATE = "18:30:06 November 12, 2016" |
|
# Revisions |
|
/FPz8_Cyclone_IV.asm.rpt
1,5 → 1,5
Assembler report for FPz8_Cyclone_IV |
Fri Nov 11 10:25:02 2016 |
Fri Nov 25 10:11:56 2016 |
Quartus II Version 9.1 Build 350 03/24/2010 Service Pack 2 SJ Web Edition |
|
|
38,7 → 38,7
+---------------------------------------------------------------+ |
; Assembler Summary ; |
+-----------------------+---------------------------------------+ |
; Assembler Status ; Successful - Fri Nov 11 10:25:02 2016 ; |
; Assembler Status ; Successful - Fri Nov 25 10:11:56 2016 ; |
; Revision Name ; FPz8_Cyclone_IV ; |
; Top-level Entity Name ; CPU ; |
; Family ; Cyclone IV E ; |
95,7 → 95,7
+----------------+-------------------------------------------+ |
; Device ; EP4CE6E22C8 ; |
; JTAG usercode ; 0xFFFFFFFF ; |
; Checksum ; 0x003E6EEA ; |
; Checksum ; 0x00400465 ; |
+----------------+-------------------------------------------+ |
|
|
106,7 → 106,7
+--------------------+---------------------------------------+ |
; Device ; EPCS4 ; |
; JTAG usercode ; 0x00000000 ; |
; Checksum ; 0x06290CB3 ; |
; Checksum ; 0x061C943C ; |
; Compression Ratio ; 2 ; |
+--------------------+---------------------------------------+ |
|
117,14 → 117,14
Info: ******************************************************************* |
Info: Running Quartus II Assembler |
Info: Version 9.1 Build 350 03/24/2010 Service Pack 2 SJ Web Edition |
Info: Processing started: Fri Nov 11 10:25:00 2016 |
Info: Processing started: Fri Nov 25 10:11:52 2016 |
Info: Command: quartus_asm --read_settings_files=off --write_settings_files=off FPz8 -c FPz8_Cyclone_IV |
Info: Writing out detailed assembly data for power analysis |
Info: Assembler is generating device programming files |
Info: Quartus II Assembler was successful. 0 errors, 0 warnings |
Info: Peak virtual memory: 202 megabytes |
Info: Processing ended: Fri Nov 11 10:25:02 2016 |
Info: Elapsed time: 00:00:02 |
Info: Total CPU time (on all processors): 00:00:02 |
Info: Processing ended: Fri Nov 25 10:11:56 2016 |
Info: Elapsed time: 00:00:04 |
Info: Total CPU time (on all processors): 00:00:03 |
|
|
/FPz8_Cyclone_IV.done
1,14 → 117,14
Fri Nov 11 10:25:15 2016 |
Fri Nov 25 10:12:13 2016 |
/FPz8_Cyclone_IV.flow.rpt
1,5 → 1,5
Flow report for FPz8_Cyclone_IV |
Fri Nov 11 10:25:14 2016 |
Fri Nov 25 10:12:12 2016 |
Quartus II Version 9.1 Build 350 03/24/2010 Service Pack 2 SJ Web Edition |
|
|
38,7 → 38,7
+-----------------------------------------------------------------------------------+ |
; Flow Summary ; |
+------------------------------------+----------------------------------------------+ |
; Flow Status ; Successful - Fri Nov 11 10:25:02 2016 ; |
; Flow Status ; Successful - Fri Nov 25 10:11:56 2016 ; |
; Quartus II Version ; 9.1 Build 350 03/24/2010 SP 2 SJ Web Edition ; |
; Revision Name ; FPz8_Cyclone_IV ; |
; Top-level Entity Name ; CPU ; |
46,10 → 46,10
; Device ; EP4CE6E22C8 ; |
; Timing Models ; Preliminary ; |
; Met timing requirements ; N/A ; |
; Total logic elements ; 4,884 / 6,272 ( 78 % ) ; |
; Total combinational functions ; 4,854 / 6,272 ( 77 % ) ; |
; Dedicated logic registers ; 494 / 6,272 ( 8 % ) ; |
; Total registers ; 494 ; |
; Total logic elements ; 5,009 / 6,272 ( 80 % ) ; |
; Total combinational functions ; 4,952 / 6,272 ( 79 % ) ; |
; Dedicated logic registers ; 584 / 6,272 ( 9 % ) ; |
; Total registers ; 584 ; |
; Total pins ; 12 / 92 ( 13 % ) ; |
; Total virtual pins ; 0 ; |
; Total memory bits ; 147,456 / 276,480 ( 53 % ) ; |
63,7 → 63,7
+-------------------+---------------------+ |
; Option ; Setting ; |
+-------------------+---------------------+ |
; Start date & time ; 11/11/2016 10:21:52 ; |
; Start date & time ; 11/25/2016 10:08:19 ; |
; Main task ; Compilation ; |
; Revision Name ; FPz8_Cyclone_IV ; |
+-------------------+---------------------+ |
75,7 → 75,7
; Assignment Name ; Value ; Default Value ; Entity Name ; Section Id ; |
+------------------------------------+------------------------------------------------------------------+------------------------------+-------------+----------------+ |
; ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ; On ; Off ; -- ; -- ; |
; COMPILER_SIGNATURE_ID ; 8796753254599.147886691203264 ; -- ; -- ; -- ; |
; COMPILER_SIGNATURE_ID ; 8796753254599.148007569904036 ; -- ; -- ; -- ; |
; FITTER_EFFORT ; Standard Fit ; Auto Fit ; -- ; -- ; |
; INCREMENTAL_COMPILATION ; Off ; FULL_INCREMENTAL_COMPILATION ; -- ; -- ; |
; IP_TOOL_NAME ; ALTSYNCRAM ; -- ; -- ; -- ; |
108,11 → 108,11
+---------------------------+--------------+-------------------------+---------------------+------------------------------------+ |
; Module Name ; Elapsed Time ; Average Processors Used ; Peak Virtual Memory ; Total CPU Time (on all processors) ; |
+---------------------------+--------------+-------------------------+---------------------+------------------------------------+ |
; Analysis & Synthesis ; 00:02:22 ; 1.0 ; 266 MB ; 00:02:19 ; |
; Fitter ; 00:00:42 ; 1.0 ; 310 MB ; 00:00:41 ; |
; TimeQuest Timing Analyzer ; 00:00:15 ; 1.0 ; 258 MB ; 00:00:11 ; |
; Assembler ; 00:00:03 ; 1.0 ; 202 MB ; 00:00:02 ; |
; Total ; 00:03:19 ; -- ; -- ; 00:03:11 ; |
; Analysis & Synthesis ; 00:02:34 ; 1.0 ; 267 MB ; 00:02:30 ; |
; Fitter ; 00:00:55 ; 1.0 ; 311 MB ; 00:00:54 ; |
; TimeQuest Timing Analyzer ; 00:00:20 ; 1.0 ; 259 MB ; 00:00:16 ; |
; Assembler ; 00:00:04 ; 1.0 ; 202 MB ; 00:00:03 ; |
; Total ; 00:03:49 ; -- ; -- ; 00:03:40 ; |
+---------------------------+--------------+-------------------------+---------------------+------------------------------------+ |
|
|
/FPz8_Cyclone_IV.map.summary
1,12 → 1,12
Analysis & Synthesis Status : Successful - Fri Nov 11 10:24:13 2016 |
Analysis & Synthesis Status : Successful - Fri Nov 25 10:10:51 2016 |
Quartus II Version : 9.1 Build 350 03/24/2010 SP 2 SJ Web Edition |
Revision Name : FPz8_Cyclone_IV |
Top-level Entity Name : CPU |
Family : Cyclone IV E |
Total logic elements : 4,886 |
Total combinational functions : 4,854 |
Dedicated logic registers : 494 |
Total registers : 494 |
Total logic elements : 5,021 |
Total combinational functions : 4,952 |
Dedicated logic registers : 584 |
Total registers : 584 |
Total pins : 12 |
Total virtual pins : 0 |
Total memory bits : 147,456 |
/FPz8_Cyclone_IV.pof
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/FPz8_Cyclone_IV.qsf
84,4 → 84,5
set_global_assignment -name SOURCE_FILE altsyncram1.cmp |
set_global_assignment -name VHDL_FILE altsyncram1.vhd |
set_global_assignment -name SOURCE_FILE altsyncram2.cmp |
set_global_assignment -name VHDL_FILE altsyncram2.vhd |
set_global_assignment -name VHDL_FILE altsyncram2.vhd |
set_global_assignment -name VHDL_FILE fpz8_timer.vhd |
/FPz8_Cyclone_IV.sof
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/README.md
1,21 → 1,27
# FPz8 - An open-source VHDL implementation of the Zilog Z8 encore |
|
FPz8 is a softcore 100% object code compatible with the Z8 encore microcontroller line. Current implementation includes 2kb of file registers (RAM), 16kb of program memory (using FPGA RAM), 8 vectored interrupts with programmable priority, full-featured onchip debugger 100% compatible with Zilog's OCD and ZDS-II IDE. |
FPz8 mk1 v0.99 |
|
It was designed to work as a SoC and everything (except the USB chip) fits inside a single FPGA (I have used an Altera Cyclone IV EP4CE6 device). The debugger connection makes use of a serial-to-USB chip (it is part of the low-cost FPGA board used on the project). |
Version: 0.99 Nov, 24th, 2016 (changed LDWX instruction, interrupts, condition code function, debugger command processor) |
Version: 0.91 Nov, 15th, 2016 |
Version: 0.9 Nov, 11th, 2016 |
|
FPz8 is a softcore almost 100% object-code compatible with the Z8 encore microcontroller line. Current implementation includes |
2kb of file registers (RAM), 16kb of program memory (using FPGA RAM), 8 vectored interrupts with programmable priority, |
full-featured onchip debugger 100% compatible with Zilog's OCD and ZDS-II IDE. |
It was designed to work as a SoC and everything (except the USB chip) fits inside a single FPGA (I have used an Altera |
Cyclone IV EP4CE6 device). The debugger connection makes use of a serial-to-USB chip (it is part of the low-cost FPGA |
board used on the project). |
In a near future I plan to add some more features to the device (such as a timer and maybe other peripherals). |
The idea behind the FPz8 was to learn more on VHDL and FPGAs (this is my second design using these technologies). I also |
believe FPz8 can be a very interesting tool for learning/teaching VHDL, computing and microprocessors/microcontrollers |
programming. |
|
The idea behind the FPz8 was to learn more on VHDL and FPGAs (this is my second design using those technologies). I also believe the FPz8 can be a very interesting tool for learning/teaching about VHDL, computing and microprocessors/microcontrollers programming. |
|
You are free to use and to modify the FPz8 to fit your needs, except for comercial use (I don't expect anyone would do that anyway). If you want to contribute to the project, contact me and share your thoughts. |
|
You are free to use and to modify FPz8 to fit your needs, except for comercial use (I don't expect anyone would do that anyway). |
If you want to contribute to the project, contact me and share your thoughts. |
Don't forget to credit the author! |
|
Fábio Pereira |
|
Note: currently there are only a few SFRs physically implemented, they are: |
|
0xFC0 - IRQ0 |
0xFC1 - IRQ0ENH |
0xFC2 - IRQ0ENL |
28,5 → 34,12
0xFFE - SPH |
0xFFF - SPL |
|
What else is missing from the original architecture? |
A: no watchdog (WDT instruction runs as a NOP), no LDE and LDEI instructions (data memory related), no option bytes, |
no data memory related debug commands, no CRC debug command, no ID bytes |
|
FPz8 was tested on an EP4CE6 mini board (50MHz clock) |
http://www.ebay.com/itm/EP4CE6-Mini-Board-USB-Blaster-Altera-Cyclone-IV-FPGA-CPLD-Nano-Size- |
|
This work is licensed under the Creative Commons Attribution 4.0 International License. |
To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/. |
/altsyncram1.bsf
20,14 → 20,14
*/ |
(header "symbol" (version "1.1")) |
(symbol |
(rect 0 0 256 112) |
(text "altsyncram1" (rect 93 1 176 17)(font "Arial" (font_size 10))) |
(text "inst" (rect 8 96 25 108)(font "Arial" )) |
(rect 64 64 320 176) |
(text "altsyncram1" (rect 168 96 251 112)(font "Arial" (font_size 10))) |
(text "inst" (rect 8 0 25 12)(font "Arial" )) |
(port |
(pt 0 32) |
(input) |
(text "data[7..0]" (rect 0 0 53 14)(font "Arial" (font_size 8))) |
(text "data[7..0]" (rect 4 19 49 32)(font "Arial" (font_size 8))) |
(text "data[7..0]" (rect 4 19 57 33)(font "Arial" (font_size 8))) |
(line (pt 0 32)(pt 112 32)(line_width 3)) |
) |
(port |
34,7 → 34,7
(pt 0 48) |
(input) |
(text "address[10..0]" (rect 0 0 82 14)(font "Arial" (font_size 8))) |
(text "address[10..0]" (rect 4 35 69 48)(font "Arial" (font_size 8))) |
(text "address[10..0]" (rect 4 35 86 49)(font "Arial" (font_size 8))) |
(line (pt 0 48)(pt 112 48)(line_width 3)) |
) |
(port |
41,7 → 41,7
(pt 0 64) |
(input) |
(text "wren" (rect 0 0 30 14)(font "Arial" (font_size 8))) |
(text "wren" (rect 4 51 26 64)(font "Arial" (font_size 8))) |
(text "wren" (rect 4 51 34 65)(font "Arial" (font_size 8))) |
(line (pt 0 64)(pt 112 64)(line_width 1)) |
) |
(port |
48,7 → 48,7
(pt 0 88) |
(input) |
(text "clock" (rect 0 0 29 14)(font "Arial" (font_size 8))) |
(text "clock" (rect 4 75 27 88)(font "Arial" (font_size 8))) |
(text "clock" (rect 4 75 33 89)(font "Arial" (font_size 8))) |
(line (pt 0 88)(pt 104 88)(line_width 1)) |
) |
(port |
55,13 → 55,13
(pt 256 32) |
(output) |
(text "q[7..0]" (rect 0 0 35 14)(font "Arial" (font_size 8))) |
(text "q[7..0]" (rect 223 19 253 32)(font "Arial" (font_size 8))) |
(text "q[7..0]" (rect 223 19 258 33)(font "Arial" (font_size 8))) |
(line (pt 256 32)(pt 168 32)(line_width 3)) |
) |
(drawing |
(text "2048 Word(s)" (rect 136 24 148 80)(font "Arial" )(vertical)) |
(text "RAM" (rect 149 42 161 62)(font "Arial" )(vertical)) |
(text "Block Type: AUTO" (rect 41 92 119 104)(font "Arial" )) |
(text "2048 Word(s)" (rect 136 24 148 90)(font "Arial" )(vertical)) |
(text "RAM" (rect 149 42 161 65)(font "Arial" )(vertical)) |
(text "Block Type: AUTO" (rect 41 92 133 104)(font "Arial" )) |
(line (pt 128 24)(pt 168 24)(line_width 1)) |
(line (pt 168 24)(pt 168 80)(line_width 1)) |
(line (pt 168 80)(pt 128 80)(line_width 1)) |
/fpz8_cpu_v1.bsf
0,0 → 1,239
/* |
WARNING: Do NOT edit the input and output ports in this file in a text |
editor if you plan to continue editing the block that represents it in |
the Block Editor! File corruption is VERY likely to occur. |
*/ |
/* |
Copyright (C) 1991-2010 Altera Corporation |
Your use of Altera Corporation's design tools, logic functions |
and other software and tools, and its AMPP partner logic |
functions, and any output files from any of the foregoing |
(including device programming or simulation files), and any |
associated documentation or information are expressly subject |
to the terms and conditions of the Altera Program License |
Subscription Agreement, Altera MegaCore Function License |
Agreement, or other applicable license agreement, including, |
without limitation, that your use is for the sole purpose of |
programming logic devices manufactured by Altera and sold by |
Altera or its authorized distributors. Please refer to the |
applicable agreement for further details. |
*/ |
(header "symbol" (version "1.1")) |
(symbol |
(rect 64 64 264 536) |
(text "fpz8_cpu_v1" (rect 5 0 68 12)(font "Arial" )) |
(text "inst" (rect 8 456 25 468)(font "Arial" )) |
(port |
(pt 200 80) |
(input) |
(text "IDB[7..0]" (rect 0 0 44 12)(font "Arial" )) |
(text "IDB[7..0]" (rect 132 72 176 84)(font "Arial" )) |
(line (pt 184 80)(pt 200 80)(line_width 3)) |
) |
(port |
(pt 200 160) |
(input) |
(text "FRIDB[7..0]" (rect 0 0 60 12)(font "Arial" )) |
(text "FRIDB[7..0]" (rect 116 152 176 164)(font "Arial" )) |
(line (pt 184 160)(pt 200 160)(line_width 3)) |
) |
(port |
(pt 200 224) |
(input) |
(text "RIDB[7..0]" (rect 0 0 53 12)(font "Arial" )) |
(text "RIDB[7..0]" (rect 123 216 176 228)(font "Arial" )) |
(line (pt 184 224)(pt 200 224)(line_width 3)) |
) |
(port |
(pt 200 432) |
(input) |
(text "INT0" (rect 0 0 23 12)(font "Arial" )) |
(text "INT0" (rect 153 424 176 436)(font "Arial" )) |
(line (pt 184 432)(pt 200 432)(line_width 1)) |
) |
(port |
(pt 200 416) |
(input) |
(text "INT1" (rect 0 0 23 12)(font "Arial" )) |
(text "INT1" (rect 153 408 176 420)(font "Arial" )) |
(line (pt 184 416)(pt 200 416)(line_width 1)) |
) |
(port |
(pt 200 400) |
(input) |
(text "INT2" (rect 0 0 23 12)(font "Arial" )) |
(text "INT2" (rect 153 392 176 404)(font "Arial" )) |
(line (pt 184 400)(pt 200 400)(line_width 1)) |
) |
(port |
(pt 200 384) |
(input) |
(text "INT3" (rect 0 0 23 12)(font "Arial" )) |
(text "INT3" (rect 153 376 176 388)(font "Arial" )) |
(line (pt 184 384)(pt 200 384)(line_width 1)) |
) |
(port |
(pt 200 368) |
(input) |
(text "INT4" (rect 0 0 23 12)(font "Arial" )) |
(text "INT4" (rect 153 360 176 372)(font "Arial" )) |
(line (pt 184 368)(pt 200 368)(line_width 1)) |
) |
(port |
(pt 200 352) |
(input) |
(text "INT5" (rect 0 0 23 12)(font "Arial" )) |
(text "INT5" (rect 153 344 176 356)(font "Arial" )) |
(line (pt 184 352)(pt 200 352)(line_width 1)) |
) |
(port |
(pt 200 336) |
(input) |
(text "INT6" (rect 0 0 23 12)(font "Arial" )) |
(text "INT6" (rect 153 328 176 340)(font "Arial" )) |
(line (pt 184 336)(pt 200 336)(line_width 1)) |
) |
(port |
(pt 200 320) |
(input) |
(text "INT7" (rect 0 0 23 12)(font "Arial" )) |
(text "INT7" (rect 153 312 176 324)(font "Arial" )) |
(line (pt 184 320)(pt 200 320)(line_width 1)) |
) |
(port |
(pt 0 144) |
(input) |
(text "DBG_RX" (rect 0 0 43 12)(font "Arial" )) |
(text "DBG_RX" (rect 21 139 64 151)(font "Arial" )) |
(line (pt 0 144)(pt 16 144)(line_width 1)) |
) |
(port |
(pt 0 416) |
(input) |
(text "PAIN[7..0]" (rect 0 0 51 12)(font "Arial" )) |
(text "PAIN[7..0]" (rect 21 411 72 423)(font "Arial" )) |
(line (pt 0 416)(pt 16 416)(line_width 3)) |
) |
(port |
(pt 0 32) |
(input) |
(text "CLK" (rect 0 0 21 12)(font "Arial" )) |
(text "CLK" (rect 21 27 42 39)(font "Arial" )) |
(line (pt 0 32)(pt 16 32)(line_width 1)) |
) |
(port |
(pt 0 48) |
(input) |
(text "RESET" (rect 0 0 35 12)(font "Arial" )) |
(text "RESET" (rect 21 43 56 55)(font "Arial" )) |
(line (pt 0 48)(pt 16 48)(line_width 1)) |
) |
(port |
(pt 200 48) |
(output) |
(text "IAB[15..0]" (rect 24 0 73 12)(font "Arial" )) |
(text "IAB[15..0]" (rect 127 40 176 52)(font "Arial" )) |
(line (pt 200 48)(pt 184 48)(line_width 3)) |
) |
(port |
(pt 200 64) |
(output) |
(text "IWDB[7..0]" (rect 24 0 79 12)(font "Arial" )) |
(text "IWDB[7..0]" (rect 121 56 176 68)(font "Arial" )) |
(line (pt 200 64)(pt 184 64)(line_width 3)) |
) |
(port |
(pt 200 128) |
(output) |
(text "FRAB[11..0]" (rect 24 0 85 12)(font "Arial" )) |
(text "FRAB[11..0]" (rect 115 120 176 132)(font "Arial" )) |
(line (pt 200 128)(pt 184 128)(line_width 3)) |
) |
(port |
(pt 200 144) |
(output) |
(text "FRODB[7..0]" (rect 24 0 88 12)(font "Arial" )) |
(text "FRODB[7..0]" (rect 112 136 176 148)(font "Arial" )) |
(line (pt 200 144)(pt 184 144)(line_width 3)) |
) |
(port |
(pt 200 208) |
(output) |
(text "RODB[7..0]" (rect 24 0 81 12)(font "Arial" )) |
(text "RODB[7..0]" (rect 119 200 176 212)(font "Arial" )) |
(line (pt 200 208)(pt 184 208)(line_width 3)) |
) |
(port |
(pt 200 96) |
(output) |
(text "PGM_WR" (rect 24 0 72 12)(font "Arial" )) |
(text "PGM_WR" (rect 128 88 176 100)(font "Arial" )) |
(line (pt 200 96)(pt 184 96)(line_width 1)) |
) |
(port |
(pt 200 192) |
(output) |
(text "WR" (rect 24 0 42 12)(font "Arial" )) |
(text "WR" (rect 158 184 176 196)(font "Arial" )) |
(line (pt 200 192)(pt 184 192)(line_width 1)) |
) |
(port |
(pt 200 240) |
(output) |
(text "REG_SEL" (rect 24 0 73 12)(font "Arial" )) |
(text "REG_SEL" (rect 127 232 176 244)(font "Arial" )) |
(line (pt 200 240)(pt 184 240)(line_width 1)) |
) |
(port |
(pt 200 176) |
(output) |
(text "MEM_SEL" (rect 24 0 73 12)(font "Arial" )) |
(text "MEM_SEL" (rect 127 168 176 180)(font "Arial" )) |
(line (pt 200 176)(pt 184 176)(line_width 1)) |
) |
(port |
(pt 0 128) |
(output) |
(text "DBG_TX" (rect 24 0 65 12)(font "Arial" )) |
(text "DBG_TX" (rect 24 120 65 132)(font "Arial" )) |
(line (pt 16 128)(pt 0 128)(line_width 1)) |
) |
(port |
(pt 0 432) |
(output) |
(text "PAOUT[7..0]" (rect 24 0 86 12)(font "Arial" )) |
(text "PAOUT[7..0]" (rect 24 424 86 436)(font "Arial" )) |
(line (pt 16 432)(pt 0 432)(line_width 3)) |
) |
(port |
(pt 200 256) |
(output) |
(text "CLK_OUT" (rect 24 0 73 12)(font "Arial" )) |
(text "CLK_OUT" (rect 127 248 176 260)(font "Arial" )) |
(line (pt 200 256)(pt 184 256)(line_width 1)) |
) |
(port |
(pt 200 32) |
(output) |
(text "CLK_OUTN" (rect 24 0 81 12)(font "Arial" )) |
(text "CLK_OUTN" (rect 119 24 176 36)(font "Arial" )) |
(line (pt 200 32)(pt 184 32)(line_width 1)) |
) |
(port |
(pt 200 288) |
(output) |
(text "STOP" (rect 24 0 52 12)(font "Arial" )) |
(text "STOP" (rect 148 280 176 292)(font "Arial" )) |
(line (pt 200 288)(pt 184 288)(line_width 1)) |
) |
(port |
(pt 200 272) |
(output) |
(text "RESET_OUT" (rect 24 0 87 12)(font "Arial" )) |
(text "RESET_OUT" (rect 113 264 176 276)(font "Arial" )) |
(line (pt 200 272)(pt 184 272)(line_width 1)) |
) |
(drawing |
(rectangle (rect 16 16 184 448)(line_width 1)) |
) |
) |
/fpz8_cpu_v1.vhd
1,9 → 1,11
-- FPz8 mk1 |
-- FPz8 mk1 v0.99 |
-- Zilog Z8 Encore! 100% compatible softcore |
|
-- Version: 0.99 Nov, 24th, 2016 (changed LDWX instruction, interrupts, condition code function, debugger command processor) |
-- Version: 0.91 Nov, 15th, 2016 |
-- Version: 0.9 Nov, 11th, 2016 |
|
-- FPz8 is a softcore 100% object-code compatible with the Z8 encore microcontroller line. Current implementation includes |
-- FPz8 is a softcore almost 100% object-code compatible with the Z8 encore microcontroller line. Current implementation includes |
-- 2kb of file registers (RAM), 16kb of program memory (using FPGA RAM), 8 vectored interrupts with programmable priority, |
-- full-featured onchip debugger 100% compatible with Zilog's OCD and ZDS-II IDE. |
-- It was designed to work as a SoC and everything (except the USB chip) fits inside a single FPGA (I have used an Altera |
10,8 → 12,8
-- Cyclone IV EP4CE6 device). The debugger connection makes use of a serial-to-USB chip (it is part of the low-cost FPGA |
-- board used on the project). |
-- In a near future I plan to add some more features to the device (such as a timer and maybe other peripherals). |
-- The idea behind the FPz8 was to learn more on VHDL and FPGAs (this is my second design using those technologies). I also |
-- believe the FPz8 can be a very interesting tool for learning/teaching about VHDL, computing and microprocessors/microcontrollers |
-- The idea behind the FPz8 was to learn more on VHDL and FPGAs (this is my second design using these technologies). I also |
-- believe FPz8 can be a very interesting tool for learning/teaching VHDL, computing and microprocessors/microcontrollers |
-- programming. |
|
-- You are free to use and to modify FPz8 to fit your needs, except for comercial use (I don't expect anyone would do that anyway). |
30,12 → 32,12
-- 0xFFD - RP |
-- 0xFFE - SPH |
-- 0xFFF - SPL |
-- Also notice INT7 is not physically present as it is planned to be used with the coming timer peripheral |
|
-- What else is missing from the original architecture? |
-- A: no watchdog (WDT instruction runs as a NOP), no LDE and LDEI instructions (data memory related), no option bytes |
-- A: no watchdog (WDT instruction runs as a NOP), no LDE and LDEI instructions (data memory related), no option bytes, |
-- no data memory related debug commands, no CRC debug command, no ID bytes |
|
-- FPz8 was tested on a EP4CE6 mini board (50MHz clock) |
-- FPz8 was tested on an EP4CE6 mini board (50MHz clock) |
-- http://www.ebay.com/itm/EP4CE6-Mini-Board-USB-Blaster-Altera-Cyclone-IV-FPGA-CPLD-Nano-Size- |
|
-- This work is licensed under the Creative Commons Attribution 4.0 International License. |
51,10 → 53,10
( |
IAB : buffer std_logic_vector(15 downto 0); -- instruction address bus (16 bits) |
IDB : in std_logic_vector(7 downto 0); -- instruction data bus (8 bits) |
PWDB : out std_logic_vector(7 downto 0); -- program write data bus (8 bits) |
MAB : buffer std_logic_vector(11 downto 0); -- memory address bus (12 bits) |
MIDB : in std_logic_vector(7 downto 0); -- memory input data bus (8 bits) |
MODB : out std_logic_vector(7 downto 0); -- memory output data bus (8 bits) |
IWDB : out std_logic_vector(7 downto 0); -- instruction write data bus (8 bits) |
FRAB : buffer std_logic_vector(11 downto 0); -- file register address bus (12 bits) |
FRIDB : in std_logic_vector(7 downto 0); -- memory input data bus (8 bits) |
FRODB : out std_logic_vector(7 downto 0); -- memory output data bus (8 bits) |
RIDB : in std_logic_vector(7 downto 0); -- register input data bus (8 bits) |
RODB : out std_logic_vector(7 downto 0); -- register output data bus (8 bits) |
PGM_WR : out std_logic; -- program memory write enable |
68,14 → 70,16
INT4 : in std_logic; -- interrupt 4 input (vector 0x000E) |
INT5 : in std_logic; -- interrupt 5 input (vector 0x000C) |
INT6 : in std_logic; -- interrupt 6 input (vector 0x000A) |
INT7 : in std_logic; -- interrupt 7 input (vector 0x0008) |
DBG_RX : in std_logic; -- debugger receive input |
DBG_TX : buffer std_logic; -- debugger transmit output |
PAOUT : out std_logic_vector(7 downto 0); -- port A output data |
PAIN : in std_logic_vector(7 downto 0); -- port A input data |
CLK : in std_logic; -- main clock |
CLK_OUT : out std_logic; -- main gated-clock output |
CLK_OUTN : out std_logic; -- main inverted-gated-clock output |
CLK_OUT : buffer std_logic; -- main clock output |
CLK_OUTN : out std_logic; -- main inverted clock output |
STOP : buffer std_logic; -- stop output |
RESET_OUT : out std_logic; -- reset output |
RESET : in std_logic -- CPU reset |
); |
end fpz8_cpu_v1; |
88,9 → 92,7
end record; |
shared variable CPU_FLAGS, ALU_FLAGS : Tflags; |
shared variable ALU_NOUPDATE : std_logic; |
shared variable INT7 : std_logic; |
shared variable IRQE : std_logic; |
shared variable HALT : std_logic; |
shared variable IRQ0 : std_logic_vector(7 downto 0); -- interrupts 0-7 flags |
shared variable IRQ0ENH,IRQ0ENL : std_logic_vector(7 downto 0); -- interrupts 0-7 enable high and low |
shared variable SP : std_logic_vector(11 downto 0); -- stack pointer |
101,6 → 103,8
ATTRIBUTE preserve : boolean; |
ATTRIBUTE preserve OF RXSYNC1 : signal IS true; |
ATTRIBUTE preserve OF RXSYNC2 : signal IS true; |
signal IRQ0_LATCH : std_logic_vector(7 downto 0); -- current state of IRQ inputs |
attribute preserve of IRQ0_LATCH : signal is true; |
|
constant ALU_ADD : std_logic_vector(3 downto 0):=x"0"; -- CZSVH D=0 |
constant ALU_ADC : std_logic_vector(3 downto 0):=x"1"; -- CZSVH D=0 |
178,13 → 182,13
elsif (ADDRESS=x"FD3") then ---------------------------------------------------- PAOUT register |
PAOUT <= DATA; |
PAOUT_BUFFER := DATA; |
else |
REG_SEL <= '1'; |
RODB <= DATA; |
else -- if it is not an internal SFR but ADDRESS>=0xF00 then it is an external register |
REG_SEL <= '1'; -- enable external register select |
RODB <= DATA; -- output data on register output data bus |
end if; |
else |
MEM_SEL <= '1'; |
MODB <= DATA; |
else -- if ADDRESS < 0xF00 then it is a RAM register |
MEM_SEL <= '1'; -- enable external memory select |
FRODB <= DATA; -- output data on file register output data bus |
end if; |
end datawrite; |
|
213,7 → 217,7
end if; |
else |
MEM_SEL <= '1'; |
return MIDB; |
return FRIDB; |
end if; |
end DATAREAD; |
|
225,35 → 229,35
when x"0" => |
return '0'; |
when x"1" => |
return ALU_FLAGS.S xor ALU_FLAGS.V; |
return CPU_FLAGS.S xor CPU_FLAGS.V; |
when x"2" => |
return ALU_FLAGS.Z or (ALU_FLAGS.S xor ALU_FLAGS.V); |
return CPU_FLAGS.Z or (CPU_FLAGS.S xor CPU_FLAGS.V); |
when x"3" => |
return ALU_FLAGS.C or ALU_FLAGS.Z; |
return CPU_FLAGS.C or CPU_FLAGS.Z; |
when x"4" => |
return ALU_FLAGS.V; |
return CPU_FLAGS.V; |
when x"5" => |
return ALU_FLAGS.S; |
return CPU_FLAGS.S; |
when x"6" => |
return ALU_FLAGS.Z; |
return CPU_FLAGS.Z; |
when x"7" => |
return ALU_FLAGS.C; |
return CPU_FLAGS.C; |
when x"8" => |
return '1'; |
when x"9" => |
return NOT (ALU_FLAGS.S xor ALU_FLAGS.V); |
return NOT (CPU_FLAGS.S xor CPU_FLAGS.V); |
when x"A" => |
return NOT (ALU_FLAGS.Z or (ALU_FLAGS.S xor ALU_FLAGS.V)); |
return NOT (CPU_FLAGS.Z or (CPU_FLAGS.S xor CPU_FLAGS.V)); |
when x"B" => |
return (NOT ALU_FLAGS.C) AND (NOT ALU_FLAGS.Z); |
return (NOT CPU_FLAGS.C) AND (NOT CPU_FLAGS.Z); |
when x"C" => |
return NOT ALU_FLAGS.V; |
return NOT CPU_FLAGS.V; |
when x"D" => |
return NOT ALU_FLAGS.S; |
return NOT CPU_FLAGS.S; |
when x"E" => |
return NOT ALU_FLAGS.Z; |
return NOT CPU_FLAGS.Z; |
when others => |
return NOT ALU_FLAGS.C; |
return NOT CPU_FLAGS.C; |
end case; |
end CONDITIONCODE; |
|
279,7 → 283,7
end if; |
end ADDRESSER8; |
|
-- ADDRESSER12 generates a 12-bit address from a 4-bit address (using RP register) |
-- ADDRESSER4 generates a 12-bit address from a 4-bit address (using RP register) |
function ADDRESSER4 |
( ADDR : in std_logic_vector(3 downto 0)) return std_logic_vector is |
begin |
464,25 → 468,37
end ADDER16; |
|
begin |
clock_out: process(CLK) |
clock_out: process(CLK,RESET) |
variable CKDIVIDER : integer range 0 to 2; |
begin |
CLK_OUTN <= not CLK; |
CLK_OUT <= CLK; |
end process; |
if (RESET='1') then |
CKDIVIDER := 0; |
CLK_OUTN <= '1'; |
CLK_OUT <= '0'; |
elsif (rising_edge(CLK)) then |
CLK_OUTN <= '1'; |
CLK_OUT <= '0'; |
CKDIVIDER := CKDIVIDER + 1; |
if (CKDIVIDER=0) then -- main clock (50MHz) is divided by 3, resulting in a 16.66MHz system clock |
CLK_OUT <= '1'; |
CLK_OUTN <= '0'; |
end if; |
end if; |
end process; -- clock_out process |
-- main process controls debugging and instruction fetching and decoding along |
main: process (CLK,RESET,DBG_RX) |
main: process (CLK_OUT,RESET,DBG_RX) |
-- CPU state machine |
type Tcpu_state is ( |
CPU_DECOD, |
CPU_INDRR, |
CPU_MUL, CPU_MUL1, CPU_MUL2, |
CPU_XADTOM, |
CPU_MTOXAD, CPU_MTOXAD2, |
CPU_XRTOM, |
CPU_XRRTORR, CPU_XRRTORR2, |
CPU_INDRR, -- indirect rr mode |
CPU_MUL, CPU_MUL1, CPU_MUL2, -- MUL instruction |
CPU_XADTOM, -- address with offset to memory |
CPU_MTOXAD, CPU_MTOXAD2, -- memory to address with offset |
CPU_XRTOM, -- register with offset to memory |
CPU_XRRTORR, CPU_XRRTORR2, -- register pair with offset to register pair |
CPU_XRRTORR3, CPU_XRRTORR4, |
CPU_IMTOIRR, CPU_MTOIRR, -- indirect and direct to indirect register pair addressing mode |
CPU_IRRS, CPU_IRRS2, |
CPU_IRRS, CPU_IRRS2, -- indirect register pair as source |
CPU_XRRD, CPU_XRRD2, CPU_XRRD3, -- indexed rr pair as destination |
CPU_XRRS, CPU_XRRS2, CPU_XRRS3, -- indexed rr pair as source |
CPU_IND1, CPU_IND2, -- indirect memory access |
491,26 → 507,26
CPU_OMA, -- One memory access instructions (immediate to/with register) |
CPU_OMA2, -- One memory access instructions (immediate to/with register) logic unit related |
CPU_DMAB, -- Decrement address bus (for word access) |
CPU_LDW, CPU_LDW2, |
CPU_LDPTOIM, CPU_LDPTOIM2, |
CPU_LDPTOM, CPU_LDPTOM2, |
CPU_LDPTOM3, CPU_LDPTOM4, |
CPU_LDMTOP, CPU_LDMTOP2, |
CPU_BIT, |
CPU_IBTJ, CPU_BTJ, |
CPU_DJNZ, |
CPU_INDJUMP, CPU_INDJUMP2, |
CPU_TRAP, CPU_TRAP2, |
CPU_INDSTACK, CPU_INDSTACK2, |
CPU_STACK, CPU_STACK1, |
CPU_LDW, CPU_LDW2, CPU_LDW3, -- load word instruction |
CPU_LDW4, CPU_LDW5, |
CPU_LDPTOIM, CPU_LDPTOIM2, -- load program to indirect memory |
CPU_LDPTOM, CPU_LDPTOM2, -- load program to memory |
CPU_LDPTOM3, CPU_LDPTOM4, |
CPU_LDMTOP, CPU_LDMTOP2, -- load memory to program |
CPU_BIT, -- BIT instruction |
CPU_IBTJ, CPU_BTJ, -- BTJ instruction |
CPU_DJNZ, -- DJNZ instruction |
CPU_INDJUMP, CPU_INDJUMP2, -- indirect JP |
CPU_TRAP, CPU_TRAP2, -- TRAP instruction |
CPU_INDSTACK, CPU_INDSTACK2, -- indirect stacking |
CPU_STACK, CPU_STACK1, -- stacking operations |
CPU_STACK2, CPU_STACK3, |
CPU_UNSTACK, CPU_UNSTACK2, |
CPU_UNSTACK3, |
CPU_UNSTACK, CPU_UNSTACK2, -- unstacking operations |
CPU_UNSTACK3, |
CPU_STORE, -- store results, no change to the flags |
CPU_VECTOR, CPU_VECTOR2, |
CPU_HALTED, |
CPU_RESET, |
CPU_ILLEGAL |
CPU_VECTOR, CPU_VECTOR2, -- vectoring stages |
CPU_RESET, -- reset state |
CPU_ILLEGAL -- illegal state |
); |
type Tfetch_state is ( |
F_ADDR, -- instruction queue is initializing, reset pointers and empty queue |
578,19 → 594,20
variable DBG_CMD : Tdbg_command; |
variable CAN_FETCH : std_logic; -- controls whether the instruction queue can actually fetch opcodes |
variable LU_INSTRUCTION : std_logic; -- indicates a LU2-related instruction |
variable INT_FLAG : std_logic; -- indicates an interrupt |
variable WORD_DATA : std_logic; -- indicates a 16-bit data instruction |
variable HALT : std_logic; -- indicates the CPU is halted |
variable PC : std_logic_vector(15 downto 0); -- program counter |
variable FETCH_ADDR : std_logic_vector(15 downto 0); -- next address to be fetched |
variable DEST_ADDR16 : std_logic_vector(15 downto 0); -- temporary 16-bit destination address |
variable DEST_ADDR : std_logic_vector(11 downto 0); -- temporary 12-bit destination address |
variable TEMP_DATA : std_logic_vector(7 downto 0); -- temporary 8-bit data |
variable OLD_IRQ0 : std_logic_vector(7 downto 0); -- previous state of IRQs |
variable OLD_IRQ0 : std_logic_vector(7 downto 0); -- previous state of IRQ inputs |
variable INTVECT : std_logic_vector(7 downto 0); -- current interrupt vector (lower 8-bits) |
variable RESULT : std_logic_vector(7 downto 0); -- temporary 8-bit result |
variable TEMP_OP : std_logic_vector(3 downto 0); -- ALU/LU2 operation code |
variable ATM_COUNTER : integer range 0 to 3; -- temporary interrupt disable counter (ATM instruction) |
variable NUM_BYTES : integer range 0 to 5; -- number of bytes decoded |
variable CKDIVIDER : integer range 0 to 2; |
type Tinstructionqueue is record |
WRPOS : integer range 0 to 7; -- instruction queue write pointer |
RDPOS : integer range 0 to 7; -- instruction queue read pointer |
614,10 → 631,11
variable OCD : Tocdflags; |
|
begin |
if (reset='1') then -- reset operations |
RESET_OUT <= RESET or OCDCR.RST; |
if (RESET='1') then -- reset operations |
IAB <= x"0002"; |
MAB <= x"000"; |
PWDB <= x"00"; |
FRAB <= x"000"; |
IWDB <= x"00"; |
SP := x"000"; |
RP := x"00"; |
WR <= '0'; |
643,266 → 661,277
IRQ0ENH := x"00"; |
IRQ0ENL := x"00"; |
ATM_COUNTER := 0; |
CKDIVIDER := 0; |
CPU_STATE := CPU_VECTOR; |
elsif (rising_edge(clk)) then |
if (OLD_IRQ0(0)='0' and INT0='1') then IRQ0(0) := '1'; end if; |
if (OLD_IRQ0(1)='0' and INT1='1') then IRQ0(1) := '1'; end if; |
if (OLD_IRQ0(2)='0' and INT2='1') then IRQ0(2) := '1'; end if; |
if (OLD_IRQ0(3)='0' and INT3='1') then IRQ0(3) := '1'; end if; |
if (OLD_IRQ0(4)='0' and INT4='1') then IRQ0(4) := '1'; end if; |
if (OLD_IRQ0(5)='0' and INT5='1') then IRQ0(5) := '1'; end if; |
if (OLD_IRQ0(6)='0' and INT6='1') then IRQ0(6) := '1'; end if; |
OLD_IRQ0 := INT7&INT6&INT5&INT4&INT3&INT2&INT1&INT0; |
CKDIVIDER := CKDIVIDER + 1; |
if (CKDIVIDER=0) then -- main clock (50MHz) is divided by 3, resulting in a 16.66MHz system clock |
WR <= '0'; |
PGM_WR <= '0'; |
|
-- This is the instruction queue FSM |
if (CAN_FETCH='1') then |
if (IQUEUE.FETCH_STATE=F_ADDR) then |
FETCH_ADDR := PC; |
IAB <= PC; |
IQUEUE.WRPOS := 0; |
IQUEUE.RDPOS := 0; |
IQUEUE.CNT := 0; |
IQUEUE.FETCH_STATE := F_READ; |
else |
if (IQUEUE.FULL='0') then |
IQUEUE.QUEUE(IQUEUE.WRPOS) := IDB; |
FETCH_ADDR := FETCH_ADDR + 1; |
IAB <= FETCH_ADDR; |
IQUEUE.WRPOS := IQUEUE.WRPOS + 1; |
IQUEUE.CNT := IQUEUE.CNT + 1; |
end if; |
elsif (rising_edge(CLK_OUT)) then |
IRQ0_LATCH <= INT7&INT6&INT5&INT4&INT3&INT2&INT1&INT0; |
if (OLD_IRQ0(0)/=IRQ0_LATCH(0)) then IRQ0(0) := '1'; end if; |
if (OLD_IRQ0(1)/=IRQ0_LATCH(1)) then IRQ0(1) := '1'; end if; |
if (OLD_IRQ0(2)/=IRQ0_LATCH(2)) then IRQ0(2) := '1'; end if; |
if (OLD_IRQ0(3)/=IRQ0_LATCH(3)) then IRQ0(3) := '1'; end if; |
if (OLD_IRQ0(4)/=IRQ0_LATCH(4)) then IRQ0(4) := '1'; end if; |
if (OLD_IRQ0(5)/=IRQ0_LATCH(5)) then IRQ0(5) := '1'; end if; |
if (OLD_IRQ0(6)/=IRQ0_LATCH(6)) then IRQ0(6) := '1'; end if; |
if (OLD_IRQ0(7)/=IRQ0_LATCH(7)) then IRQ0(7) := '1'; end if; |
OLD_IRQ0 := IRQ0_LATCH; |
|
WR <= '0'; |
PGM_WR <= '0'; |
|
-- start of instruction queue FSM |
if (CAN_FETCH='1') then |
if (IQUEUE.FETCH_STATE=F_ADDR) then |
FETCH_ADDR := PC; |
IAB <= PC; |
IQUEUE.WRPOS := 0; |
IQUEUE.RDPOS := 0; |
IQUEUE.CNT := 0; |
IQUEUE.FETCH_STATE := F_READ; |
else |
if (IQUEUE.FULL='0') then |
IQUEUE.QUEUE(IQUEUE.WRPOS) := IDB; |
FETCH_ADDR := FETCH_ADDR + 1; |
IAB <= FETCH_ADDR; |
IQUEUE.WRPOS := IQUEUE.WRPOS + 1; |
IQUEUE.CNT := IQUEUE.CNT + 1; |
end if; |
end if; |
if (IQUEUE.CNT=7) then IQUEUE.FULL:='1'; else IQUEUE.FULL:='0'; |
end if; |
-- This is the end of instruction queue FSM |
|
-- These are the Debugger FSMs |
DBG_UART.BAUDPRE := DBG_UART.BAUDPRE+1; |
if (DBG_UART.BAUDPRE=0) then |
DBG_UART.BAUDCNTRX := DBG_UART.BAUDCNTRX+1; |
DBG_UART.BAUDCNTTX := DBG_UART.BAUDCNTTX+1; |
end if; |
RXSYNC2 <= DBG_RX; |
RXSYNC1 <= RXSYNC2; |
case DBG_UART.RX_STATE is |
when DBGST_NOSYNC => |
DBG_UART.DBG_SYNC := '0'; |
DBG_UART.RX_DONE := '0'; |
DBG_CMD := DBG_WAIT_CMD; |
DBG_UART.RX_STATE := DBGST_WAITSTART; |
when DBGST_WAITSTART => |
if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then |
DBG_UART.RX_STATE := DBGST_MEASURING; |
DBG_UART.BAUDCNTRX := x"000"; |
end if; |
if (IQUEUE.CNT=7) then IQUEUE.FULL:='1'; else IQUEUE.FULL:='0'; |
end if; |
-- end of instruction queue FSM |
|
-- start of debugger UART |
DBG_UART.BAUDPRE := DBG_UART.BAUDPRE+1; -- baudrate prescaler |
if (DBG_UART.BAUDPRE=0) then |
DBG_UART.BAUDCNTRX := DBG_UART.BAUDCNTRX+1; |
DBG_UART.BAUDCNTTX := DBG_UART.BAUDCNTTX+1; |
end if; |
RXSYNC2 <= DBG_RX; -- DBG_RX input synchronization |
RXSYNC1 <= RXSYNC2; -- RXSYNC1 is a synchronized DBG_RX signal |
case DBG_UART.RX_STATE is |
when DBGST_NOSYNC => |
DBG_UART.DBG_SYNC := '0'; |
DBG_UART.RX_DONE := '0'; |
DBG_CMD := DBG_WAIT_CMD; |
DBG_UART.RX_STATE := DBGST_WAITSTART; |
when DBGST_WAITSTART => |
if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then |
DBG_UART.RX_STATE := DBGST_MEASURING; |
DBG_UART.BAUDCNTRX := x"000"; |
end if; |
when DBGST_MEASURING => |
if (DBG_UART.BAUDCNTRX/=x"FFF") then |
if (RXSYNC1='1') then |
DBG_UART.DBG_SYNC := '1'; |
DBG_UART.RX_STATE := DBGST_IDLE; |
DBG_UART.BITTIMERX := "0000"&DBG_UART.BAUDCNTRX(11 downto 4); |
DBG_UART.BITTIMETX := "000"&DBG_UART.BAUDCNTRX(11 downto 3); |
end if; |
when DBGST_MEASURING => |
if (DBG_UART.BAUDCNTRX/=x"FFF") then |
if (RXSYNC1='1') then |
DBG_UART.DBG_SYNC := '1'; |
DBG_UART.RX_STATE := DBGST_IDLE; |
DBG_UART.BITTIMERX := "0000"&DBG_UART.BAUDCNTRX(11 downto 4); |
DBG_UART.BITTIMETX := "000"&DBG_UART.BAUDCNTRX(11 downto 3); |
end if; |
else |
DBG_UART.RX_STATE := DBGST_NOSYNC; |
end if; |
when DBGST_IDLE => |
DBG_UART.BAUDCNTRX:=x"000"; |
DBG_UART.RXCNT:=0; |
if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then -- it's a start bit |
DBG_UART.RX_STATE := DBGST_START; |
end if; |
when DBGST_START => |
if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMERX) then |
DBG_UART.BAUDCNTRX:=x"000"; |
if (RXSYNC1='0') then |
DBG_UART.RX_STATE := DBGST_RECEIVING; |
else |
DBG_UART.RX_STATE := DBGST_NOSYNC; |
DBG_UART.RX_STATE := DBGST_ERROR; |
DBG_UART.TX_STATE := DBGTX_BREAK; |
end if; |
when DBGST_IDLE => |
end if; |
when DBGST_RECEIVING => |
if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMETX) then |
DBG_UART.BAUDCNTRX:=x"000"; |
DBG_UART.RXCNT:=0; |
if (RXSYNC1='0' and DBG_UART.LAST_SMP='1') then -- it's a start bit |
DBG_UART.RX_STATE := DBGST_START; |
end if; |
when DBGST_START => |
if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMERX) then |
DBG_UART.BAUDCNTRX:=x"000"; |
if (RXSYNC1='0') then |
DBG_UART.RX_STATE := DBGST_RECEIVING; |
-- one bit time elapsed, sample RX input |
DBG_UART.RXSHIFTREG := RXSYNC1 & DBG_UART.RXSHIFTREG(8 downto 1); |
DBG_UART.RXCNT := DBG_UART.RXCNT + 1; |
if (DBG_UART.RXCNT=9) then |
if (RXSYNC1='1') then |
-- if the stop bit is 1, rx is completed ok |
DBG_UART.RX_DATA := DBG_UART.RXSHIFTREG(7 downto 0); |
DBG_UART.RX_DONE := '1'; |
DBG_UART.RX_STATE := DBGST_IDLE; |
else |
-- if the stop bit is 0, it is a break char, reset receiver |
DBG_UART.RX_STATE := DBGST_ERROR; |
DBG_UART.TX_STATE := DBGTX_BREAK; |
end if; |
end if; |
when DBGST_RECEIVING => |
if (DBG_UART.BAUDCNTRX=DBG_UART.BITTIMETX) then |
DBG_UART.BAUDCNTRX:=x"000"; |
-- one bit time elapsed, sample RX input |
DBG_UART.RXSHIFTREG := RXSYNC1 & DBG_UART.RXSHIFTREG(8 downto 1); |
DBG_UART.RXCNT := DBG_UART.RXCNT + 1; |
if (DBG_UART.RXCNT=9) then |
if (RXSYNC1='1') then |
-- if the stop bit is 1, rx is completed ok |
DBG_UART.RX_DATA := DBG_UART.RXSHIFTREG(7 downto 0); |
DBG_UART.RX_DONE := '1'; |
DBG_UART.RX_STATE := DBGST_IDLE; |
else |
-- if the stop bit is 0, it is a break char, reset receiver |
DBG_UART.RX_STATE := DBGST_ERROR; |
DBG_UART.TX_STATE := DBGTX_BREAK; |
end if; |
end if; |
end if; |
when others => |
end case; |
DBG_UART.LAST_SMP := RXSYNC1; |
case DBG_UART.TX_STATE is |
when DBGTX_INIT => |
DBG_UART.TX_EMPTY := '1'; |
DBG_UART.TX_STATE:=DBGTX_IDLE; |
when DBGTX_IDLE => -- UART is idle and not transmitting |
DBG_TX <= '1'; |
if (DBG_UART.TX_EMPTY='0' and DBG_UART.DBG_SYNC='1') then -- there is new data in TX_DATA register |
DBG_UART.BAUDCNTTX:=x"000"; |
DBG_UART.TX_STATE := DBGTX_START; |
end if; |
when DBGTX_START => |
if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then |
DBG_UART.BAUDCNTTX:=x"000"; |
DBG_UART.TXSHIFTREG := '1'&DBG_UART.TX_DATA; |
DBG_UART.TXCNT := 10; |
DBG_UART.TX_STATE := DBGTX_TRASMITTING; |
DBG_TX <= '0'; |
end if; |
when DBGTX_TRASMITTING => -- UART is shifting data |
if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then |
DBG_UART.BAUDCNTTX:=x"000"; |
DBG_TX <= DBG_UART.TXSHIFTREG(0); |
DBG_UART.TXSHIFTREG := '1'&DBG_UART.TXSHIFTREG(8 downto 1); |
DBG_UART.TXCNT :=DBG_UART.TXCNT - 1; |
if (DBG_UART.TXCNT=0) then |
DBG_UART.TX_STATE:=DBGTX_IDLE; |
DBG_UART.TX_EMPTY := '1'; |
end if; |
end if; |
when DBGTX_BREAK => |
end if; |
when others => |
end case; |
DBG_UART.LAST_SMP := RXSYNC1; |
case DBG_UART.TX_STATE is |
when DBGTX_INIT => |
DBG_UART.TX_EMPTY := '1'; |
DBG_UART.TX_STATE:=DBGTX_IDLE; |
when DBGTX_IDLE => -- UART is idle and not transmitting |
DBG_TX <= '1'; |
if (DBG_UART.TX_EMPTY='0' and DBG_UART.DBG_SYNC='1') then -- there is new data in TX_DATA register |
DBG_UART.BAUDCNTTX:=x"000"; |
DBG_UART.TX_STATE:=DBGTX_BREAK2; |
when DBGTX_BREAK2 => |
DBG_UART.TX_STATE := DBGTX_START; |
end if; |
when DBGTX_START => |
if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then |
DBG_UART.BAUDCNTTX:=x"000"; |
DBG_UART.TXSHIFTREG := '1'&DBG_UART.TX_DATA; |
DBG_UART.TXCNT := 10; |
DBG_UART.TX_STATE := DBGTX_TRASMITTING; |
DBG_TX <= '0'; |
DBG_UART.RX_STATE := DBGST_NOSYNC; |
if (DBG_UART.BAUDCNTTX=x"FFF") then |
DBG_UART.TX_STATE:=DBGTX_INIT; |
end if; |
when DBGTX_TRASMITTING => -- UART is shifting data |
if (DBG_UART.BAUDCNTTX=DBG_UART.BITTIMETX) then |
DBG_UART.BAUDCNTTX:=x"000"; |
DBG_TX <= DBG_UART.TXSHIFTREG(0); |
DBG_UART.TXSHIFTREG := '1'&DBG_UART.TXSHIFTREG(8 downto 1); |
DBG_UART.TXCNT :=DBG_UART.TXCNT - 1; |
if (DBG_UART.TXCNT=0) then |
DBG_UART.TX_STATE:=DBGTX_IDLE; |
DBG_UART.TX_EMPTY := '1'; |
end if; |
end case; |
if (RXSYNC1='0') then DBG_TX <='0'; |
end if; |
case DBG_CMD is |
when DBG_WAIT_CMD => |
if (DBG_UART.RX_DONE='1') then |
case DBG_UART.RX_DATA is |
when DBGCMD_READ_REV => DBG_CMD := DBG_SEND_REV; |
when DBGCMD_READ_STATUS => DBG_CMD := DBG_SEND_STATUS; |
when DBGCMD_WRITE_CTRL => DBG_CMD := DBG_WRITE_CTRL; |
when DBGCMD_READ_CTRL => DBG_CMD := DBG_SEND_CTRL; |
when DBGCMD_WRITE_PC => DBG_CMD := DBG_WRITE_PC; |
when DBGCMD_READ_PC => DBG_CMD := DBG_SEND_PC; |
when DBGCMD_WRITE_REG => DBG_CMD := DBG_WRITE_REG; |
when DBGCMD_READ_REG => DBG_CMD := DBG_READ_REG; |
when DBGCMD_WRITE_PROGRAM=> DBG_CMD := DBG_WRITE_PROGMEM; |
when DBGCMD_READ_PROGRAM=> DBG_CMD := DBG_READ_PROGMEM; |
when DBGCMD_STEP => DBG_CMD := DBG_STEP; |
when DBGCMD_STUFF => DBG_CMD := DBG_STUFF; |
when DBGCMD_EXEC => DBG_CMD := DBG_EXEC; |
when others => |
end case; |
DBG_UART.RX_DONE:='0'; |
end if; |
when DBG_SEND_REV => |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=x"01"; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_SEND_REV2; |
end if; |
when DBG_SEND_REV2 => |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=x"00"; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_SEND_STATUS => |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=OCDCR.DBGMODE&HALT&"000000"; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_WRITE_CTRL => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.RX_DONE:='0'; |
OCDCR.DBGMODE := DBG_UART.RX_DATA(7); |
OCDCR.BRKEN := DBG_UART.RX_DATA(6); |
OCDCR.DBGACK := DBG_UART.RX_DATA(5); |
OCDCR.BRKLOOP := DBG_UART.RX_DATA(4); |
OCDCR.RST := DBG_UART.RX_DATA(0); |
if (OCDCR.RST='1') then CPU_STATE:=CPU_RESET; |
end if; |
when DBGTX_BREAK => |
DBG_UART.BAUDCNTTX:=x"000"; |
DBG_UART.TX_STATE:=DBGTX_BREAK2; |
when DBGTX_BREAK2 => |
DBG_TX <= '0'; |
DBG_UART.RX_STATE := DBGST_NOSYNC; |
if (DBG_UART.BAUDCNTTX=x"FFF") then |
DBG_UART.TX_STATE:=DBGTX_INIT; |
end if; |
end case; |
if (RXSYNC1='0') then DBG_TX <='0'; -- this mimics open-collector feature of OCD communication |
end if; |
-- end of the debugger UART |
|
-- This is the instruction decoder |
case CPU_STATE IS |
when CPU_DECOD => |
TEMP_OP := ALU_LD; -- default ALU operation is load |
LU_INSTRUCTION := '0'; -- default is ALU operation (instead of LU2) |
INT_FLAG := '0'; -- reset temporary interrupt flag |
WORD_DATA := '0'; -- default is 8-bit operation |
INTVECT := x"00"; -- default vector is 0x00 |
NUM_BYTES := 0; -- default instruction length is 0 bytes |
|
-- start of debugger command processor |
case DBG_CMD is |
when DBG_WAIT_CMD => |
if (DBG_UART.RX_DONE='1') then |
case DBG_UART.RX_DATA is |
when DBGCMD_READ_REV => DBG_CMD := DBG_SEND_REV; |
when DBGCMD_READ_STATUS => DBG_CMD := DBG_SEND_STATUS; |
when DBGCMD_WRITE_CTRL => DBG_CMD := DBG_WRITE_CTRL; |
when DBGCMD_READ_CTRL => DBG_CMD := DBG_SEND_CTRL; |
when DBGCMD_WRITE_PC => DBG_CMD := DBG_WRITE_PC; |
when DBGCMD_READ_PC => DBG_CMD := DBG_SEND_PC; |
when DBGCMD_WRITE_REG => DBG_CMD := DBG_WRITE_REG; |
when DBGCMD_READ_REG => DBG_CMD := DBG_READ_REG; |
when DBGCMD_WRITE_PROGRAM=> DBG_CMD := DBG_WRITE_PROGMEM; |
when DBGCMD_READ_PROGRAM=> DBG_CMD := DBG_READ_PROGMEM; |
when DBGCMD_STEP => DBG_CMD := DBG_STEP; |
when DBGCMD_STUFF => DBG_CMD := DBG_STUFF; |
when DBGCMD_EXEC => DBG_CMD := DBG_EXEC; |
when others => |
end case; |
DBG_UART.RX_DONE:='0'; |
end if; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_SEND_CTRL => |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=OCDCR.DBGMODE&OCDCR.BRKEN&OCDCR.DBGACK&OCDCR.BRKLOOP&"000"&OCDCR.RST; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_WRITE_PC => |
if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then |
DBG_UART.RX_DONE:='0'; |
CAN_FETCH := '0'; |
PC(15 downto 8) := DBG_UART.RX_DATA; |
DBG_CMD := DBG_WRITE_PC2; |
end if; |
when DBG_WRITE_PC2 => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.RX_DONE:='0'; |
PC(7 downto 0) := DBG_UART.RX_DATA; |
IQUEUE.FETCH_STATE := F_ADDR; |
IQUEUE.CNT := 0; |
CAN_FETCH := '1'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_SEND_PC => |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=PC(15 downto 8); |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_SEND_PC2; |
end if; |
when DBG_SEND_PC2 => |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=PC(7 downto 0); |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_WRITE_REG => |
DBG_UART.WRT := '1'; |
DBG_CMD := DBG_REG; |
when DBG_READ_REG => |
DBG_UART.WRT := '0'; |
DBG_CMD := DBG_REG; |
when DBG_REG => |
if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then |
CAN_FETCH := '0'; |
MAB(11 downto 8) <= DBG_UART.RX_DATA(3 downto 0); |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_REG2; |
end if; |
when DBG_REG2 => |
if (DBG_UART.RX_DONE='1') then |
MAB(7 downto 0) <= DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_REG3; |
end if; |
when DBG_REG3 => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.SIZE := x"00"&DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_REG4; |
end if; |
when DBG_REG4 => |
if (OCDCR.DBGMODE='1') then |
when DBG_SEND_REV => -- read revision first byte |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=x"01"; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_SEND_REV2; |
end if; |
when DBG_SEND_REV2 => -- read revision second byte |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=x"00"; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_SEND_STATUS => -- read OCD status |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=OCDCR.DBGMODE&HALT&"000000"; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_WRITE_CTRL => -- write OCD control register |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.RX_DONE:='0'; |
OCDCR.DBGMODE := DBG_UART.RX_DATA(7); |
OCDCR.BRKEN := DBG_UART.RX_DATA(6); |
OCDCR.DBGACK := DBG_UART.RX_DATA(5); |
OCDCR.BRKLOOP := DBG_UART.RX_DATA(4); |
OCDCR.RST := DBG_UART.RX_DATA(0); |
if (OCDCR.RST='1') then CPU_STATE:=CPU_RESET; |
end if; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_SEND_CTRL => -- read OCD control register |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=OCDCR.DBGMODE&OCDCR.BRKEN&OCDCR.DBGACK&OCDCR.BRKLOOP&"000"&OCDCR.RST; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_WRITE_PC => -- write PC high byte |
if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then |
DBG_UART.RX_DONE:='0'; |
CAN_FETCH := '0'; |
PC(15 downto 8) := DBG_UART.RX_DATA; |
DBG_CMD := DBG_WRITE_PC2; |
end if; |
when DBG_WRITE_PC2 => -- write PC low byte |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.RX_DONE:='0'; |
PC(7 downto 0) := DBG_UART.RX_DATA; |
IQUEUE.FETCH_STATE := F_ADDR; |
IQUEUE.CNT := 0; |
CAN_FETCH := '1'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_SEND_PC => -- read PC high byte |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=PC(15 downto 8); |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_SEND_PC2; |
end if; |
when DBG_SEND_PC2 => -- read PC high byte |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=PC(7 downto 0); |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_WAIT_CMD; |
end if; |
when DBG_WRITE_REG => -- write to SFR/user registers |
DBG_UART.WRT := '1'; |
DBG_CMD := DBG_REG; |
when DBG_READ_REG => -- read SFR/user registers |
DBG_UART.WRT := '0'; |
DBG_CMD := DBG_REG; |
when DBG_REG => -- proceed with register read/write |
if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then |
FRAB(11 downto 8) <= DBG_UART.RX_DATA(3 downto 0); |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_REG2; |
end if; |
when DBG_REG2 => |
if (DBG_UART.RX_DONE='1') then |
FRAB(7 downto 0) <= DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_REG3; |
end if; |
when DBG_REG3 => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.SIZE := x"00"&DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_REG4; |
end if; |
when DBG_REG4 => |
if (DBG_UART.WRT='1') then |
if (DBG_UART.RX_DONE='1') then |
CPU_STATE := CPU_OMA; |
912,129 → 941,116
end if; |
else |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=DATAREAD(MAB); |
DBG_UART.TX_DATA:=DATAREAD(FRAB); |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_REG5; |
end if; |
end if; |
end if; |
when DBG_REG5 => |
if (CPU_STATE=CPU_DECOD) then |
MAB <= MAB + 1; |
when DBG_REG5 => |
FRAB <= FRAB + 1; |
DBG_UART.SIZE := DBG_UART.SIZE - 1; |
if (DBG_UART.SIZE=x"0000") then |
DBG_CMD := DBG_WAIT_CMD; |
CAN_FETCH := '1'; |
else DBG_CMD := DBG_REG4; |
end if; |
end if; |
when DBG_WRITE_PROGMEM => |
DBG_UART.WRT := '1'; |
DBG_CMD := DBG_PROGMEM; |
when DBG_READ_PROGMEM => |
DBG_UART.WRT := '0'; |
DBG_CMD := DBG_PROGMEM; |
when DBG_PROGMEM => |
if (DBG_UART.RX_DONE='1') then |
CAN_FETCH := '0'; |
IAB(15 downto 8) <= DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_PROGMEM2; |
end if; |
when DBG_PROGMEM2 => |
if (DBG_UART.RX_DONE='1') then |
IAB(7 downto 0) <= DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_PROGMEM3; |
end if; |
when DBG_PROGMEM3 => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.SIZE(15 downto 8) := DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_PROGMEM4; |
end if; |
when DBG_PROGMEM4 => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.SIZE(7 downto 0) := DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_PROGMEM5; |
end if; |
when DBG_PROGMEM5 => |
if (DBG_UART.WRT='1') then |
when DBG_WRITE_PROGMEM => |
DBG_UART.WRT := '1'; |
DBG_CMD := DBG_PROGMEM; |
when DBG_READ_PROGMEM => |
DBG_UART.WRT := '0'; |
DBG_CMD := DBG_PROGMEM; |
when DBG_PROGMEM => |
if (DBG_UART.RX_DONE='1') then |
PWDB <= DBG_UART.RX_DATA; |
CAN_FETCH := '0'; |
IAB(15 downto 8) <= DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
PGM_WR <= '1'; |
DBG_CMD := DBG_PROGMEM6; |
DBG_CMD := DBG_PROGMEM2; |
end if; |
else |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=IDB; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_PROGMEM6; |
when DBG_PROGMEM2 => |
if (DBG_UART.RX_DONE='1') then |
IAB(7 downto 0) <= DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_PROGMEM3; |
end if; |
when DBG_PROGMEM3 => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.SIZE(15 downto 8) := DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_PROGMEM4; |
end if; |
when DBG_PROGMEM4 => |
if (DBG_UART.RX_DONE='1') then |
DBG_UART.SIZE(7 downto 0) := DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_PROGMEM5; |
end if; |
end if; |
when DBG_PROGMEM6 => |
IAB <= IAB + 1; |
DBG_UART.SIZE := DBG_UART.SIZE - 1; |
if (DBG_UART.SIZE=x"0000") then |
DBG_CMD := DBG_WAIT_CMD; |
CAN_FETCH := '1'; |
IQUEUE.CNT := 0; |
IQUEUE.FETCH_STATE := F_ADDR; |
else DBG_CMD := DBG_PROGMEM5; |
end if; |
when DBG_STEP => |
OCD.SINGLESTEP:='1'; |
IQUEUE.FETCH_STATE := F_ADDR; |
DBG_CMD := DBG_WAIT_CMD; |
when DBG_STUFF => |
if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then |
IQUEUE.QUEUE(IQUEUE.RDPOS) := DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
DBG_CMD := DBG_STEP; |
end if; |
when DBG_EXEC => |
if (OCDCR.DBGMODE='1') then |
when DBG_PROGMEM5 => |
if (DBG_UART.WRT='1') then |
if (DBG_UART.RX_DONE='1') then |
IWDB <= DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
PGM_WR <= '1'; |
DBG_CMD := DBG_PROGMEM6; |
end if; |
else |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=IDB; |
DBG_UART.TX_EMPTY:='0'; |
DBG_CMD := DBG_PROGMEM6; |
end if; |
end if; |
when DBG_PROGMEM6 => |
IAB <= IAB + 1; |
DBG_UART.SIZE := DBG_UART.SIZE - 1; |
if (DBG_UART.SIZE=x"0000") then |
DBG_CMD := DBG_WAIT_CMD; |
CAN_FETCH := '1'; |
IQUEUE.CNT := 0; |
IQUEUE.FETCH_STATE := F_ADDR; |
else DBG_CMD := DBG_PROGMEM5; |
end if; |
when DBG_STEP => |
OCD.SINGLESTEP:='1'; |
CAN_FETCH:='0'; |
IQUEUE.CNT := 0; |
IQUEUE.FETCH_STATE := F_ADDR; |
end if; |
DBG_CMD := DBG_EXEC2; |
when DBG_EXEC2 => |
if (DBG_UART.RX_DONE='1') then |
if (OCDCR.DBGMODE='0') then DBG_CMD := DBG_WAIT_CMD; |
else |
IQUEUE.QUEUE(IQUEUE.WRPOS) := DBG_UART.RX_DATA; |
DBG_CMD := DBG_WAIT_CMD; |
when DBG_STUFF => |
if (DBG_UART.RX_DONE='1' and OCDCR.DBGMODE='1') then |
IQUEUE.QUEUE(IQUEUE.RDPOS) := DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
IQUEUE.WRPOS := IQUEUE.WRPOS + 1; |
IQUEUE.CNT := IQUEUE.CNT + 1; |
DBG_CMD := DBG_EXEC3; |
DBG_CMD := DBG_STEP; |
end if; |
end if; |
when DBG_EXEC3 => |
if (OCD.SINGLESTEP='1') then DBG_CMD := DBG_EXEC2; else |
DBG_CMD := DBG_WAIT_CMD; |
CAN_FETCH:='0'; |
IQUEUE.FETCH_STATE := F_ADDR; |
end if; |
when others => |
end case; |
-- This is the end of the debugger code |
|
-- This is the main instruction decoder |
case CPU_STATE IS |
when CPU_DECOD => |
TEMP_OP := ALU_LD; -- default ALU operation is load |
LU_INSTRUCTION := '0'; -- default is ALU operation (instead of LU2) |
WORD_DATA := '0'; -- default is 8-bit operation |
INTVECT := x"00"; -- default vector is 0x00 |
NUM_BYTES := 0; -- default instruction length is 0 bytes |
when DBG_EXEC => |
if (OCDCR.DBGMODE='1') then |
OCD.SINGLESTEP:='1'; |
CAN_FETCH:='0'; |
IQUEUE.CNT := 0; |
IQUEUE.FETCH_STATE := F_ADDR; |
end if; |
DBG_CMD := DBG_EXEC2; |
when DBG_EXEC2 => |
if (DBG_UART.RX_DONE='1') then |
if (OCDCR.DBGMODE='0') then DBG_CMD := DBG_WAIT_CMD; |
else |
IQUEUE.QUEUE(IQUEUE.WRPOS) := DBG_UART.RX_DATA; |
DBG_UART.RX_DONE:='0'; |
IQUEUE.WRPOS := IQUEUE.WRPOS + 1; |
IQUEUE.CNT := IQUEUE.CNT + 1; |
DBG_CMD := DBG_EXEC3; |
end if; |
end if; |
when DBG_EXEC3 => |
if (OCD.SINGLESTEP='1') then DBG_CMD := DBG_EXEC2; else |
DBG_CMD := DBG_WAIT_CMD; |
IQUEUE.FETCH_STATE := F_ADDR; |
end if; |
when others => |
end case; |
-- end of debugger command processor |
|
if (ATM_COUNTER/=3) then ATM_COUNTER := ATM_COUNTER+1; |
else -- interrupt processing ***************************************************************************** |
if (IRQE='1') then -- if interrupts are enabled |
-- first the highest priority interrupts |
-- first the highest priority level interrupts |
if ((IRQ0(7)='1') and (IRQ0ENH(7)='1') and IRQ0ENL(7)='1') then |
INTVECT:=x"08"; |
IRQ0(7):='0'; |
1111,744 → 1127,748
IRQ0(0):='0'; |
end if; |
if (INTVECT/=x"00") then |
DEST_ADDR16 := PC; |
IAB <= x"00"&INTVECT; -- build the address of the interrupt vector |
SP := SP - 1; -- prepare stack pointer by decrementing it |
MAB <= SP; -- put SP on MAB |
CAN_FETCH := '0'; -- disable instruction fetching |
IQUEUE.CNT := 0; -- empty instruction queue |
STOP <= '0'; -- disable stop bit |
LU_INSTRUCTION := '1'; -- the stacking uses this bit to flag it is an interrupt stacking operation |
CPU_STATE := CPU_STACK; |
if (OCDCR.DBGMODE='0' or (OCDCR.DBGMODE='1' and OCD.SINGLESTEP='1')) then |
DEST_ADDR16 := PC; |
IAB <= x"00"&INTVECT; -- build the interrupt vector address |
SP := SP - 1; -- prepare stack pointer by decrementing it |
FRAB <= SP; -- put SP on FRAB |
CAN_FETCH := '0'; -- disable instruction fetching |
OCD.SINGLESTEP := '0'; -- disable stepping |
IQUEUE.CNT := 0; -- set queue empty |
STOP <= '0'; -- disable stop bit |
HALT := '0'; -- disable halt mode |
INT_FLAG := '1'; -- signal it is an interrupt stacking operation |
CPU_STATE := CPU_VECTOR; |
end if; |
end if; |
end if; |
end if; |
|
if (OCDCR.DBGMODE='0' or (OCDCR.DBGMODE='1' and OCD.SINGLESTEP='1')) then |
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 5-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=5) then |
---------------------------------------------------------------------------------------------------- 2nd page instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then |
---------------------------------------------------------------------------------------------- CPC ER2,ER1 instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A8") then |
MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4)); |
DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4)); |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 5; |
CPU_STATE := CPU_TMA; |
---------------------------------------------------------------------------------------------- CPC IMM,ER1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A9") then |
MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 5; |
CPU_STATE := CPU_OMA; |
--------------------------------------------------------------------------------------------- LDWX ER1,ER2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"E8") then |
MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4)); |
DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4)); |
NUM_BYTES := 5; |
CPU_STATE := CPU_LDW; |
end if; -- if IRQE=1 |
end if; -- if ATM_COUNTER... |
if (STOP='0' and HALT='0') then |
if (OCDCR.DBGMODE='0' or (OCDCR.DBGMODE='1' and OCD.SINGLESTEP='1')) then |
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 5-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=5) then -- 5-byte instructions |
---------------------------------------------------------------------------------------------------- 2nd page instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then |
---------------------------------------------------------------------------------------------- CPC ER2,ER1 instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A8") then |
FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4)); |
DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4)); |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 5; |
CPU_STATE := CPU_TMA; |
---------------------------------------------------------------------------------------------- CPC IMM,ER1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A9") then |
FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 5; |
CPU_STATE := CPU_OMA; |
--------------------------------------------------------------------------------------------- LDWX ER1,ER2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"E8") then |
FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)(7 downto 4)); |
DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+3)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+4)); |
NUM_BYTES := 5; |
CPU_STATE := CPU_LDW; |
end if; |
end if; |
end if; |
end if; |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 4-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=4) then |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then ------------------------------------------------ column 9 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------- LDX rr1,r2,X instruction |
when x"9" => ------------------------------------------------------------------------ LEA rr1,rr2,X instruction |
when x"C" => |
CPU_STATE := CPU_ILLEGAL; |
when x"D" => |
CPU_STATE := CPU_ILLEGAL; |
when x"F" => |
CPU_STATE := CPU_ILLEGAL; |
when others => -------------------------------------------------------------- IM,ER1 addressing mode instructions |
MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 4-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=4) then -- 4-byte instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then ------------------------------------------------ column 9 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------- LDX rr1,r2,X instruction |
when x"9" => ------------------------------------------------------------------------ LEA rr1,rr2,X instruction |
when x"C" => |
CPU_STATE := CPU_ILLEGAL; |
when x"D" => |
CPU_STATE := CPU_ILLEGAL; |
when x"F" => |
CPU_STATE := CPU_ILLEGAL; |
when others => -------------------------------------------------------------- IM,ER1 addressing mode instructions |
FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 4; |
CPU_STATE := CPU_OMA; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------- LDX r1,rr2,X instruction |
when x"9" => -------------------------------------------------------------------------- LEA r1,r2,X instruction |
when x"C" => -------------------------------------------------------------------------------- PUSHX instruction |
when x"D" => --------------------------------------------------------------------------------- POPX instruction |
when x"F" => |
CPU_STATE := CPU_ILLEGAL; |
when others => ------------------------------------------------------------- ER2,ER1 addressing mode instructions |
FRAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+1)) & IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); |
DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 4; |
CPU_STATE := CPU_TMA; |
end case; |
---------------------------------------------------------------------------------------------------- 2nd page instructions |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then |
------------------------------------------------------------------------------------------------ CPC R2,R1 instruction |
TEMP_OP := ALU_CPC; |
if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A4") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 4; |
CPU_STATE := CPU_OMA; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------- LDX r1,rr2,X instruction |
when x"9" => -------------------------------------------------------------------------- LEA r1,r2,X instruction |
when x"C" => -------------------------------------------------------------------------------- PUSHX instruction |
when x"D" => --------------------------------------------------------------------------------- POPX instruction |
when x"F" => |
CPU_STATE := CPU_ILLEGAL; |
when others => ------------------------------------------------------------- ER2,ER1 addressing mode instructions |
MAB <= ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+1)) & IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); |
DEST_ADDR := ADDRESSER12((IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)) & IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
CPU_STATE := CPU_TMA; |
----------------------------------------------------------------------------------------------- CPC IR2,R1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A5") then |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 4; |
CPU_STATE := CPU_TMA; |
end case; |
---------------------------------------------------------------------------------------------------- 2nd page instructions |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then |
------------------------------------------------------------------------------------------------ CPC R2,R1 instruction |
TEMP_OP := ALU_CPC; |
if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A4") then |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 4; |
CPU_STATE := CPU_TMA; |
----------------------------------------------------------------------------------------------- CPC IR2,R1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A5") then |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+3)); |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 4; |
CPU_STATE := CPU_ISMD1; |
----------------------------------------------------------------------------------------------- CPC R1,IMM instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A6") then |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3); |
NUM_BYTES := 4; |
CPU_STATE := CPU_OMA; |
---------------------------------------------------------------------------------------------- CPC IR1,IMM instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A7") then |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3); |
NUM_BYTES := 4; |
CPU_STATE := CPU_IND1; |
CPU_STATE := CPU_ISMD1; |
----------------------------------------------------------------------------------------------- CPC R1,IMM instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A6") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3); |
NUM_BYTES := 4; |
CPU_STATE := CPU_OMA; |
---------------------------------------------------------------------------------------------- CPC IR1,IMM instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A7") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+3); |
NUM_BYTES := 4; |
CPU_STATE := CPU_IND1; |
end if; |
end if; |
end if; |
end if; |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 3-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=3) then |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"D") then -------------------------------------------------- JP cc,DirectAddress |
if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then |
PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
IQUEUE.FETCH_STATE := F_ADDR; |
else |
NUM_BYTES := 3; |
end if; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then -------------------------------------------- column 9 instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then ----------------------------------------- LDX rr1,r2,X instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT = offset (X) |
NUM_BYTES := 3; |
CPU_STATE := CPU_XRRD; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then ------------------------------------ LEA rr1,rr2,X instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_XRRTORR; |
end if; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then ----------------------------------------- LDX r1,rr2,X instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT = offset (X) |
NUM_BYTES := 3; |
CPU_STATE := CPU_XRRS; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then -------------------------------------- LEA r1,r2,X instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_XRTOM; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"C") then ---------------------------------------- PUSHX ER2 instruction |
SP := SP - 1; |
MAB <= ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); |
DEST_ADDR := SP; |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"D") then ----------------------------------------- POPX ER2 instruction |
MAB <= SP; |
DEST_ADDR := ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); |
SP := SP + 1; |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
end if; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"7") then -------------------------------------------- column 7 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------- LDX IRR2,IR1 instruction |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 3-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=3) then -- 3-byte instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"D") then -------------------------------------------------- JP cc,DirectAddress |
if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then |
PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
IQUEUE.FETCH_STATE := F_ADDR; |
else |
NUM_BYTES := 3; |
CPU_STATE := CPU_IRRS; |
when x"9" => ------------------------------------------------------------------------- LDX IR2,IRR1 instruction |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
end if; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"9") then -------------------------------------------- column 9 instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then ----------------------------------------- LDX rr1,r2,X instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT = offset (X) |
NUM_BYTES := 3; |
CPU_STATE := CPU_IMTOIRR; |
when x"C" => --------------------------------------------------------------------------- LD r1,r2,X instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
CPU_STATE := CPU_XRRD; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then ------------------------------------ LEA rr1,rr2,X instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_XRRTORR; |
end if; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"8") then -------------------------------------------- column 8 instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"8") then ----------------------------------------- LDX r1,rr2,X instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT = offset (X) |
NUM_BYTES := 3; |
CPU_STATE := CPU_XADTOM; |
when x"D" => --------------------------------------------------------------------------- LD r2,r1,X instruction |
MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); |
DEST_ADDR := RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
CPU_STATE := CPU_XRRS; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"9") then -------------------------------------- LEA r1,r2,X instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_MTOXAD; |
when x"F" => ------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction |
when others => ----------------------------------------------------------------------------- IR1,imm instructions |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
CPU_STATE := CPU_XRTOM; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"C") then ---------------------------------------- PUSHX ER2 instruction |
SP := SP - 1; |
FRAB <= ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); |
DEST_ADDR := SP; |
NUM_BYTES := 3; |
CPU_STATE := CPU_IND1; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"6") then -------------------------------------------- column 6 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => -------------------------------------------------------------------------- LDX IRR2,R1 instruction |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
CPU_STATE := CPU_TMA; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)=x"D") then ----------------------------------------- POPX ER2 instruction |
FRAB <= SP; |
DEST_ADDR := ADDRESSER12(IQUEUE.QUEUE(IQUEUE.RDPOS+1)&IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); |
SP := SP + 1; |
NUM_BYTES := 3; |
LU_INSTRUCTION := '1'; -- in this mode this flag is used to signal the direct register addressing mode |
CPU_STATE := CPU_IRRS; |
when x"9" => -------------------------------------------------------------------------- LDX R2,IRR1 instruction |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_MTOIRR; |
when x"C" => -- illegal, decoded at 1-byte decoder |
--CPU_STATE := CPU_ILLEGAL; -- uncommenting this adds +400 LEs to the design!!! |
when x"D" => ------------------------------------------------------------------------------ CALL DA instruction |
when x"F" => ------------------------------------------------------------------------- BTJ p,b,r1,X instruction |
when others => ------------------------------------------------------------------------------ R1,imm instructions |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
CPU_STATE := CPU_TMA; |
end if; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"7") then -------------------------------------------- column 7 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------- LDX IRR2,IR1 instruction |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 3; |
CPU_STATE := CPU_IRRS; |
when x"9" => ------------------------------------------------------------------------- LDX IR2,IRR1 instruction |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 3; |
CPU_STATE := CPU_IMTOIRR; |
when x"C" => --------------------------------------------------------------------------- LD r1,r2,X instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT = offset (X) |
NUM_BYTES := 3; |
CPU_STATE := CPU_XADTOM; |
when x"D" => --------------------------------------------------------------------------- LD r2,r1,X instruction |
FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); |
DEST_ADDR := RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_MTOXAD; |
when x"F" => ------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction |
when others => ----------------------------------------------------------------------------- IR1,imm instructions |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 3; |
CPU_STATE := CPU_IND1; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"6") then -------------------------------------------- column 6 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => -------------------------------------------------------------------------- LDX IRR2,R1 instruction |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 3; |
LU_INSTRUCTION := '1'; -- in this mode this flag is used to signal the direct register addressing mode |
CPU_STATE := CPU_IRRS; |
when x"9" => -------------------------------------------------------------------------- LDX R2,IRR1 instruction |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 3; |
CPU_STATE := CPU_MTOIRR; |
when x"C" => -- illegal, decoded at 1-byte decoder |
--CPU_STATE := CPU_ILLEGAL; -- uncommenting this adds +400 LEs to the design!!! |
when x"D" => ------------------------------------------------------------------------------ CALL DA instruction |
when x"F" => ------------------------------------------------------------------------- BTJ p,b,r1,X instruction |
when others => ------------------------------------------------------------------------------ R1,imm instructions |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 3; |
CPU_STATE := CPU_OMA; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"5") then -------------------------------------------- column 5 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => -------------------------------------------------------------------------- LDX Ir1,ER2 instruction |
FRAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
NUM_BYTES := 3; |
CPU_STATE := CPU_IND2; |
when x"9" => -------------------------------------------------------------------------- LDX Ir2,ER1 instruction |
FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); |
DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_ISMD1; |
when x"C" => ------------------------------------------------------------------------- LDC Ir1,Irr2 instruction |
when x"D" => ----------------------------------------------------------------------------- BSWAP R1 instruction |
when x"F" => ---------------------------------------------------------------------------- LD R2,IR1 instruction |
when others => ------------------------------------------------------------------------------ IR2,R1 instructions |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 3; |
CPU_STATE := CPU_ISMD1; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"4") then -------------------------------------------- column 4 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => --------------------------------------------------------------------------- LDX r1,ER2 instruction |
FRAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
when x"9" => --------------------------------------------------------------------------- LDX r2,ER1 instruction |
FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); |
DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
when x"C" => ------------------------------------------------------------------------------ JP Irr1 instruction |
when x"D" => ---------------------------------------------------------------------------- CALL Irr1 instruction |
when x"F" => ----------------------------------------------------------------------------- MULT RR1 instruction |
when others => ------------------------------------------------------------------------------- R2,R1 instructions |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
end case; |
end if; |
------------------------------------------------------------------------------------------------- BTJ p,b,r1,X instruction |
------------------------------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F6" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F7") then |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0) |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT has the offset X |
NUM_BYTES := 3; |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(0)='0') then CPU_STATE := CPU_BTJ; else CPU_STATE := CPU_IBTJ; |
end if; |
---------------------------------------------------------------------------------------------------- LD R2,IR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F5") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
NUM_BYTES := 3; |
CPU_STATE := CPU_IND2; |
------------------------------------------------------------------------------------------------------ CALL DA instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D6") then |
DEST_ADDR16 := PC + 3; |
PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
SP := SP - 1; |
FRAB <= SP; |
LU_INSTRUCTION := '0'; -- this is used to indicate wether the stacking is due to a CALL or INT, 0 for a CALL |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_STACK; |
---------------------------------------------------------------------------------------------------- 2nd page instructions |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then |
-------------------------------------------------------------------------------------------------- PUSH IM instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"70") then |
SP := SP - 1; |
FRAB <= SP; |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 3; |
CPU_STATE := CPU_OMA; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"5") then -------------------------------------------- column 5 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => -------------------------------------------------------------------------- LDX Ir1,ER2 instruction |
MAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
CPU_STATE := CPU_OMA; |
------------------------------------------------------------------------------------------------ CPC r1,r2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A2") then |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); -- dest address |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 3; |
CPU_STATE := CPU_IND2; |
when x"9" => -------------------------------------------------------------------------- LDX Ir2,ER1 instruction |
MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); |
DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
CPU_STATE := CPU_TMA; |
----------------------------------------------------------------------------------------------- CPC r1,Ir2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A3") then |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); -- dest address |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 3; |
CPU_STATE := CPU_ISMD1; |
when x"C" => ------------------------------------------------------------------------- LDC Ir1,Irr2 instruction |
when x"D" => ----------------------------------------------------------------------------- BSWAP R1 instruction |
when x"F" => ---------------------------------------------------------------------------- LD R2,IR1 instruction |
when others => ------------------------------------------------------------------------------ IR2,R1 instructions |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
CPU_STATE := CPU_ISMD1; |
--------------------------------------------------------------------------------------------------- SRL R1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C0") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_OP := LU2_SRL; |
NUM_BYTES := 3; |
CPU_STATE := CPU_ISMD1; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"4") then -------------------------------------------- column 4 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => --------------------------------------------------------------------------- LDX r1,ER2 instruction |
MAB <= IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
CPU_STATE := CPU_OMA2; |
-------------------------------------------------------------------------------------------------- SRL IR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C1") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_OP := LU2_SRL; |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
when x"9" => --------------------------------------------------------------------------- LDX r2,ER1 instruction |
MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); |
DEST_ADDR := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
when x"C" => ------------------------------------------------------------------------------ JP Irr1 instruction |
when x"D" => ---------------------------------------------------------------------------- CALL Irr1 instruction |
when x"F" => ----------------------------------------------------------------------------- MULT RR1 instruction |
when others => ------------------------------------------------------------------------------- R2,R1 instructions |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
end case; |
end if; |
------------------------------------------------------------------------------------------------- BTJ p,b,r1,X instruction |
------------------------------------------------------------------------------------------------ BTJ p,b,Ir1,X instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F6" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F7") then |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0) |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT has the offset X |
NUM_BYTES := 3; |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(0)='0') then CPU_STATE := CPU_BTJ; else CPU_STATE := CPU_IBTJ; |
CPU_STATE := CPU_IND1; |
LU_INSTRUCTION := '1'; |
end if; |
end if; |
---------------------------------------------------------------------------------------------------- LD R2,IR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F5") then |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_IND2; |
------------------------------------------------------------------------------------------------------ CALL DA instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D6") then |
DEST_ADDR16 := PC + 3; |
PC := IQUEUE.QUEUE(IQUEUE.RDPOS+1) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
SP := SP - 1; |
MAB <= SP; |
LU_INSTRUCTION := '0'; -- this is used to indicate wether the stacking is due to a CALL or INT, 0 for a CALL |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_STACK; |
---------------------------------------------------------------------------------------------------- 2nd page instructions |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"1F") then |
-------------------------------------------------------------------------------------------------- PUSH IM instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"70") then |
SP := SP - 1; |
MAB <= SP; |
TEMP_DATA := IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
NUM_BYTES := 3; |
CPU_STATE := CPU_OMA; |
------------------------------------------------------------------------------------------------ CPC r1,r2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A2") then |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); -- dest address |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 3; |
CPU_STATE := CPU_TMA; |
----------------------------------------------------------------------------------------------- CPC r1,Ir2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"A3") then |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+2)(7 downto 4)); -- dest address |
TEMP_OP := ALU_CPC; |
NUM_BYTES := 3; |
CPU_STATE := CPU_ISMD1; |
--------------------------------------------------------------------------------------------------- SRL R1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C0") then |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+2)); |
TEMP_OP := LU2_SRL; |
NUM_BYTES := 3; |
CPU_STATE := CPU_OMA2; |
-------------------------------------------------------------------------------------------------- SRL IR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS+1)=x"C1") then |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+2); |
TEMP_OP := LU2_SRL; |
NUM_BYTES := 3; |
CPU_STATE := CPU_IND1; |
LU_INSTRUCTION := '1'; |
end if; |
end if; |
end if; |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 2-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=2) then |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"C") then ------------------------------------------------- LD r,IMM instruction |
MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
DATAWRITE(RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4),IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
NUM_BYTES := 2; |
CPU_STATE := CPU_STORE; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"B") then -------------------------------------------- JR cc,RelativeAddress |
PC := PC + 2; |
if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then |
PC := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 2-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=2) then -- 2-byte instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"C") then ------------------------------------------------- LD r,IMM instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)); |
DATAWRITE(ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)),IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
NUM_BYTES := 2; |
CPU_STATE := CPU_STORE; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"B") then -------------------------------------------- JR cc,RelativeAddress |
PC := PC + 2; |
if (CONDITIONCODE(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4))='1') then |
PC := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
IQUEUE.FETCH_STATE := F_ADDR; |
else |
IQUEUE.RDPOS := IQUEUE.RDPOS + 2; |
IQUEUE.CNT := IQUEUE.CNT - 2; |
end if; |
CPU_STATE := CPU_DECOD; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"A") then ------------------------------------------- DJNZ r,RelativeAddress |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4)); |
PC := PC + 2; |
DEST_ADDR16 := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
IQUEUE.RDPOS := IQUEUE.RDPOS + 2; |
IQUEUE.CNT := IQUEUE.CNT - 2; |
IQUEUE.FETCH_STATE := F_ADDR; |
else |
IQUEUE.RDPOS := IQUEUE.RDPOS + 2; |
IQUEUE.CNT := IQUEUE.CNT - 2; |
CPU_STATE := CPU_DJNZ; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"3") then -------------------------------------------- column 3 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------ LDEI Ir1,Irr2 instruction |
when x"9" => ------------------------------------------------------------------------ LDEI Ir2,Irr1 instruction |
when x"C" => ------------------------------------------------------------------------ LDCI Ir1,Irr2 instruction |
RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '0'; -- indicates it is a read from program memory |
WORD_DATA := '1'; -- indicates it is a LDCI instruction |
CPU_STATE := CPU_LDPTOIM; |
when x"D" => ------------------------------------------------------------------------ LDCI Ir2,Irr1 instruction |
RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '1'; -- indicates it is a write onto program memory |
WORD_DATA := '1'; -- indicates it is a LDCI instruction |
CPU_STATE := CPU_LDPTOIM; |
when x"F" => ---------------------------------------------------------------------------- LD Ir1,r2 instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CPU_STATE := CPU_IND2; |
when others => --------------------------------------------------------------------------- Ir2 to r1 instructions |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_ISMD1; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"2") then -------------------------------------------- column 2 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => -------------------------------------------------------------------------- LDE r1,Irr2 instruction |
when x"9" => -------------------------------------------------------------------------- LDE r2,Irr1 instruction |
when x"C" => -------------------------------------------------------------------------- LDC r1,Irr2 instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '0'; |
CPU_STATE := CPU_LDPTOM; |
when x"D" => -------------------------------------------------------------------------- LDC r2,Irr1 instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '1'; |
CPU_STATE := CPU_LDPTOM; |
when x"E" => --------------------------------------------------------------------------- BIT p,b,r1 instruction |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0) |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT has the offset X |
NUM_BYTES := 2; |
CPU_STATE := CPU_BIT; |
when x"F" => ----------------------------------------------------------------------------- TRAP imm instruction |
FRAB <= "000" & IQUEUE.QUEUE(IQUEUE.RDPOS+1) & '0'; |
DEST_ADDR16 := PC + 2; |
NUM_BYTES := 2; |
CPU_STATE := CPU_TRAP; |
when others => ---------------------------------------------------------------------------- r2 to r1 instructions |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_TMA; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"1") then -------------------------------------------- column 1 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"0" => ------------------------------------------------------------------------------ SRP IMM instruction |
RP := IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
NUM_BYTES := 2; |
CPU_STATE := CPU_DECOD; |
when x"5" => ------------------------------------------------------------------------------ POP IR1 instruction |
FRAB <= SP; |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
SP := SP + 1; |
NUM_BYTES := 2; |
CPU_STATE := CPU_IND2; |
when x"7" => ----------------------------------------------------------------------------- PUSH IR1 instruction |
SP := SP - 1; |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := SP; |
NUM_BYTES := 2; |
CPU_STATE := CPU_ISMD1; |
when x"8" => --------------------------------------------------------------------------------- DECW instruction |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := LU2_DEC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_INDRR; |
when x"A" => --------------------------------------------------------------------------------- INCW instruction |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := LU2_INC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_INDRR; |
when others => --------------------------------------------------------------------------------- IR1 instructions |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_IND1; |
LU_INSTRUCTION := '1'; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"0") then -------------------------------------------- column 0 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"0" => ---------------------------------------------------------------------------------- BRK instruction |
-- do nothing, BRK decoding is done in 1-byte instruction section |
when x"5" => ---------------------------------------------------------------------------------- POP instruction |
FRAB <= SP; |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
SP := SP + 1; |
NUM_BYTES := 2; |
CPU_STATE := CPU_TMA; |
when x"7" => --------------------------------------------------------------------------------- PUSH instruction |
SP := SP - 1; |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := SP; |
NUM_BYTES := 2; |
CPU_STATE := CPU_TMA; |
when x"8" => --------------------------------------------------------------------------------- DECW instruction |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
FRAB <= DEST_ADDR+1; |
TEMP_OP := LU2_DEC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA2; |
when x"A" => --------------------------------------------------------------------------------- INCW instruction |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
FRAB <= DEST_ADDR+1; |
TEMP_OP := LU2_INC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA2; |
when others => ---------------------------------------------------------------------------------- R1 instructions |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA2; |
end case; |
end if; |
---------------------------------------------------------------------------------------------------------- MUL instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F4") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
NUM_BYTES := 2; |
CPU_STATE := CPU_MUL; |
---------------------------------------------------------------------------------------------------- CALL IRR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D4") then |
DEST_ADDR16 := PC + 2; |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_INDSTACK; |
------------------------------------------------------------------------------------------------------ JP IRR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C4") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_INDJUMP; |
----------------------------------------------------------------------------------------------------- BSWAP R1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D5") then |
FRAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := ALU_BSWAP; |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA; |
------------------------------------------------------------------------------------------------- LDC Ir1,Irr2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C5") then |
RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
FRAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '0'; |
CPU_STATE := CPU_LDPTOIM; |
end if; |
CPU_STATE := CPU_DECOD; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"A") then ------------------------------------------- DJNZ r,RelativeAddress |
MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
PC := PC + 2; |
DEST_ADDR16 := ADDER16(PC,IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
IQUEUE.RDPOS := IQUEUE.RDPOS + 2; |
IQUEUE.CNT := IQUEUE.CNT - 2; |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_DJNZ; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"3") then -------------------------------------------- column 3 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => ------------------------------------------------------------------------ LDEI Ir1,Irr2 instruction |
when x"9" => ------------------------------------------------------------------------ LDEI Ir2,Irr1 instruction |
when x"C" => ------------------------------------------------------------------------ LDCI Ir1,Irr2 instruction |
RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '0'; -- indicates it is a read from program memory |
WORD_DATA := '1'; -- indicates it is a LDCI instruction |
CPU_STATE := CPU_LDPTOIM; |
when x"D" => ------------------------------------------------------------------------ LDCI Ir2,Irr1 instruction |
RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '1'; -- indicates it is a write onto program memory |
WORD_DATA := '1'; -- indicates it is a LDCI instruction |
CPU_STATE := CPU_LDPTOIM; |
when x"F" => ---------------------------------------------------------------------------- LD Ir1,r2 instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CPU_STATE := CPU_IND2; |
when others => --------------------------------------------------------------------------- Ir2 to r1 instructions |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_ISMD1; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"2") then -------------------------------------------- column 2 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"8" => -------------------------------------------------------------------------- LDE r1,Irr2 instruction |
when x"9" => -------------------------------------------------------------------------- LDE r2,Irr1 instruction |
when x"C" => -------------------------------------------------------------------------- LDC r1,Irr2 instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '0'; |
CPU_STATE := CPU_LDPTOM; |
when x"D" => -------------------------------------------------------------------------- LDC r2,Irr1 instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '1'; |
CPU_STATE := CPU_LDPTOM; |
when x"E" => --------------------------------------------------------------------------- BIT p,b,r1 instruction |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4); -- TEMP_OP has the polarity (bit 3) and bit number (bits 2:0) |
RESULT := IQUEUE.QUEUE(IQUEUE.RDPOS+2); -- RESULT has the offset X |
NUM_BYTES := 2; |
CPU_STATE := CPU_BIT; |
when x"F" => ----------------------------------------------------------------------------- TRAP imm instruction |
MAB <= "000" & IQUEUE.QUEUE(IQUEUE.RDPOS+1) & '0'; |
DEST_ADDR16 := PC + 2; |
NUM_BYTES := 2; |
CPU_STATE := CPU_TRAP; |
when others => ---------------------------------------------------------------------------- r2 to r1 instructions |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0)); -- source address |
DEST_ADDR := ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); -- dest address |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_TMA; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"1") then -------------------------------------------- column 1 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"0" => ------------------------------------------------------------------------------ SRP IMM instruction |
RP := IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
NUM_BYTES := 2; |
CPU_STATE := CPU_DECOD; |
when x"5" => ------------------------------------------------------------------------------ POP IR1 instruction |
MAB <= SP; |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
SP := SP + 1; |
NUM_BYTES := 2; |
CPU_STATE := CPU_IND2; |
when x"7" => ----------------------------------------------------------------------------- PUSH IR1 instruction |
SP := SP - 1; |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
DEST_ADDR := SP; |
NUM_BYTES := 2; |
CPU_STATE := CPU_ISMD1; |
when x"8" => --------------------------------------------------------------------------------- DECW instruction |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := LU2_DEC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_INDRR; |
when x"A" => --------------------------------------------------------------------------------- INCW instruction |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := LU2_INC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_INDRR; |
when others => --------------------------------------------------------------------------------- IR1 instructions |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_IND1; |
LU_INSTRUCTION := '1'; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"0") then -------------------------------------------- column 0 instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"0" => ---------------------------------------------------------------------------------- BRK instruction |
-- do nothing, BRK decoding is done in 1-byte instruction section |
when x"5" => ---------------------------------------------------------------------------------- POP instruction |
MAB <= SP; |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
SP := SP + 1; |
NUM_BYTES := 2; |
CPU_STATE := CPU_TMA; |
when x"7" => --------------------------------------------------------------------------------- PUSH instruction |
SP := SP - 1; |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
DEST_ADDR := SP; |
NUM_BYTES := 2; |
CPU_STATE := CPU_TMA; |
when x"8" => --------------------------------------------------------------------------------- DECW instruction |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
MAB <= DEST_ADDR+1; |
TEMP_OP := LU2_DEC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA2; |
when x"A" => --------------------------------------------------------------------------------- INCW instruction |
DEST_ADDR := ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
MAB <= DEST_ADDR+1; |
TEMP_OP := LU2_INC; |
WORD_DATA := '1'; |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA2; |
when others => ---------------------------------------------------------------------------------- R1 instructions |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA2; |
end case; |
end if; |
---------------------------------------------------------------------------------------------------------- MUL instruction |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F4") then |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
NUM_BYTES := 2; |
CPU_STATE := CPU_MUL; |
---------------------------------------------------------------------------------------------------- CALL IRR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D4") then |
DEST_ADDR16 := PC + 2; |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_INDSTACK; |
------------------------------------------------------------------------------------------------------ JP IRR1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C4") then |
MAB <= RP(3 downto 0) & IQUEUE.QUEUE(IQUEUE.RDPOS+1); |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_INDJUMP; |
----------------------------------------------------------------------------------------------------- BSWAP R1 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D5") then |
MAB <= ADDRESSER8(IQUEUE.QUEUE(IQUEUE.RDPOS+1)); |
TEMP_OP := ALU_BSWAP; |
NUM_BYTES := 2; |
CPU_STATE := CPU_OMA; |
------------------------------------------------------------------------------------------------- LDC Ir1,Irr2 instruction |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C5") then |
RESULT(3 downto 0) := IQUEUE.QUEUE(IQUEUE.RDPOS+1)(3 downto 0); |
MAB <= ADDRESSER4(IQUEUE.QUEUE(IQUEUE.RDPOS+1)(7 downto 4)); |
NUM_BYTES := 2; |
CAN_FETCH := '0'; |
LU_INSTRUCTION := '0'; |
CPU_STATE := CPU_LDPTOIM; |
end if; |
end if; |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 1-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=1) then |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"F") then ------------------------------------------------ column F instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"0" => ---------------------------------------------------------------------------------- NOP instruction |
NUM_BYTES := 1; |
when x"1" => ------------------------------------------------------------------------------ page 2 instructions |
when x"2" => |
ATM_COUNTER := 0; |
NUM_BYTES := 1; |
when x"3" => |
CPU_STATE := CPU_ILLEGAL; |
when x"4" => |
CPU_STATE := CPU_ILLEGAL; |
when x"5" => ---------------------------------------------------------------------------------- WDT instruction |
NUM_BYTES := 1; |
when x"6" => --------------------------------------------------------------------------------- STOP instruction |
NUM_BYTES := 1; |
CPU_STATE := CPU_HALTED; |
STOP <= '1'; |
when x"7" => --------------------------------------------------------------------------------- HALT instruction |
NUM_BYTES := 1; |
CPU_STATE := CPU_HALTED; |
when x"8" => ----------------------------------------------------------------------------------- DI instruction |
IRQE := '0'; |
NUM_BYTES := 1; |
when x"9" => ----------------------------------------------------------------------------------- EI instruction |
IRQE := '1'; |
NUM_BYTES := 1; |
when x"A" => ---------------------------------------------------------------------------------- RET instruction |
NUM_BYTES := 1; |
MAB <= SP; |
CPU_STATE := CPU_UNSTACK; |
when x"B" => --------------------------------------------------------------------------------- IRET instruction |
NUM_BYTES := 1; |
IRQE := '1'; |
MAB <= SP; |
CPU_STATE := CPU_UNSTACK3; |
when x"C" => ---------------------------------------------------------------------------------- RCF instruction |
CPU_FLAGS.C := '0'; |
NUM_BYTES := 1; |
when x"D" => ---------------------------------------------------------------------------------- SCF instruction |
CPU_FLAGS.C := '1'; |
NUM_BYTES := 1; |
when x"E" => ---------------------------------------------------------------------------------- CCF instruction |
CPU_FLAGS.C := not CPU_FLAGS.C; |
NUM_BYTES := 1; |
when others => ---------------------------------------------------------------------------------- R1 instructions |
CPU_STATE := CPU_ILLEGAL; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"E") then ------------------------------------------------ INC r instruction |
MAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
TEMP_OP := LU2_INC; |
NUM_BYTES := 1; |
CPU_STATE := CPU_OMA2; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"00") then -------------------------------------------------------------- BRK instruction |
if (OCDCR.BRKEN='1') then -- the BRK instruction is enabled |
if (OCDCR.DBGACK='1') then |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=x"FF"; |
DBG_UART.TX_EMPTY:='0'; |
|
------------------------------------------------------------------------------------------------------------------------------ |
--**************************************************************************************************************************-- |
-- 1-byte instructions -- |
--**************************************************************************************************************************-- |
------------------------------------------------------------------------------------------------------------------------------ |
if (IQUEUE.CNT>=1) then -- 1-byte instructions |
if (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"F") then ------------------------------------------------ column F instructions |
case IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4) is |
when x"0" => ---------------------------------------------------------------------------------- NOP instruction |
NUM_BYTES := 1; |
when x"1" => ------------------------------------------------------------------------------ page 2 instructions |
when x"2" => |
ATM_COUNTER := 0; |
NUM_BYTES := 1; |
when x"3" => |
CPU_STATE := CPU_ILLEGAL; |
when x"4" => |
CPU_STATE := CPU_ILLEGAL; |
when x"5" => ---------------------------------------------------------------------------------- WDT instruction |
NUM_BYTES := 1; |
when x"6" => --------------------------------------------------------------------------------- STOP instruction |
NUM_BYTES := 1; |
STOP <= '1'; |
when x"7" => --------------------------------------------------------------------------------- HALT instruction |
NUM_BYTES := 1; |
HALT := '1'; |
when x"8" => ----------------------------------------------------------------------------------- DI instruction |
IRQE := '0'; |
NUM_BYTES := 1; |
when x"9" => ----------------------------------------------------------------------------------- EI instruction |
IRQE := '1'; |
NUM_BYTES := 1; |
when x"A" => ---------------------------------------------------------------------------------- RET instruction |
NUM_BYTES := 1; |
FRAB <= SP; |
CPU_STATE := CPU_UNSTACK2; |
when x"B" => --------------------------------------------------------------------------------- IRET instruction |
NUM_BYTES := 1; |
IRQE := '1'; |
FRAB <= SP; |
CPU_STATE := CPU_UNSTACK3; |
when x"C" => ---------------------------------------------------------------------------------- RCF instruction |
CPU_FLAGS.C := '0'; |
NUM_BYTES := 1; |
when x"D" => ---------------------------------------------------------------------------------- SCF instruction |
CPU_FLAGS.C := '1'; |
NUM_BYTES := 1; |
when x"E" => ---------------------------------------------------------------------------------- CCF instruction |
CPU_FLAGS.C := not CPU_FLAGS.C; |
NUM_BYTES := 1; |
when others => ---------------------------------------------------------------------------------- R1 instructions |
CPU_STATE := CPU_ILLEGAL; |
end case; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)(3 downto 0)=x"E") then ------------------------------------------------ INC r instruction |
FRAB <= RP(3 downto 0) & RP(7 downto 4) & IQUEUE.QUEUE(IQUEUE.RDPOS)(7 downto 4); |
TEMP_OP := LU2_INC; |
NUM_BYTES := 1; |
CPU_STATE := CPU_OMA2; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"00") then -------------------------------------------------------------- BRK instruction |
if (OCDCR.BRKEN='1') then -- the BRK instruction is enabled |
if (OCDCR.DBGACK='1') then |
if (DBG_UART.TX_EMPTY='1') then |
DBG_UART.TX_DATA:=x"FF"; |
DBG_UART.TX_EMPTY:='0'; |
end if; |
end if; |
if (OCDCR.BRKLOOP='0') then -- if loop on BRK is disabled |
OCDCR.DBGMODE := '1'; -- set DBGMODE halting CPU |
end if; |
else |
NUM_BYTES := 1; -- remove the instruction from queue (execute as a NOP) |
end if; |
if (OCDCR.BRKLOOP='0') then -- if loop on BRK is disabled |
OCDCR.DBGMODE := '1'; -- set DBGMODE halting CPU |
end if; |
else |
NUM_BYTES := 1; -- remove the instruction from queue (execute as a NOP) |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F9" or |
IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F8" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C6") then --------------------------- illegal opcode |
CPU_STATE:= CPU_ILLEGAL; |
NUM_BYTES := 1; |
end if; |
elsif (IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"D9" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F9" or |
IQUEUE.QUEUE(IQUEUE.RDPOS)=x"F8" or IQUEUE.QUEUE(IQUEUE.RDPOS)=x"C6") then --------------------------- illegal opcode |
CPU_STATE:= CPU_ILLEGAL; |
NUM_BYTES := 1; |
end if; |
end if; -- if DBGMODE=0... |
end if; -- if not stopped or halted |
PC := PC + NUM_BYTES; -- update PC after instruction |
IQUEUE.RDPOS := IQUEUE.RDPOS + NUM_BYTES; -- update QUEUE read pointer |
IQUEUE.CNT := IQUEUE.CNT - NUM_BYTES; -- update QUEUE available bytes |
if (OCD.SINGLESTEP='1') then -- if we are stepping instructions |
if (NUM_BYTES/=0 or IQUEUE.FETCH_STATE=F_ADDR) then OCD.SINGLESTEP:='0'; -- if a instruction was decoded, reset step flag |
end if; |
end if; |
PC := PC + NUM_BYTES; |
IQUEUE.RDPOS := IQUEUE.RDPOS + NUM_BYTES; |
IQUEUE.CNT := IQUEUE.CNT - NUM_BYTES; |
if (OCD.SINGLESTEP='1') then |
if (NUM_BYTES/=0 or IQUEUE.FETCH_STATE=F_ADDR) then OCD.SINGLESTEP:='0'; |
end if; |
end if; |
when CPU_MUL => -- MUL *********************************************************************************************************** |
TEMP_DATA := DATAREAD(MAB); -- read first operand |
MAB <= MAB + 1; -- go to the next operand |
TEMP_DATA := DATAREAD(FRAB); -- read first operand |
FRAB <= FRAB + 1; -- go to the next operand |
CPU_STATE := CPU_MUL1; |
when CPU_MUL1 => |
DEST_ADDR16 := TEMP_DATA * DATAREAD(MAB); -- multiply previous operand by the second operand and store temporarily |
DATAWRITE(MAB,DEST_ADDR16(7 downto 0)); -- write the lower byte in current memory address |
DEST_ADDR16 := TEMP_DATA * DATAREAD(FRAB); -- multiply previous operand by the second operand and store temporarily |
DATAWRITE(FRAB,DEST_ADDR16(7 downto 0)); -- prepare to write the lower byte in current memory address |
WR <= '1'; |
CPU_STATE := CPU_MUL2; |
when CPU_MUL2 => |
MAB <= MAB - 1; -- decrement memory address (point to the first operand) |
DATAWRITE(MAB,DEST_ADDR16(15 downto 8)); -- write the higher byte |
FRAB <= FRAB - 1; -- decrement memory address (point to the first operand) |
DATAWRITE(FRAB,DEST_ADDR16(15 downto 8)); -- write the higher byte |
CPU_STATE := CPU_STORE; -- complete store operation |
when CPU_XRRTORR => -- LEA ******************************************************************************************************* |
TEMP_DATA := DATAREAD(MAB); -- read the operand and store it |
MAB <= MAB + 1; -- go to the next memory address |
TEMP_DATA := DATAREAD(FRAB); -- read the operand and store it |
FRAB <= FRAB + 1; -- go to the next memory address |
CPU_STATE := CPU_XRRTORR2; |
when CPU_XRRTORR2 => |
-- read the next operand and perform a 16 bit add with the offset previously in result |
DEST_ADDR16 := ADDER16(TEMP_DATA & DATAREAD(MAB),RESULT); |
MAB <= DEST_ADDR; -- point to the destination address |
DATAWRITE(MAB,DEST_ADDR16(15 downto 8)); -- store the higher byte of the 16-bit result |
-- read next operand and perform a 16 bit add with the offset previously in result |
DEST_ADDR16 := ADDER16(TEMP_DATA & DATAREAD(FRAB),RESULT); |
FRAB <= DEST_ADDR; -- point to the destination address |
DATAWRITE(FRAB,DEST_ADDR16(15 downto 8)); -- store the higher byte of the 16-bit result |
CPU_STATE := CPU_XRRTORR3; |
when CPU_XRRTORR3 => |
WR <= '1'; |
CPU_STATE := CPU_XRRTORR4; |
when CPU_XRRTORR4 => |
MAB <= MAB + 1; -- go to the next memory address |
DATAWRITE(MAB,DEST_ADDR16(7 downto 0)); -- store the lower byte of the 16-bit result |
FRAB <= FRAB + 1; -- go to the next memory address |
DATAWRITE(FRAB,DEST_ADDR16(7 downto 0)); -- store the lower byte of the 16-bit result |
CPU_STATE := CPU_STORE; -- complete store operation |
when CPU_MTOXAD => -- MEMORY TO INDEXED 8-BIT ADDRESS *************************************************************************** |
TEMP_DATA := DATAREAD(MAB); |
MAB <= DEST_ADDR; |
TEMP_DATA := DATAREAD(FRAB); -- read operand from memory |
FRAB <= DEST_ADDR; -- update address bus with destination address |
CPU_STATE := CPU_MTOXAD2; |
when CPU_MTOXAD2 => |
MAB <= RP(3 downto 0)&(DATAREAD(MAB) + RESULT); |
DATAWRITE(MAB,TEMP_DATA); |
CPU_STATE := CPU_STORE; |
FRAB <= RP(3 downto 0)&(DATAREAD(FRAB) + RESULT); -- update address bus indexed result |
DATAWRITE(FRAB,TEMP_DATA); -- prepare to write data on destination (indexed) address |
CPU_STATE := CPU_STORE; -- perform store (WR=1) |
when CPU_XADTOM => -- INDEXED 8-BIT ADDRESS TO MEMORY *************************************************************************** |
MAB <= RP(3 downto 0)&(DATAREAD(MAB) + RESULT); |
FRAB <= RP(3 downto 0)&(DATAREAD(FRAB) + RESULT); |
CPU_STATE := CPU_TMA; |
when CPU_XRTOM => -- LEA ******************************************************************************************************* |
TEMP_DATA := DATAREAD(MAB)+RESULT; |
MAB <= DEST_ADDR; |
DATAWRITE(MAB,TEMP_DATA); |
TEMP_DATA := DATAREAD(FRAB)+RESULT; |
FRAB <= DEST_ADDR; |
DATAWRITE(FRAB,TEMP_DATA); |
CPU_STATE := CPU_STORE; |
when CPU_IMTOIRR => -- INDIRECT MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR *********************************************** |
MAB <= RP(3 downto 0) & DATAREAD(MAB); -- source address is read from indirect register |
FRAB <= RP(3 downto 0) & DATAREAD(FRAB); -- source address is read from indirect register |
CPU_STATE := CPU_MTOIRR; |
when CPU_MTOIRR => -- MEMORY TO INDIRECT ADDRESS READ FROM REGISTER PAIR ******************************************************** |
TEMP_DATA := DATAREAD(MAB); -- reads data from the source (MAB) address and store it into TEMP_DATA |
MAB <= DEST_ADDR; -- MAB points to the indirect destination register pair |
TEMP_DATA := DATAREAD(FRAB); -- reads data from the source (FRAB) address and store it into TEMP_DATA |
FRAB <= DEST_ADDR; -- FRAB points to the indirect destination register pair |
RESULT := x"00"; |
CPU_STATE := CPU_XRRD2; -- proceed as X indexed register pair destination |
CPU_STATE := CPU_XRRD2; -- proceed as X indexed register pair destination |
when CPU_IRRS => -- RR PAIR AS INDIRECT SOURCE ADDRESS ************************************************************************ |
DEST_ADDR16(15 downto 8) := DATAREAD(MAB); |
MAB <= MAB + 1; |
DEST_ADDR16(15 downto 8) := DATAREAD(FRAB); |
FRAB <= FRAB + 1; |
CPU_STATE := CPU_IRRS2; |
when CPU_IRRS2 => |
DEST_ADDR16(7 downto 0) := DATAREAD(MAB); |
MAB <= DEST_ADDR16(11 downto 0); |
DEST_ADDR16(7 downto 0) := DATAREAD(FRAB); |
FRAB <= DEST_ADDR16(11 downto 0); |
if (LU_INSTRUCTION='1') then |
CPU_STATE:= CPU_TMA; -- if it is direct addressing mode, go to TMA |
else |
CPU_STATE := CPU_IND2; -- if it is indirect addressing mode, go to IND2 |
end if; |
when CPU_XRRD => |
TEMP_DATA := DATAREAD(MAB); -- reads data from the source (MAB) address and store it into TEMP_DATA |
MAB <= DEST_ADDR; |
when CPU_XRRD => -- RR PAIR PLUS OFFSET AS DESTINATION ADDRESS **************************************************************** |
TEMP_DATA := DATAREAD(FRAB); -- reads data from the source (FRAB) address and store it into TEMP_DATA |
FRAB <= DEST_ADDR; |
CPU_STATE := CPU_XRRD2; |
when CPU_XRRD2 => |
DEST_ADDR16(15 downto 8) := DATAREAD(MAB); |
MAB <= MAB + 1; |
DEST_ADDR16(15 downto 8) := DATAREAD(FRAB); |
FRAB <= FRAB + 1; |
CPU_STATE := CPU_XRRD3; |
when CPU_XRRD3 => |
DEST_ADDR16(7 downto 0) := DATAREAD(MAB); |
MAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0); |
DATAWRITE(MAB,TEMP_DATA); |
DEST_ADDR16(7 downto 0) := DATAREAD(FRAB); |
FRAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0); |
DATAWRITE(FRAB,TEMP_DATA); |
CPU_STATE := CPU_STORE; |
when CPU_XRRS => |
DEST_ADDR16(15 downto 8) := DATAREAD(MAB); |
MAB <= MAB + 1; |
when CPU_XRRS => -- RR PAIR PLUS OFFSET AS SOURCE ADDRESS ********************************************************************* |
DEST_ADDR16(15 downto 8) := DATAREAD(FRAB); |
FRAB <= FRAB + 1; |
CPU_STATE := CPU_XRRS2; |
when CPU_XRRS2 => |
DEST_ADDR16(7 downto 0) := DATAREAD(MAB); |
MAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0); |
DEST_ADDR16(7 downto 0) := DATAREAD(FRAB); |
FRAB <= ADDER16(DEST_ADDR16,RESULT)(11 downto 0); |
CPU_STATE := CPU_XRRS3; |
when CPU_XRRS3 => |
TEMP_DATA := DATAREAD(MAB); |
MAB <= DEST_ADDR; |
DATAWRITE(MAB,TEMP_DATA); |
TEMP_DATA := DATAREAD(FRAB); |
FRAB <= DEST_ADDR; |
DATAWRITE(FRAB,TEMP_DATA); |
CPU_STATE := CPU_STORE; |
when CPU_INDRR => -- INDIRECT DESTINATION ADDRESS FOR WORD INSTRUCTIONS (DECW AND INCW) **************************************** |
MAB <= (RP(3 downto 0) & DATAREAD(MAB))+1; -- the destination address is given by indirect address |
FRAB <= (RP(3 downto 0) & DATAREAD(FRAB))+1; -- the destination address is given by indirect address |
CPU_STATE := CPU_OMA2; |
when CPU_ISMD1 => -- INDIRECT SOURCE ADDRESS *********************************************************************************** |
MAB <= RP(3 downto 0) & DATAREAD(MAB); -- source address is read from indirect register |
FRAB <= RP(3 downto 0) & DATAREAD(FRAB); -- source address is read from indirect register |
CPU_STATE := CPU_TMA; |
when CPU_IND2 => -- READS REGISTER AND PERFORM OPERATION ON AN INDIRECT DESTINATION ******************************************* |
TEMP_DATA := DATAREAD(MAB); -- reads data from the source (MAB) address and store it into TEMP_DATA |
MAB <= DEST_ADDR; -- place the address of the indirect register on MAB |
TEMP_DATA := DATAREAD(FRAB); -- reads data from the source (FRAB) address and store it into TEMP_DATA |
FRAB <= DEST_ADDR; -- place the address of the indirect register on FRAB |
CPU_STATE := CPU_IND1; -- proceed to the indirect |
when CPU_IND1 => -- INDIRECT DESTINATION ADDRESS ****************************************************************************** |
MAB <= RP(3 downto 0) & DATAREAD(MAB); -- the destination address is given by indirect address |
FRAB <= RP(3 downto 0) & DATAREAD(FRAB); -- the destination address is given by indirect address |
if (LU_INSTRUCTION='0') then CPU_STATE := CPU_OMA; -- proceed with one memory access |
else CPU_STATE := CPU_OMA2; -- proceed with one memory access (logic unit related) |
end if; |
when CPU_TMA => -- TWO MEMORY ACCESS, READS SOURCE OPERAND FROM MEMORY ******************************************************* |
TEMP_DATA := DATAREAD(MAB); -- reads data from the source (MAB) address and store it into TEMP_DATA |
MAB <= DEST_ADDR; -- place the destination address (DEST_ADDR) on the memory address bus (MAB) |
TEMP_DATA := DATAREAD(FRAB); -- reads data from the source (FRAB) address and store it into TEMP_DATA |
FRAB <= DEST_ADDR; -- place destination address (DEST_ADDR) on memory address bus (FRAB) |
CPU_STATE := CPU_OMA; -- proceed to the last stage |
when CPU_OMA => -- ONE MEMORY ACCESS stage *********************************************************************************** |
-- this stage performs the TEMP_OP operation between TEMP_DATA and data read from current (MAB) address (destination) |
RESULT := ALU(TEMP_OP,DATAREAD(MAB),TEMP_DATA,CPU_FLAGS.C); |
-- this stage performs TEMP_OP operation between TEMP_DATA and data read from current (FRAB) address (destination) |
RESULT := ALU(TEMP_OP,DATAREAD(FRAB),TEMP_DATA,CPU_FLAGS.C); |
if (TEMP_OP<ALU_OR) then |
CPU_FLAGS.C := ALU_FLAGS.C; |
CPU_FLAGS.V := ALU_FLAGS.V; |
1867,7 → 1887,7
CPU_FLAGS.V := '0'; |
end if; |
if (ALU_NOUPDATE='0') then |
DATAWRITE(MAB,RESULT); |
DATAWRITE(FRAB,RESULT); |
WR <= '1'; |
end if; |
CPU_STATE := CPU_DECOD; |
1875,8 → 1895,8
CPU_STATE := CPU_LDW; |
end if; |
when CPU_OMA2 => -- ONE MEMORY ACCESS stage logic unit related **************************************************************** |
-- this stage performs the TEMP_OP LU2 operation on data read from current (MAB) address |
RESULT := LU2(TEMP_OP,DATAREAD(MAB),CPU_FLAGS.D,CPU_FLAGS.H,CPU_FLAGS.C); |
-- this stage performs TEMP_OP LU2 operation on data read from current (FRAB) address |
RESULT := LU2(TEMP_OP,DATAREAD(FRAB),CPU_FLAGS.D,CPU_FLAGS.H,CPU_FLAGS.C); |
if (TEMP_OP=LU2_DEC or TEMP_OP=LU2_INC) then |
CPU_FLAGS.V := ALU_FLAGS.V; |
CPU_FLAGS.Z := ALU_FLAGS.Z; |
1902,7 → 1922,7
CPU_FLAGS.Z := ALU_FLAGS.Z; |
CPU_FLAGS.S := ALU_FLAGS.S; |
end if; |
DATAWRITE(MAB,RESULT); |
DATAWRITE(FRAB,RESULT); |
WR <= '1'; |
if (WORD_DATA='1') then |
WORD_DATA := '0'; |
1911,52 → 1931,54
CPU_STATE := CPU_DMAB; |
else CPU_STATE := CPU_DECOD; |
end if; |
when CPU_DMAB => -- DECREMENT MEMORY ADDRESS BUS ***************************************************************************** |
MAB <= MAB - 1; |
when CPU_DMAB => -- DECREMENT MEMORY ADDRESS BUS ****************************************************************************** |
FRAB <= FRAB - 1; |
CPU_STATE := CPU_OMA2; |
when CPU_LDW => |
if (WORD_DATA='0') then |
TEMP_DATA := DATAREAD(MAB); |
MAB <= MAB + 1; |
else |
DATAWRITE(MAB,TEMP_DATA); |
WR <= '1'; |
end if; |
when CPU_LDW => -- LOAD WORD INSTRUCTION ************************************************************************************* |
-- read higher byte from source operand |
TEMP_DATA := DATAREAD(FRAB); |
FRAB <= FRAB + 1; |
CPU_STATE := CPU_LDW2; |
when CPU_LDW2 => |
if (WORD_DATA='0') then |
RESULT := DATAREAD(MAB); |
MAB <= DEST_ADDR; |
WORD_DATA := '1'; |
CPU_STATE := CPU_LDW; |
else |
MAB <= MAB + 1; |
DATAWRITE(MAB,RESULT); |
CPU_STATE := CPU_STORE; |
end if; |
-- read lower byte from source operand |
RESULT := DATAREAD(FRAB); |
FRAB <= DEST_ADDR; |
CPU_STATE := CPU_LDW3; |
when CPU_LDW3 => |
-- write higher byte to destination operand |
DATAWRITE(FRAB,TEMP_DATA); |
WR <= '1'; |
CPU_STATE := CPU_LDW4; |
when CPU_LDW4 => |
-- points FRAB to lower byte of destination address |
FRAB <= FRAB + 1; |
CPU_STATE := CPU_LDW5; |
when CPU_LDW5 => |
DATAWRITE(FRAB,RESULT); |
CPU_STATE := CPU_STORE; |
when CPU_LDPTOIM => -- LOAD PROGRAM TO INDIRECT MEMORY ************************************************************************** |
TEMP_DATA := DATAREAD(MAB); |
TEMP_DATA := DATAREAD(FRAB); |
DEST_ADDR := RP(3 downto 0) & TEMP_DATA; -- the destination address is read from the indirect address |
if (WORD_DATA='1') then |
-- it is a LDCI instruction, so we have to increment the indirect address after the operation |
DATAWRITE(MAB,TEMP_DATA+1); |
DATAWRITE(FRAB,TEMP_DATA+1); |
WR <= '1'; |
CPU_STATE := CPU_LDPTOIM2; |
else |
-- it is a LDC instruction, proceed the load instruction |
MAB <= ADDRESSER4(RESULT(3 downto 0)); -- the source address (program memory) is read from source register pair |
FRAB <= ADDRESSER4(RESULT(3 downto 0)); -- the source address (program memory) is read from source register pair |
CPU_STATE := CPU_LDPTOM; |
end if; |
when CPU_LDPTOIM2 => |
MAB <= ADDRESSER4(RESULT(3 downto 0)); -- the source address (program memory) is read from source register pair |
FRAB <= ADDRESSER4(RESULT(3 downto 0)); -- the source address (program memory) is read from source register pair |
CPU_STATE := CPU_LDPTOM; |
when CPU_LDPTOM => -- LOAD PROGRAM TO MEMORY *********************************************************************************** |
IAB(15 downto 8) <= DATAREAD(MAB); -- read the high address from the first register |
MAB <= MAB + 1; |
IAB(15 downto 8) <= DATAREAD(FRAB); -- read the high address from the first register |
FRAB <= FRAB + 1; |
CPU_STATE := CPU_LDPTOM2; |
when CPU_LDPTOM2 => |
IAB(7 downto 0) <= DATAREAD(MAB); -- read the low address from the second register |
MAB <= DEST_ADDR; |
IAB(7 downto 0) <= DATAREAD(FRAB); -- read the low address from the second register |
FRAB <= DEST_ADDR; |
if (LU_INSTRUCTION='0') then |
CPU_STATE := CPU_LDPTOM3; -- if it is a read from program memory |
else |
1963,7 → 1985,7
CPU_STATE := CPU_LDMTOP; -- if it is a write onto program memory |
end if; |
when CPU_LDPTOM3 => -- READ PROGRAM MEMORY AND STORE INTO RAM ******************************************************************* |
DATAWRITE(MAB,IDB); |
DATAWRITE(FRAB,IDB); |
WR <= '1'; |
CAN_FETCH := '1'; -- re-enable fetching |
FETCH_ADDR := PC; |
1974,11 → 1996,11
end if; |
when CPU_LDPTOM4 => |
DEST_ADDR := ADDRESSER4(RESULT(3 downto 0)); |
MAB <= DEST_ADDR+1; |
FRAB <= DEST_ADDR+1; |
TEMP_OP := LU2_INC; |
CPU_STATE := CPU_OMA2; |
when CPU_LDMTOP => -- READ RAM AND STORE ONTO PROGRAM MEMORY ******************************************************************* |
PWDB <= DATAREAD(MAB); -- PWDB receive the content of RAM |
IWDB <= DATAREAD(FRAB); -- IWDB receive the content of RAM |
PGM_WR <= '1'; -- enable program memory write signal |
CPU_STATE := CPU_LDMTOP2; |
when CPU_LDMTOP2 => |
1989,96 → 2011,95
if (WORD_DATA='1') then |
CPU_STATE := CPU_LDPTOM4; |
end if; |
when CPU_BIT => |
TEMP_DATA := DATAREAD(MAB); |
when CPU_BIT => -- BIT INSTRUCTION ******************************************************************************************* |
TEMP_DATA := DATAREAD(FRAB); |
TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0)))):=TEMP_OP(3); |
DATAWRITE(MAB,TEMP_DATA); |
DATAWRITE(FRAB,TEMP_DATA); |
WR <= '1'; |
CPU_STATE := CPU_DECOD; |
when CPU_IBTJ => |
MAB <= RP(3 downto 0) & DATAREAD(MAB); |
when CPU_IBTJ => -- INDIRECT BIT TEST JUMP INSTRUCTION ************************************************************************ |
FRAB <= RP(3 downto 0) & DATAREAD(FRAB); |
CPU_STATE := CPU_BTJ; |
when CPU_BTJ => |
TEMP_DATA := DATAREAD(MAB); |
when CPU_BTJ => -- BIT TEST JUMP INSTRUCTION ********************************************************************************* |
TEMP_DATA := DATAREAD(FRAB); |
if (TEMP_DATA(to_integer(unsigned(TEMP_OP(2 downto 0))))=TEMP_OP(3)) then |
PC := ADDER16(PC,RESULT); |
IQUEUE.FETCH_STATE := F_ADDR; |
end if; |
CPU_STATE := CPU_DECOD; |
when CPU_DJNZ => |
RESULT := LU2(LU2_DEC,DATAREAD(MAB),'0','0','0'); |
when CPU_DJNZ => -- DECREMENT AND JUMP IF NOT ZERO INSTRUCTION **************************************************************** |
RESULT := LU2(LU2_DEC,DATAREAD(FRAB),'0','0','0'); |
if (ALU_FLAGS.Z='0') then -- result is not zero, then jump relative |
PC := DEST_ADDR16; |
IQUEUE.FETCH_STATE := F_ADDR; |
end if; |
DATAWRITE(MAB,RESULT); |
DATAWRITE(FRAB,RESULT); |
WR <= '1'; |
CPU_STATE := CPU_DECOD; |
when CPU_INDJUMP => |
PC(15 downto 8) := DATAREAD(MAB); |
MAB <= MAB + 1; |
when CPU_INDJUMP => -- INDIRECT JUMP INSTRUCTION ********************************************************************************* |
PC(15 downto 8) := DATAREAD(FRAB); |
FRAB <= FRAB + 1; |
CPU_STATE:= CPU_INDJUMP2; |
when CPU_INDJUMP2 => |
PC(7 downto 0) := DATAREAD(MAB); |
PC(7 downto 0) := DATAREAD(FRAB); |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_DECOD; |
when CPU_TRAP => |
PC(15 downto 8) := DATAREAD(MAB); |
MAB <= MAB + 1; |
when CPU_TRAP => -- TRAP INSTRUCTION ****************************************************************************************** |
PC(15 downto 8) := DATAREAD(FRAB); |
FRAB <= FRAB + 1; |
CPU_STATE:= CPU_TRAP2; |
when CPU_TRAP2 => |
PC(7 downto 0) := DATAREAD(MAB); |
PC(7 downto 0) := DATAREAD(FRAB); |
SP := SP - 1; |
MAB <= SP; |
FRAB <= SP; |
IQUEUE.FETCH_STATE := F_ADDR; |
LU_INSTRUCTION := '1'; |
CPU_STATE := CPU_STACK; |
when CPU_INDSTACK => |
PC(15 downto 8) := DATAREAD(MAB); |
MAB <= MAB + 1; |
when CPU_INDSTACK => -- INDIRECT CALL INSTRUCTION ***************************************************************************** |
PC(15 downto 8) := DATAREAD(FRAB); |
FRAB <= FRAB + 1; |
CPU_STATE:= CPU_INDSTACK2; |
when CPU_INDSTACK2 => |
PC(7 downto 0) := DATAREAD(MAB); |
PC(7 downto 0) := DATAREAD(FRAB); |
SP := SP - 1; |
MAB <= SP; |
FRAB <= SP; |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_STACK; |
when CPU_VECTOR => |
PC(15 downto 8) := IDB; |
when CPU_VECTOR => -- LOAD PC WITH ADDRESS STORED IN PROGRAM MEMORY ********************************************************* |
PC(15 downto 8) := IDB; -- read high byte of destination address |
IAB <= IAB + 1; |
CPU_STATE := CPU_VECTOR2; |
when CPU_VECTOR2 => |
PC(7 downto 0) := IDB; |
IQUEUE.FETCH_STATE := F_ADDR; |
CAN_FETCH := '1'; |
if (LU_INSTRUCTION='1') then CPU_STATE := CPU_STACK; |
PC(7 downto 0) := IDB; -- read low byte of destination address |
IQUEUE.FETCH_STATE := F_ADDR; -- reset queue FSM |
CAN_FETCH := '1'; -- restart fetching |
if (INT_FLAG='1') then CPU_STATE := CPU_STACK; |
else CPU_STATE := CPU_DECOD; |
end if; |
when CPU_STACK => -- PUSH PC 7:0 INTO THE STACK ******************************************************************************* |
DATAWRITE(MAB,DEST_ADDR16(7 downto 0)); |
when CPU_STACK => -- PUSH PC 7:0 INTO THE STACK ******************************************************************************** |
DATAWRITE(FRAB,DEST_ADDR16(7 downto 0)); |
WR <= '1'; |
CPU_STATE := CPU_STACK1; |
when CPU_STACK1 => |
SP := SP - 1; |
MAB <= SP; |
FRAB <= SP; |
CPU_STATE := CPU_STACK2; |
when CPU_STACK2 => |
DATAWRITE(MAB,DEST_ADDR16(15 downto 8)); |
when CPU_STACK2 => -- PUSH PC 15:8 INTO THE STACK ******************************************************************************* |
DATAWRITE(FRAB,DEST_ADDR16(15 downto 8)); |
WR <= '1'; |
if (LU_INSTRUCTION='1') then |
if (INT_FLAG='1') then |
CPU_STATE := CPU_STACK3; |
else |
CPU_STATE := CPU_DECOD; |
end if; |
when CPU_STACK3 => -- PUSH FLAGS INTO THE STACK ******************************************************************************* |
when CPU_STACK3 => -- PUSH FLAGS INTO THE STACK ********************************************************************************* |
SP := SP - 1; |
MAB <= SP; |
DATAWRITE(MAB,CPU_FLAGS.C&CPU_FLAGS.Z&CPU_FLAGS.S&CPU_FLAGS.V&CPU_FLAGS.D&CPU_FLAGS.H&CPU_FLAGS.F2&CPU_FLAGS.F1); |
WR <= '1'; |
FRAB <= SP; |
DATAWRITE(FRAB,CPU_FLAGS.C&CPU_FLAGS.Z&CPU_FLAGS.S&CPU_FLAGS.V&CPU_FLAGS.D&CPU_FLAGS.H&CPU_FLAGS.F2&CPU_FLAGS.F1); |
IRQE := '0'; |
CPU_STATE := CPU_DECOD; |
when CPU_UNSTACK3 => |
TEMP_DATA := DATAREAD(MAB); |
CPU_STATE := CPU_STORE; |
when CPU_UNSTACK3 => -- POP FLAGS FROM STACK ********************************************************************************** |
TEMP_DATA := DATAREAD(FRAB); |
CPU_FLAGS.C := TEMP_DATA(7); |
CPU_FLAGS.Z := TEMP_DATA(6); |
CPU_FLAGS.S := TEMP_DATA(5); |
2088,28 → 2109,27
CPU_FLAGS.F2 := TEMP_DATA(1); |
CPU_FLAGS.F1 := TEMP_DATA(0); |
SP := SP + 1; |
MAB <= SP; |
CPU_STATE := CPU_UNSTACK; |
when CPU_UNSTACK => |
DEST_ADDR16(15 downto 8) := DATAREAD(MAB); |
FRAB <= SP; |
CPU_STATE := CPU_UNSTACK2; |
when CPU_UNSTACK2 => -- POP PC(15:8) FROM STACK ******************************************************************************* |
DEST_ADDR16(15 downto 8) := DATAREAD(FRAB); |
SP := SP + 1; |
MAB <= SP; |
CPU_STATE := CPU_UNSTACK2; |
when CPU_UNSTACK2 => |
DEST_ADDR16(7 downto 0) := DATAREAD(MAB); |
FRAB <= SP; |
CPU_STATE := CPU_UNSTACK; |
when CPU_UNSTACK => -- POP PC(7:0) FROM STACK ******************************************************************************** |
DEST_ADDR16(7 downto 0) := DATAREAD(FRAB); |
SP := SP + 1; |
PC := DEST_ADDR16; |
IQUEUE.FETCH_STATE := F_ADDR; |
CPU_STATE := CPU_DECOD; |
when CPU_STORE => |
WR <= '1'; |
CPU_STATE := CPU_DECOD; |
when CPU_HALTED => -- HALT mode, wait for an interrupt or reset |
when CPU_STORE => -- stores data into memory |
WR <= '1'; -- enable write signal (it is automatically disabled on CPU_DECOD state) |
CPU_STATE := CPU_DECOD; -- proceed to main decoding state |
when CPU_ILLEGAL => -- An illegal opcode was fetched |
when CPU_RESET => |
when CPU_RESET => -- SOFTWARE RESET (TRIGGERED BY OCD RESET BIT) *********************************************************** |
IAB <= x"0002"; |
MAB <= x"000"; |
PWDB <= x"00"; |
FRAB <= x"000"; |
IWDB <= x"00"; |
SP := x"000"; |
RP := x"00"; |
WR <= '0'; |
2131,9 → 2151,8
CPU_STATE := CPU_VECTOR; |
when others => |
CPU_STATE := CPU_DECOD; |
end case; |
-- end of the main decoder |
end if; -- CKDIVIDER |
end case; |
-- end of the main decoder |
end if; |
end process; |
end CPU; |
/fpz8_timer.bsf
0,0 → 1,120
/* |
WARNING: Do NOT edit the input and output ports in this file in a text |
editor if you plan to continue editing the block that represents it in |
the Block Editor! File corruption is VERY likely to occur. |
*/ |
/* |
Copyright (C) 1991-2010 Altera Corporation |
Your use of Altera Corporation's design tools, logic functions |
and other software and tools, and its AMPP partner logic |
functions, and any output files from any of the foregoing |
(including device programming or simulation files), and any |
associated documentation or information are expressly subject |
to the terms and conditions of the Altera Program License |
Subscription Agreement, Altera MegaCore Function License |
Agreement, or other applicable license agreement, including, |
without limitation, that your use is for the sole purpose of |
programming logic devices manufactured by Altera and sold by |
Altera or its authorized distributors. Please refer to the |
applicable agreement for further details. |
*/ |
(header "symbol" (version "1.1")) |
(symbol |
(rect 64 64 240 320) |
(text "fpz8_timer" (rect 5 0 56 12)(font "Arial" )) |
(text "inst" (rect 8 240 25 252)(font "Arial" )) |
(port |
(pt 0 48) |
(input) |
(text "RAB[11..0]" (rect 0 0 54 12)(font "Arial" )) |
(text "RAB[11..0]" (rect 21 40 75 52)(font "Arial" )) |
(line (pt 0 48)(pt 16 48)(line_width 3)) |
) |
(port |
(pt 0 64) |
(input) |
(text "RIDB[7..0]" (rect 0 0 53 12)(font "Arial" )) |
(text "RIDB[7..0]" (rect 21 56 74 68)(font "Arial" )) |
(line (pt 0 64)(pt 16 64)(line_width 3)) |
) |
(port |
(pt 176 80) |
(input) |
(text "SIDB[7..0]" (rect 0 0 51 12)(font "Arial" )) |
(text "SIDB[7..0]" (rect 101 72 152 84)(font "Arial" )) |
(line (pt 160 80)(pt 176 80)(line_width 3)) |
) |
(port |
(pt 0 96) |
(input) |
(text "REG_SEL" (rect 0 0 49 12)(font "Arial" )) |
(text "REG_SEL" (rect 21 88 70 100)(font "Arial" )) |
(line (pt 0 96)(pt 16 96)(line_width 1)) |
) |
(port |
(pt 0 32) |
(input) |
(text "WR" (rect 0 0 18 12)(font "Arial" )) |
(text "WR" (rect 21 24 39 36)(font "Arial" )) |
(line (pt 0 32)(pt 16 32)(line_width 1)) |
) |
(port |
(pt 0 112) |
(input) |
(text "CLK_IN" (rect 0 0 38 12)(font "Arial" )) |
(text "CLK_IN" (rect 21 104 59 116)(font "Arial" )) |
(line (pt 0 112)(pt 16 112)(line_width 1)) |
) |
(port |
(pt 0 144) |
(input) |
(text "STOP" (rect 0 0 28 12)(font "Arial" )) |
(text "STOP" (rect 21 136 49 148)(font "Arial" )) |
(line (pt 0 144)(pt 16 144)(line_width 1)) |
) |
(port |
(pt 176 216) |
(input) |
(text "TMR_IN" (rect 0 0 40 12)(font "Arial" )) |
(text "TMR_IN" (rect 112 208 152 220)(font "Arial" )) |
(line (pt 160 216)(pt 176 216)(line_width 1)) |
) |
(port |
(pt 176 32) |
(input) |
(text "TMR_ID[1..0]" (rect 0 0 66 12)(font "Arial" )) |
(text "TMR_ID[1..0]" (rect 86 24 152 36)(font "Arial" )) |
(line (pt 160 32)(pt 176 32)(line_width 3)) |
) |
(port |
(pt 0 128) |
(input) |
(text "RESET" (rect 0 0 35 12)(font "Arial" )) |
(text "RESET" (rect 21 120 56 132)(font "Arial" )) |
(line (pt 0 128)(pt 16 128)(line_width 1)) |
) |
(port |
(pt 0 80) |
(output) |
(text "RODB[7..0]" (rect 0 0 57 12)(font "Arial" )) |
(text "RODB[7..0]" (rect 24 72 81 84)(font "Arial" )) |
(line (pt 16 80)(pt 0 80)(line_width 3)) |
) |
(port |
(pt 0 216) |
(output) |
(text "INT" (rect 0 0 17 12)(font "Arial" )) |
(text "INT" (rect 24 208 41 220)(font "Arial" )) |
(line (pt 16 216)(pt 0 216)(line_width 1)) |
) |
(port |
(pt 176 200) |
(output) |
(text "TMR_OUT" (rect 0 0 50 12)(font "Arial" )) |
(text "TMR_OUT" (rect 105 195 155 207)(font "Arial" )) |
(line (pt 176 200)(pt 160 200)(line_width 1)) |
) |
(drawing |
(rectangle (rect 16 16 160 232)(line_width 1)) |
) |
) |
/fpz8_timer.vhd
0,0 → 1,111
-- FPz8 simple timer |
-- By Fabio Pereira |
|
library ieee ; |
use ieee.std_logic_1164.all ; |
use ieee.numeric_std.all; |
use ieee.std_logic_unsigned.all ; |
|
entity fpz8_timer IS |
port |
( |
RAB : in std_logic_vector(11 downto 0); |
RIDB : in std_logic_vector(7 downto 0); |
RODB : out std_logic_vector(7 downto 0); |
SIDB : in std_logic_vector(7 downto 0); |
REG_SEL : in std_logic; |
WR : in std_logic; |
CLK_IN : in std_logic; |
STOP : in std_logic; |
INT : out std_logic; |
TMR_OUT : out std_logic; |
TMR_IN : in std_logic; |
TMR_ID : in std_logic_vector(1 downto 0); |
RESET : in std_logic |
); |
end fpz8_timer; |
|
architecture timer of fpz8_timer is |
shared variable TMR_EN : std_logic; |
shared variable TMR_CMP : std_logic_vector(15 downto 0); |
shared variable TMR_TEMP : std_logic_vector(7 downto 0); |
shared variable TMR_PRESEL : std_logic_vector(2 downto 0); |
shared variable TMR_CNT : std_logic_vector(15 downto 0); |
shared variable TMR_PRE : std_logic_vector(7 downto 0); |
shared variable INT_OUT : std_logic; |
shared variable BASE_ADDR : std_logic_vector(11 downto 0); |
begin |
control: process(CLK_IN,REG_SEL,RESET) |
begin |
INT <= INT_OUT; |
case TMR_ID is |
when "00" => BASE_ADDR := x"F00"; |
when "01" => BASE_ADDR := x"F08"; |
when "10" => BASE_ADDR := x"F10"; |
when "11" => BASE_ADDR := x"F18"; |
end case; |
if (RESET='1') then |
TMR_EN := '0'; |
TMR_CMP := x"0000"; |
TMR_TEMP := x"00"; |
elsif (rising_edge(CLK_IN) and REG_SEL='1') then |
if (WR='0') then -- it is a reading operation |
if (RAB=(BASE_ADDR+7)) then ------ register TMR_CTL |
RODB<=TMR_EN&'0'&TMR_PRESEL&"000"; |
elsif (RAB=BASE_ADDR+2) then -- register TMR_CMPH |
RODB<=TMR_CMP(15 downto 8); |
elsif (RAB=BASE_ADDR+3) then -- register TMR_CMPL |
RODB<=TMR_CMP(7 downto 0); |
else RODB<=SIDB; |
end if; |
else -- it is a writing operation |
if (RAB=BASE_ADDR+7) then ----- register TMR_CTL |
TMR_EN:=RIDB(7); |
TMR_PRESEL:=RIDB(5 downto 3); |
elsif (RAB=BASE_ADDR+2) then -- register TMR_RLH |
TMR_TEMP := RIDB; |
elsif (RAB=BASE_ADDR+3) then -- register TMR_RLL |
TMR_CMP(7 downto 0) := RIDB; |
TMR_CMP(15 downto 8) := TMR_TEMP; |
end if; |
end if; |
end if; |
end process control; -- control process |
counter: process(CLK_IN,RESET,STOP) |
variable TMR_PRECP : std_logic_vector(7 downto 0); |
begin |
if (RESET='1') then |
TMR_CNT := x"0000"; |
TMR_PRE := x"00"; |
TMR_PRECP := x"00"; |
INT_OUT := '0'; |
elsif (rising_edge(CLK_IN)) then |
if (STOP='0') then |
if (TMR_EN='1') then |
case TMR_PRESEL is |
when "000" => TMR_PRECP:=x"01"; -- prescaler divide by 1 |
when "001" => TMR_PRECP:=x"02"; -- prescaler divide by 2 |
when "010" => TMR_PRECP:=x"04"; -- prescaler divide by 4 |
when "011" => TMR_PRECP:=x"08"; -- prescaler divide by 8 |
when "100" => TMR_PRECP:=x"10"; -- prescaler divide by 16 |
when "101" => TMR_PRECP:=x"20"; -- prescaler divide by 32 |
when "110" => TMR_PRECP:=x"40"; -- prescaler divide by 64 |
when others => TMR_PRECP:=x"80"; -- prescaler divide by 128 |
end case; |
TMR_PRE := TMR_PRE + 1; |
if (TMR_PRE=TMR_PRECP) then |
TMR_PRE:=x"00"; |
TMR_CNT:=TMR_CNT+1; |
if (TMR_CNT=TMR_CMP) then |
TMR_CNT:=x"0000"; |
INT_OUT := not INT_OUT; |
end if; |
end if; |
else |
TMR_CNT:=x"0000"; |
TMR_PRE:=x"00"; |
end if; -- if TMR_EN=1 |
end if; -- if STOP=0 |
end if; -- rising edge of CLK_IN |
end process; -- counter process |
end timer; |