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

Subversion Repositories neo430

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neo430/trunk
    from Rev 192 to Rev 193
    Reverse comparison

Rev 192 → Rev 193

/neo430/README.md
73,7 → 73,7
- Internal [DMEM](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_dmem.vhd) (RAM, for data) and [IMEM](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_imem.vhd) (RAM or ROM, for code), configurable sizes
- Customizable processor hardware configuration:
- Optional multiplier/divider unit ([MULDIV](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_muldiv.vhd))
- Optional high-precision timer ([TIMER](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_timer.vhd))
- Optional high-precision timer ([TIMER](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_timer.vhd)) with arbitrary frequency generator output
- Optional universal asynchronous receiver and transmitter ([UART](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_uart.vhd))
- Optional serial peripheral interface ([SPI](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_spi.vhd)), 8 or 16 bit tansfer data size, 6 dedicated CS lines
- Optional I2C-compatible two wire serial interface ([TWI](https://github.com/stnolting/neo430/blob/master/rtl/core/neo430_twi.vhd)) supporting clock stretching
/neo430/doc/NEO430.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/neo430/doc/figures/neo430_arch.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/neo430/doc/neo430_control_fsm.ods Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/neo430/rtl/core/neo430_application_image.vhd
191,7 → 191,7
000180 => x"4030",
000181 => x"014e",
000182 => x"4c82",
000183 => x"ffae",
000183 => x"ffac",
000184 => x"4130",
000185 => x"421e",
000186 => x"fffe",
/neo430/rtl/core/neo430_bootloader_image.vhd
22,7 → 22,7
000011 => x"c004",
000012 => x"435c",
000013 => x"12b0",
000014 => x"f6a8",
000014 => x"f6ac",
000015 => x"413b",
000016 => x"413c",
000017 => x"413d",
30,22 → 30,22
000019 => x"413f",
000020 => x"1300",
000021 => x"403c",
000022 => x"f6f4",
000022 => x"f6f8",
000023 => x"12b0",
000024 => x"f5d4",
000024 => x"f5d8",
000025 => x"4130",
000026 => x"4c4a",
000027 => x"403c",
000028 => x"f72d",
000028 => x"f72e",
000029 => x"12b0",
000030 => x"f5d4",
000030 => x"f5d8",
000031 => x"4a4c",
000032 => x"12b0",
000033 => x"f626",
000033 => x"f62a",
000034 => x"4302",
000035 => x"435c",
000036 => x"12b0",
000037 => x"f6a2",
000037 => x"f6a6",
000038 => x"4030",
000039 => x"f04c",
000040 => x"120a",
52,7 → 52,7
000041 => x"d392",
000042 => x"ffa4",
000043 => x"403a",
000044 => x"f68c",
000044 => x"f690",
000045 => x"407c",
000046 => x"0005",
000047 => x"128a",
60,7 → 60,7
000049 => x"128a",
000050 => x"4c0a",
000051 => x"12b0",
000052 => x"f684",
000052 => x"f688",
000053 => x"4a4c",
000054 => x"413a",
000055 => x"4130",
68,7 → 68,7
000057 => x"d392",
000058 => x"ffa4",
000059 => x"403a",
000060 => x"f68c",
000060 => x"f690",
000061 => x"407c",
000062 => x"009e",
000063 => x"128a",
76,7 → 76,7
000065 => x"128a",
000066 => x"4c0a",
000067 => x"12b0",
000068 => x"f684",
000068 => x"f688",
000069 => x"4a4c",
000070 => x"413a",
000071 => x"4130",
83,9 → 83,9
000072 => x"d392",
000073 => x"ffa4",
000074 => x"12b0",
000075 => x"f68c",
000075 => x"f690",
000076 => x"12b0",
000077 => x"f684",
000077 => x"f688",
000078 => x"4130",
000079 => x"407c",
000080 => x"00b9",
92,9 → 92,9
000081 => x"12b0",
000082 => x"f090",
000083 => x"403c",
000084 => x"f734",
000084 => x"f735",
000085 => x"12b0",
000086 => x"f5d4",
000086 => x"f5d8",
000087 => x"403d",
000088 => x"ffa0",
000089 => x"4d2c",
119,7 → 119,7
000108 => x"4d81",
000109 => x"0000",
000110 => x"12b0",
000111 => x"f6b4",
000111 => x"f6b8",
000112 => x"4c88",
000113 => x"0000",
000114 => x"4a0c",
127,12 → 127,12
000116 => x"407e",
000117 => x"0010",
000118 => x"12b0",
000119 => x"f6ee",
000119 => x"f6f2",
000120 => x"4c89",
000121 => x"0000",
000122 => x"5321",
000123 => x"4030",
000124 => x"f6d2",
000124 => x"f6d6",
000125 => x"120a",
000126 => x"8231",
000127 => x"436e",
149,7 → 149,7
000138 => x"d392",
000139 => x"ffa4",
000140 => x"403a",
000141 => x"f68c",
000141 => x"f690",
000142 => x"407c",
000143 => x"0003",
000144 => x"128a",
166,7 → 166,7
000155 => x"128a",
000156 => x"4c0a",
000157 => x"12b0",
000158 => x"f684",
000158 => x"f688",
000159 => x"4a4c",
000160 => x"5231",
000161 => x"413a",
180,7 → 180,7
000169 => x"934e",
000170 => x"200b",
000171 => x"4039",
000172 => x"f5c2",
000172 => x"f5c6",
000173 => x"1289",
000174 => x"4c4a",
000175 => x"1289",
187,9 → 187,9
000176 => x"4c4d",
000177 => x"4a4c",
000178 => x"12b0",
000179 => x"f6b8",
000179 => x"f6bc",
000180 => x"4030",
000181 => x"f6d0",
000181 => x"f6d4",
000182 => x"4039",
000183 => x"f0fa",
000184 => x"1289",
221,11 → 221,11
000210 => x"12b0",
000211 => x"f034",
000212 => x"403d",
000213 => x"f5d4",
000213 => x"f5d8",
000214 => x"9306",
000215 => x"200f",
000216 => x"403c",
000217 => x"f741",
000217 => x"f742",
000218 => x"128d",
000219 => x"4037",
000220 => x"f146",
240,7 → 240,7
000229 => x"4030",
000230 => x"f1a4",
000231 => x"403c",
000232 => x"f754",
000232 => x"f755",
000233 => x"4030",
000234 => x"f1b4",
000235 => x"464e",
314,13 → 314,13
000303 => x"4030",
000304 => x"f21e",
000305 => x"403c",
000306 => x"f75f",
000306 => x"f760",
000307 => x"12b0",
000308 => x"f5d4",
000308 => x"f5d8",
000309 => x"5031",
000310 => x"0006",
000311 => x"4030",
000312 => x"f6ca",
000312 => x"f6ce",
000313 => x"120a",
000314 => x"1209",
000315 => x"8231",
343,7 → 343,7
000332 => x"d392",
000333 => x"ffa4",
000334 => x"403a",
000335 => x"f68c",
000335 => x"f690",
000336 => x"436c",
000337 => x"128a",
000338 => x"411c",
358,7 → 358,7
000347 => x"490c",
000348 => x"128a",
000349 => x"12b0",
000350 => x"f684",
000350 => x"f688",
000351 => x"403a",
000352 => x"f050",
000353 => x"128a",
366,7 → 366,7
000355 => x"23fd",
000356 => x"5231",
000357 => x"4030",
000358 => x"f6d4",
000358 => x"f6d8",
000359 => x"120a",
000360 => x"1209",
000361 => x"1208",
376,7 → 376,7
000365 => x"4e07",
000366 => x"4e0c",
000367 => x"12b0",
000368 => x"f6b4",
000368 => x"f6b8",
000369 => x"4039",
000370 => x"f272",
000371 => x"4c4e",
390,7 → 390,7
000379 => x"630d",
000380 => x"1289",
000381 => x"4030",
000382 => x"f6d0",
000382 => x"f6d4",
000383 => x"120a",
000384 => x"8231",
000385 => x"436e",
411,7 → 411,7
000400 => x"d392",
000401 => x"ffa4",
000402 => x"403a",
000403 => x"f68c",
000403 => x"f690",
000404 => x"407c",
000405 => x"00d8",
000406 => x"128a",
425,7 → 425,7
000414 => x"0002",
000415 => x"128a",
000416 => x"12b0",
000417 => x"f684",
000417 => x"f688",
000418 => x"403a",
000419 => x"f050",
000420 => x"128a",
442,9 → 442,9
000431 => x"1205",
000432 => x"1204",
000433 => x"4038",
000434 => x"f5d4",
000434 => x"f5d8",
000435 => x"403c",
000436 => x"f762",
000436 => x"f763",
000437 => x"1288",
000438 => x"434c",
000439 => x"426d",
478,10 → 478,10
000467 => x"426d",
000468 => x"128a",
000469 => x"403c",
000470 => x"f75f",
000470 => x"f760",
000471 => x"1288",
000472 => x"4030",
000473 => x"f6ca",
000473 => x"f6ce",
000474 => x"492e",
000475 => x"ee04",
000476 => x"4906",
502,7 → 502,7
000491 => x"1206",
000492 => x"1205",
000493 => x"12b0",
000494 => x"f6c2",
000494 => x"f6c6",
000495 => x"4032",
000496 => x"c000",
000497 => x"4382",
515,321 → 515,321
000504 => x"ffe8",
000505 => x"4382",
000506 => x"ffee",
000507 => x"40b2",
000508 => x"f00a",
000509 => x"c000",
000510 => x"4382",
000511 => x"ffaa",
000512 => x"435c",
000513 => x"12b0",
000514 => x"f6a2",
000507 => x"4382",
000508 => x"ffa8",
000509 => x"435c",
000510 => x"12b0",
000511 => x"f6a6",
000512 => x"40b2",
000513 => x"f00a",
000514 => x"c000",
000515 => x"403c",
000516 => x"4b00",
000517 => x"434d",
000518 => x"12b0",
000519 => x"f52e",
000519 => x"f532",
000520 => x"12b0",
000521 => x"f5ce",
000521 => x"f5d2",
000522 => x"436c",
000523 => x"12b0",
000524 => x"f65c",
000524 => x"f660",
000525 => x"4382",
000526 => x"ffb0",
000527 => x"4038",
000528 => x"fffe",
000529 => x"482c",
000530 => x"5c0c",
000531 => x"5c0c",
000532 => x"533c",
000533 => x"4c82",
000534 => x"ffb4",
000535 => x"40b2",
000536 => x"00ff",
000537 => x"ffb0",
000538 => x"4382",
000539 => x"c004",
000540 => x"12b0",
000541 => x"f6ae",
000542 => x"403a",
000543 => x"f5d4",
000544 => x"403c",
000545 => x"f766",
000546 => x"128a",
000547 => x"4039",
000548 => x"f642",
000549 => x"421c",
000550 => x"fff0",
000551 => x"1289",
000552 => x"403c",
000553 => x"f794",
000554 => x"128a",
000555 => x"421c",
000556 => x"fff4",
000557 => x"1289",
000558 => x"403c",
000559 => x"f79d",
000560 => x"128a",
000561 => x"482c",
000562 => x"1289",
000563 => x"421c",
000564 => x"fffc",
000565 => x"1289",
000566 => x"403c",
000567 => x"f7a6",
000568 => x"128a",
000569 => x"421c",
000570 => x"fff6",
000571 => x"1289",
000572 => x"403c",
000573 => x"f7af",
000574 => x"128a",
000575 => x"421c",
000576 => x"fffa",
000577 => x"1289",
000578 => x"403c",
000579 => x"f7b8",
000580 => x"128a",
000581 => x"421c",
000582 => x"fff2",
000583 => x"1289",
000584 => x"407c",
000585 => x"00ab",
000586 => x"12b0",
000587 => x"f090",
000588 => x"403c",
000589 => x"f7c1",
000590 => x"128a",
000591 => x"403e",
000592 => x"c004",
000593 => x"403d",
000594 => x"ffa2",
000595 => x"4e2c",
000596 => x"903c",
000597 => x"0010",
000598 => x"2008",
000599 => x"435c",
000600 => x"12b0",
000601 => x"f182",
000602 => x"403c",
000603 => x"f7e9",
000604 => x"128a",
000605 => x"12b0",
000606 => x"f09e",
000607 => x"4d2c",
000608 => x"930c",
000609 => x"37f1",
000610 => x"4038",
000611 => x"f02a",
000612 => x"1288",
000613 => x"4037",
000614 => x"f5c2",
000615 => x"4036",
000616 => x"f5ae",
000617 => x"4035",
000618 => x"f354",
000619 => x"403c",
000620 => x"f7eb",
000621 => x"128a",
000622 => x"1287",
000623 => x"4c49",
000624 => x"1286",
000625 => x"403c",
000626 => x"f7e9",
000627 => x"128a",
000628 => x"9079",
000629 => x"0072",
000630 => x"2004",
000631 => x"4030",
000632 => x"f000",
000526 => x"ffb6",
000527 => x"4382",
000528 => x"ffb0",
000529 => x"4038",
000530 => x"fffe",
000531 => x"482c",
000532 => x"5c0c",
000533 => x"5c0c",
000534 => x"533c",
000535 => x"4c82",
000536 => x"ffb4",
000537 => x"40b2",
000538 => x"00ff",
000539 => x"ffb0",
000540 => x"4382",
000541 => x"c004",
000542 => x"12b0",
000543 => x"f6b2",
000544 => x"403a",
000545 => x"f5d8",
000546 => x"403c",
000547 => x"f767",
000548 => x"128a",
000549 => x"4039",
000550 => x"f646",
000551 => x"421c",
000552 => x"fff0",
000553 => x"1289",
000554 => x"403c",
000555 => x"f795",
000556 => x"128a",
000557 => x"421c",
000558 => x"fff4",
000559 => x"1289",
000560 => x"403c",
000561 => x"f79e",
000562 => x"128a",
000563 => x"482c",
000564 => x"1289",
000565 => x"421c",
000566 => x"fffc",
000567 => x"1289",
000568 => x"403c",
000569 => x"f7a7",
000570 => x"128a",
000571 => x"421c",
000572 => x"fff6",
000573 => x"1289",
000574 => x"403c",
000575 => x"f7b0",
000576 => x"128a",
000577 => x"421c",
000578 => x"fffa",
000579 => x"1289",
000580 => x"403c",
000581 => x"f7b9",
000582 => x"128a",
000583 => x"421c",
000584 => x"fff2",
000585 => x"1289",
000586 => x"407c",
000587 => x"00ab",
000588 => x"12b0",
000589 => x"f090",
000590 => x"403c",
000591 => x"f7c2",
000592 => x"128a",
000593 => x"403e",
000594 => x"c004",
000595 => x"403d",
000596 => x"ffa2",
000597 => x"4e2c",
000598 => x"903c",
000599 => x"0010",
000600 => x"2008",
000601 => x"435c",
000602 => x"12b0",
000603 => x"f182",
000604 => x"403c",
000605 => x"f7ea",
000606 => x"128a",
000607 => x"12b0",
000608 => x"f09e",
000609 => x"4d2c",
000610 => x"930c",
000611 => x"37f1",
000612 => x"4038",
000613 => x"f02a",
000614 => x"1288",
000615 => x"4037",
000616 => x"f5c6",
000617 => x"4036",
000618 => x"f5b2",
000619 => x"4035",
000620 => x"f354",
000621 => x"403c",
000622 => x"f7ec",
000623 => x"128a",
000624 => x"1287",
000625 => x"4c49",
000626 => x"1286",
000627 => x"403c",
000628 => x"f7ea",
000629 => x"128a",
000630 => x"9079",
000631 => x"0072",
000632 => x"2004",
000633 => x"4030",
000634 => x"f4d6",
000635 => x"9079",
000636 => x"0068",
000637 => x"2003",
000638 => x"1288",
000639 => x"4030",
000640 => x"f4d6",
000641 => x"9079",
000642 => x"0075",
000643 => x"2005",
000644 => x"434c",
000645 => x"12b0",
000646 => x"f182",
000647 => x"4030",
000648 => x"f4d6",
000649 => x"9079",
000650 => x"0070",
000651 => x"2003",
000652 => x"1285",
000653 => x"4030",
000654 => x"f4d6",
000655 => x"9079",
000656 => x"0065",
000657 => x"27cb",
000658 => x"403c",
000659 => x"f7f3",
000660 => x"128a",
000661 => x"4030",
000662 => x"f4d6",
000663 => x"120a",
000664 => x"1209",
000665 => x"421a",
000666 => x"fffc",
000667 => x"421b",
000668 => x"fffe",
000669 => x"4c0e",
000670 => x"5c0e",
000671 => x"4d0f",
000672 => x"6d0f",
000673 => x"434c",
000674 => x"4f09",
000675 => x"9f0b",
000676 => x"2804",
000677 => x"9b09",
000678 => x"201b",
000679 => x"9e0a",
000680 => x"2c19",
000681 => x"434a",
000682 => x"4079",
000683 => x"0003",
000684 => x"407d",
000685 => x"00ff",
000686 => x"9c0d",
000687 => x"2817",
000688 => x"4382",
000689 => x"ffa0",
000690 => x"4a0d",
000691 => x"5a0d",
000692 => x"5d0d",
000693 => x"5d0d",
000634 => x"f000",
000635 => x"4030",
000636 => x"f4da",
000637 => x"9079",
000638 => x"0068",
000639 => x"2003",
000640 => x"1288",
000641 => x"4030",
000642 => x"f4da",
000643 => x"9079",
000644 => x"0075",
000645 => x"2005",
000646 => x"434c",
000647 => x"12b0",
000648 => x"f182",
000649 => x"4030",
000650 => x"f4da",
000651 => x"9079",
000652 => x"0070",
000653 => x"2003",
000654 => x"1285",
000655 => x"4030",
000656 => x"f4da",
000657 => x"9079",
000658 => x"0065",
000659 => x"27cb",
000660 => x"403c",
000661 => x"f7f4",
000662 => x"128a",
000663 => x"4030",
000664 => x"f4da",
000665 => x"120a",
000666 => x"1209",
000667 => x"421a",
000668 => x"fffc",
000669 => x"421b",
000670 => x"fffe",
000671 => x"4c0e",
000672 => x"5c0e",
000673 => x"4d0f",
000674 => x"6d0f",
000675 => x"434c",
000676 => x"4f09",
000677 => x"9f0b",
000678 => x"2804",
000679 => x"9b09",
000680 => x"201b",
000681 => x"9e0a",
000682 => x"2c19",
000683 => x"434a",
000684 => x"4079",
000685 => x"0003",
000686 => x"407d",
000687 => x"00ff",
000688 => x"9c0d",
000689 => x"2817",
000690 => x"4382",
000691 => x"ffa0",
000692 => x"4a0d",
000693 => x"5a0d",
000694 => x"5d0d",
000695 => x"5d0d",
000696 => x"5d0d",
000697 => x"5d0d",
000698 => x"5d0d",
000699 => x"dc0d",
000700 => x"d03d",
000701 => x"1000",
000702 => x"4d82",
000703 => x"ffa0",
000704 => x"4030",
000705 => x"f6d4",
000706 => x"8e0a",
000707 => x"7f0b",
000708 => x"531c",
000709 => x"4030",
000710 => x"f546",
000711 => x"936a",
000712 => x"2402",
000713 => x"926a",
000714 => x"2008",
000715 => x"490d",
000716 => x"12b0",
000717 => x"f6e0",
000718 => x"535a",
000719 => x"f03a",
000720 => x"00ff",
000721 => x"4030",
000722 => x"f558",
000723 => x"c312",
000724 => x"100c",
000725 => x"4030",
000726 => x"f59c",
000727 => x"f03c",
000728 => x"00ff",
000729 => x"403e",
000730 => x"ffa0",
000731 => x"4e2d",
000732 => x"930d",
000733 => x"3bfd",
000734 => x"4c82",
000735 => x"ffa2",
000736 => x"4130",
000737 => x"403d",
000738 => x"ffa2",
000739 => x"4d2c",
000740 => x"930c",
000741 => x"37fd",
000742 => x"4130",
000743 => x"421c",
000744 => x"ffa2",
000745 => x"4130",
000746 => x"120a",
000747 => x"1209",
000748 => x"1208",
000749 => x"1207",
000750 => x"4c09",
000751 => x"4038",
000752 => x"f5ae",
000753 => x"4077",
000754 => x"000d",
000755 => x"496a",
000756 => x"930a",
000757 => x"2002",
000758 => x"4030",
000759 => x"f6d0",
000760 => x"903a",
000761 => x"000a",
000762 => x"2002",
000763 => x"474c",
000764 => x"1288",
000765 => x"4a4c",
000699 => x"5d0d",
000700 => x"5d0d",
000701 => x"dc0d",
000702 => x"d03d",
000703 => x"1000",
000704 => x"4d82",
000705 => x"ffa0",
000706 => x"4030",
000707 => x"f6d8",
000708 => x"8e0a",
000709 => x"7f0b",
000710 => x"531c",
000711 => x"4030",
000712 => x"f54a",
000713 => x"936a",
000714 => x"2402",
000715 => x"926a",
000716 => x"2008",
000717 => x"490d",
000718 => x"12b0",
000719 => x"f6e4",
000720 => x"535a",
000721 => x"f03a",
000722 => x"00ff",
000723 => x"4030",
000724 => x"f55c",
000725 => x"c312",
000726 => x"100c",
000727 => x"4030",
000728 => x"f5a0",
000729 => x"f03c",
000730 => x"00ff",
000731 => x"403e",
000732 => x"ffa0",
000733 => x"4e2d",
000734 => x"930d",
000735 => x"3bfd",
000736 => x"4c82",
000737 => x"ffa2",
000738 => x"4130",
000739 => x"403d",
000740 => x"ffa2",
000741 => x"4d2c",
000742 => x"930c",
000743 => x"37fd",
000744 => x"4130",
000745 => x"421c",
000746 => x"ffa2",
000747 => x"4130",
000748 => x"120a",
000749 => x"1209",
000750 => x"1208",
000751 => x"1207",
000752 => x"4c09",
000753 => x"4038",
000754 => x"f5b2",
000755 => x"4077",
000756 => x"000d",
000757 => x"496a",
000758 => x"930a",
000759 => x"2002",
000760 => x"4030",
000761 => x"f6d4",
000762 => x"903a",
000763 => x"000a",
000764 => x"2002",
000765 => x"474c",
000766 => x"1288",
000767 => x"5319",
000768 => x"4030",
000769 => x"f5e6",
000770 => x"f07c",
000771 => x"000f",
000772 => x"407d",
000773 => x"0009",
000774 => x"9c4d",
000775 => x"2805",
000776 => x"503c",
000777 => x"0030",
000778 => x"12b0",
000779 => x"f5ae",
000780 => x"4130",
000781 => x"507c",
000782 => x"0057",
000783 => x"f03c",
000784 => x"00ff",
000785 => x"4030",
000786 => x"f614",
000787 => x"120a",
000788 => x"1209",
000789 => x"4c49",
000790 => x"490c",
000791 => x"426d",
000792 => x"12b0",
000793 => x"f6e0",
000794 => x"403a",
000795 => x"f604",
000796 => x"128a",
000797 => x"494c",
000767 => x"4a4c",
000768 => x"1288",
000769 => x"5319",
000770 => x"4030",
000771 => x"f5ea",
000772 => x"f07c",
000773 => x"000f",
000774 => x"407d",
000775 => x"0009",
000776 => x"9c4d",
000777 => x"2805",
000778 => x"503c",
000779 => x"0030",
000780 => x"12b0",
000781 => x"f5b2",
000782 => x"4130",
000783 => x"507c",
000784 => x"0057",
000785 => x"f03c",
000786 => x"00ff",
000787 => x"4030",
000788 => x"f618",
000789 => x"120a",
000790 => x"1209",
000791 => x"4c49",
000792 => x"490c",
000793 => x"426d",
000794 => x"12b0",
000795 => x"f6e4",
000796 => x"403a",
000797 => x"f608",
000798 => x"128a",
000799 => x"4030",
000800 => x"f6d4",
000801 => x"120a",
000802 => x"1209",
000803 => x"4c09",
000804 => x"427d",
000805 => x"12b0",
000806 => x"f6e0",
000807 => x"403a",
000808 => x"f626",
000809 => x"128a",
000810 => x"494c",
000799 => x"494c",
000800 => x"128a",
000801 => x"4030",
000802 => x"f6d8",
000803 => x"120a",
000804 => x"1209",
000805 => x"4c09",
000806 => x"427d",
000807 => x"12b0",
000808 => x"f6e4",
000809 => x"403a",
000810 => x"f62a",
000811 => x"128a",
000812 => x"4030",
000813 => x"f6d4",
000814 => x"f03c",
000815 => x"00ff",
000816 => x"403d",
000817 => x"ffa4",
000818 => x"438d",
000819 => x"0000",
000820 => x"5c0c",
000821 => x"5c0c",
000812 => x"494c",
000813 => x"128a",
000814 => x"4030",
000815 => x"f6d8",
000816 => x"f03c",
000817 => x"00ff",
000818 => x"403d",
000819 => x"ffa4",
000820 => x"438d",
000821 => x"0000",
000822 => x"5c0c",
000823 => x"5c0c",
000824 => x"5c0c",
837,199 → 837,199
000826 => x"5c0c",
000827 => x"5c0c",
000828 => x"5c0c",
000829 => x"d03c",
000830 => x"0040",
000831 => x"4c8d",
000832 => x"0000",
000833 => x"4130",
000834 => x"f0b2",
000835 => x"ffc0",
000836 => x"ffa4",
000837 => x"4130",
000838 => x"403d",
000839 => x"ffa6",
000840 => x"4c8d",
000841 => x"0000",
000842 => x"403e",
000843 => x"ffa4",
000844 => x"4e2c",
000845 => x"930c",
000846 => x"3bfd",
000847 => x"4d2c",
000848 => x"4130",
000849 => x"4c82",
000850 => x"ffae",
000851 => x"4130",
000852 => x"ec82",
000853 => x"ffae",
000854 => x"4130",
000855 => x"d232",
000856 => x"4303",
000857 => x"4130",
000858 => x"108c",
000829 => x"5c0c",
000830 => x"5c0c",
000831 => x"d03c",
000832 => x"0040",
000833 => x"4c8d",
000834 => x"0000",
000835 => x"4130",
000836 => x"f0b2",
000837 => x"ffc0",
000838 => x"ffa4",
000839 => x"4130",
000840 => x"403d",
000841 => x"ffa6",
000842 => x"4c8d",
000843 => x"0000",
000844 => x"403e",
000845 => x"ffa4",
000846 => x"4e2c",
000847 => x"930c",
000848 => x"3bfd",
000849 => x"4d2c",
000850 => x"4130",
000851 => x"4c82",
000852 => x"ffac",
000853 => x"4130",
000854 => x"ec82",
000855 => x"ffac",
000856 => x"4130",
000857 => x"d232",
000858 => x"4303",
000859 => x"4130",
000860 => x"4c4e",
000861 => x"4d4c",
000862 => x"108e",
000863 => x"de0c",
000864 => x"4130",
000865 => x"40b2",
000866 => x"4700",
000867 => x"ffb8",
000868 => x"4130",
000869 => x"4134",
000870 => x"4135",
000871 => x"4136",
000872 => x"4137",
000873 => x"4138",
000874 => x"4139",
000875 => x"413a",
000876 => x"4130",
000877 => x"533d",
000878 => x"c312",
000879 => x"100c",
000880 => x"930d",
000881 => x"23fb",
000882 => x"4130",
000883 => x"533e",
000884 => x"c312",
000885 => x"100d",
000886 => x"100c",
000887 => x"930e",
000888 => x"23fa",
000889 => x"4130",
000890 => x"4d43",
000891 => x"7344",
000892 => x"0a3a",
000893 => x"3a68",
000894 => x"4820",
000895 => x"6c65",
000896 => x"0a70",
000897 => x"3a72",
000898 => x"5220",
000899 => x"7365",
000900 => x"6174",
000901 => x"7472",
000902 => x"750a",
000903 => x"203a",
000904 => x"7055",
000905 => x"6f6c",
000906 => x"6461",
000907 => x"700a",
000908 => x"203a",
000909 => x"7250",
000910 => x"676f",
000911 => x"6172",
000912 => x"0a6d",
000913 => x"3a65",
000914 => x"4520",
000915 => x"6578",
000916 => x"7563",
000917 => x"6574",
000918 => x"0700",
000919 => x"450a",
000920 => x"5252",
000921 => x"005f",
000922 => x"6f42",
000923 => x"746f",
000924 => x"6e69",
000925 => x"2e67",
000860 => x"108c",
000861 => x"4130",
000862 => x"4c4e",
000863 => x"4d4c",
000864 => x"108e",
000865 => x"de0c",
000866 => x"4130",
000867 => x"40b2",
000868 => x"4700",
000869 => x"ffb8",
000870 => x"4130",
000871 => x"4134",
000872 => x"4135",
000873 => x"4136",
000874 => x"4137",
000875 => x"4138",
000876 => x"4139",
000877 => x"413a",
000878 => x"4130",
000879 => x"533d",
000880 => x"c312",
000881 => x"100c",
000882 => x"930d",
000883 => x"23fb",
000884 => x"4130",
000885 => x"533e",
000886 => x"c312",
000887 => x"100d",
000888 => x"100c",
000889 => x"930e",
000890 => x"23fa",
000891 => x"4130",
000892 => x"4d43",
000893 => x"7344",
000894 => x"0a3a",
000895 => x"3a68",
000896 => x"4820",
000897 => x"6c65",
000898 => x"0a70",
000899 => x"3a72",
000900 => x"5220",
000901 => x"7365",
000902 => x"6174",
000903 => x"7472",
000904 => x"750a",
000905 => x"203a",
000906 => x"7055",
000907 => x"6f6c",
000908 => x"6461",
000909 => x"700a",
000910 => x"203a",
000911 => x"7250",
000912 => x"676f",
000913 => x"650a",
000914 => x"203a",
000915 => x"7845",
000916 => x"6365",
000917 => x"7475",
000918 => x"0065",
000919 => x"0a07",
000920 => x"5245",
000921 => x"5f52",
000922 => x"4200",
000923 => x"6f6f",
000924 => x"6974",
000925 => x"676e",
000926 => x"2e2e",
000927 => x"0a0a",
000928 => x"4100",
000929 => x"6177",
000930 => x"7469",
000931 => x"6e69",
000932 => x"2067",
000933 => x"4942",
000934 => x"454e",
000935 => x"4558",
000936 => x"2e2e",
000937 => x"002e",
000938 => x"6f4c",
000939 => x"6461",
000940 => x"6e69",
000941 => x"2e67",
000927 => x"0a2e",
000928 => x"000a",
000929 => x"7741",
000930 => x"6961",
000931 => x"6974",
000932 => x"676e",
000933 => x"4220",
000934 => x"4e49",
000935 => x"5845",
000936 => x"2e45",
000937 => x"2e2e",
000938 => x"4c00",
000939 => x"616f",
000940 => x"6964",
000941 => x"676e",
000942 => x"2e2e",
000943 => x"4f00",
000944 => x"004b",
000945 => x"2e2e",
000946 => x"002e",
000947 => x"0a0a",
000948 => x"454e",
000949 => x"344f",
000950 => x"3033",
000951 => x"4220",
000952 => x"6f6f",
000953 => x"6c74",
000954 => x"616f",
000955 => x"6564",
000956 => x"0a72",
000957 => x"420a",
000958 => x"564c",
000959 => x"203a",
000960 => x"614d",
000961 => x"2072",
000962 => x"3631",
000963 => x"3220",
000964 => x"3230",
000965 => x"0a30",
000966 => x"5748",
000967 => x"3a56",
000968 => x"3020",
000969 => x"0078",
000970 => x"550a",
000971 => x"5253",
000972 => x"203a",
000973 => x"7830",
000974 => x"0a00",
000975 => x"4c43",
000976 => x"3a4b",
000977 => x"3020",
000978 => x"0078",
000979 => x"520a",
000980 => x"4d4f",
000981 => x"203a",
000982 => x"7830",
000983 => x"0a00",
000984 => x"4152",
000985 => x"3a4d",
000986 => x"3020",
000987 => x"0078",
000988 => x"530a",
000989 => x"5359",
000990 => x"203a",
000991 => x"7830",
000992 => x"0a00",
000993 => x"410a",
000994 => x"7475",
000995 => x"626f",
000996 => x"6f6f",
000997 => x"2074",
000998 => x"6e69",
000999 => x"3420",
001000 => x"2e73",
001001 => x"5020",
001002 => x"6572",
001003 => x"7373",
001004 => x"6b20",
001005 => x"7965",
001006 => x"7420",
001007 => x"206f",
001008 => x"6261",
001009 => x"726f",
001010 => x"2e74",
001011 => x"0a0a",
001012 => x"0a00",
001013 => x"0a00",
001014 => x"4d43",
001015 => x"3a44",
001016 => x"203e",
001017 => x"4200",
001018 => x"6461",
001019 => x"4320",
001020 => x"444d",
001021 => x"0000",
000943 => x"002e",
000944 => x"4b4f",
000945 => x"2e00",
000946 => x"2e2e",
000947 => x"0a00",
000948 => x"4e0a",
000949 => x"4f45",
000950 => x"3334",
000951 => x"2030",
000952 => x"6f42",
000953 => x"746f",
000954 => x"6f6c",
000955 => x"6461",
000956 => x"7265",
000957 => x"0a0a",
000958 => x"4c42",
000959 => x"3a56",
000960 => x"4d20",
000961 => x"7261",
000962 => x"3220",
000963 => x"2039",
000964 => x"3032",
000965 => x"3032",
000966 => x"480a",
000967 => x"5657",
000968 => x"203a",
000969 => x"7830",
000970 => x"0a00",
000971 => x"5355",
000972 => x"3a52",
000973 => x"3020",
000974 => x"0078",
000975 => x"430a",
000976 => x"4b4c",
000977 => x"203a",
000978 => x"7830",
000979 => x"0a00",
000980 => x"4f52",
000981 => x"3a4d",
000982 => x"3020",
000983 => x"0078",
000984 => x"520a",
000985 => x"4d41",
000986 => x"203a",
000987 => x"7830",
000988 => x"0a00",
000989 => x"5953",
000990 => x"3a53",
000991 => x"3020",
000992 => x"0078",
000993 => x"0a0a",
000994 => x"7541",
000995 => x"6f74",
000996 => x"6f62",
000997 => x"746f",
000998 => x"6920",
000999 => x"206e",
001000 => x"7334",
001001 => x"202e",
001002 => x"7250",
001003 => x"7365",
001004 => x"2073",
001005 => x"656b",
001006 => x"2079",
001007 => x"6f74",
001008 => x"6120",
001009 => x"6f62",
001010 => x"7472",
001011 => x"0a2e",
001012 => x"000a",
001013 => x"000a",
001014 => x"430a",
001015 => x"444d",
001016 => x"3e3a",
001017 => x"0020",
001018 => x"6142",
001019 => x"2064",
001020 => x"4d43",
001021 => x"0044",
others => x"0000"
);
 
/neo430/rtl/core/neo430_control.vhd
1,7 → 1,7
-- #################################################################################################
-- # << NEO430 - Main Control Unit >> #
-- # ********************************************************************************************* #
-- # Central CPU control unit (FSM). #
-- # Central CPU control unit (micro sequencer / FSM). #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
196,7 → 196,7
-- valid write back? --
valid_wb_v := '1';
if (ir(15 downto 12) = alu_cmp_c) or (ir(15 downto 12) = alu_bit_c) then
valid_wb_v := '0';
valid_wb_v := '0'; -- CMP and BIT instructions only write status flags
end if;
 
-- state machine --
205,7 → 205,6
when RESET => -- init PC with boot address
-- ------------------------------------------------------------
ctrl_nxt(ctrl_rf_boot_c) <= '1'; -- load boot address
ctrl_nxt(ctrl_rf_ad_c) <= '0'; -- DST address mode = REG
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC
state_nxt <= IFETCH_0;
215,7 → 214,6
-- ------------------------------------------------------------
sam_nxt <= "00"; -- SRC address mode = REG, required for all special operations + IRQ
ctrl_nxt(ctrl_alu_bw_c) <= '0'; -- word mode, also required for all IRQ states
ctrl_nxt(ctrl_rf_ad_c) <= '0'; -- DST address mode = REG
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2
ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr gen feedback
263,7 → 261,6
else
ctrl_nxt(ctrl_alu_cmd3_c downto ctrl_alu_cmd0_c) <= alu_mov_c; -- to move OpA -> RF/MEM
end if;
ctrl_nxt(ctrl_rf_ad_c) <= instr_i(5) or instr_i(4);
case instr_i(9 downto 7) is
when "100" => state_nxt <= TRANS_0; -- PUSH (via single ALU OP)
when "101" => state_nxt <= TRANS_0; -- CALL (via single ALU OP)
286,7 → 283,6
am_nxt(2 downto 1) <= instr_i(5 downto 4); -- source addressing mode
end if;
am_nxt(0) <= instr_i(7); -- dst addressing mode
ctrl_nxt(ctrl_rf_ad_c) <= instr_i(7);
ctrl_nxt(ctrl_alu_cmd3_c downto ctrl_alu_cmd0_c) <= instr_i(15 downto 12); -- ALU function
src_nxt <= instr_i(11 downto 8);
if (instr_i(15 downto 12) = "1010") then -- !!!INVALID ALUOP!!!
301,29 → 297,30
-- ------------------------------------------------------------
-- (pseudo) defaults
ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr gen feedback (only relevant for when 2,3,5)
ctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus (only relevant for when 2,4,5)
ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast) (only relevant for when 2,4,5)
mem_rd <= '1'; -- Memory read (only relevant for when 3) [not so very energy efficient]
ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast)
ctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus
ctrl_nxt(ctrl_adr_mar_wr_c) <= am(0); -- write to MAR [relevant for memory writeback when using CLASS II operations]
--
case am is -- addressing mode
when "0001" | "0000" | "1000" =>
-- "0001" = CLASS II, SRC: Reg, DST: Indexed
-- "0000" = CLASS II, SRC/DST: register direct
-- "1000" = CLASS I, SRC/DST: Reg
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= src; -- source: reg A
ctrl_nxt(ctrl_alu_opa_wr_c) <= '1'; -- write OpA
if (am(3) = '0') then -- CLASS II
if (spec_cmd_v = '1') then -- push or call
state_nxt <= PUSHCALL_0;
else
state_nxt <= TRANS_6;
end if;
else -- CLASS I
state_nxt <= TRANS_1;
if (spec_cmd_v = '1') then -- push or call
state_nxt <= PUSHCALL_0;
elsif (am(3) = '0') then -- CLASS II operation
state_nxt <= TRANS_6;
else
state_nxt <= TRANS_3;
end if;
 
when "1001" | "0010" | "0011" =>
when "1001" | "1010" | "0010" | "0011" =>
-- "1001" = CLASS I, SRC: register direct, DST: indexed
-- "001-" = CLASS II, SRC/DST: indexed/symbolic/absolute
--
-- "1010" = CLASS I, SRC: indexed/symbolic/absolute, DST: register direct
-- "001-" = CLASS II, SRC: indexed/symbolic/absolute, DST: indexed/symbolic/absolute OR register direct
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC
--> ctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus
--> ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast)
330,18 → 327,18
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2
--> ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr gen feedback
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back
if (am(3) = '1') then -- "1001" = CLASS I, SRC: register direct, DST: indexed
if (am(2 downto 1) = "00") then -- "1001" = CLASS I, SRC: register direct, DST: indexed
state_nxt <= TRANS_3;
else -- "001-" = CLASS II, SRC/DST: indexed/symbolic/absolute
else
state_nxt <= TRANS_2;
end if;
 
when "1010" | "1011" =>
-- "1010" = CLASS I, SRC: indexed/symbolic/absolute, DST: register direct
when "1011" =>
-- "1011" = CLASS I, SRC: indexed/symbolic/absolute, DST: indexed
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= reg_pc_c; -- source/destination: PC
ctrl_nxt(ctrl_adr_mar_wr_c) <= '1'; -- write to MAR
--> mem_rd <= '1'; -- Memory read
mem_rd <= '1'; -- Memory read
--> ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast)
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2
--> ctrl_nxt(ctrl_rf_in_sel_c) <= '1'; -- select addr gen feedback
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write back
352,7 → 349,7
-- "1100" = CLASS I, SRC: indirect, DST: register direct
-- "1101" = CLASS I, SRC: indirect, DST: indexed
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= src; -- source: reg A
--> ctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus
--> cctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus
--> ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast)
state_nxt <= TRANS_1;
 
360,7 → 357,8
-- "011-" = CLASS II, SRC/DST: indirect auto inc
-- "1110" = CLASS I, SRC: indirect auto inc, DST: register direct
-- "1111" = CLASS I, SRC: indirect auto inc, DST: indexed
--> ctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= src; -- source: reg A
--> cctrl_nxt(ctrl_adr_bp_en_c) <= '1'; -- directly output RF.out to address bus
--> ctrl_nxt(ctrl_mem_rd_c) <= '1'; -- Memory read (fast)
if (ir(6) = '0') or (src = reg_pc_c) then -- word mode (force if accessing PC)
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "010"; -- add +2
380,26 → 378,14
mem_rd <= '1'; -- Memory read (only relevant for last two 'when' 5)
--
case am is -- addressing mode
when "0000" | "0001" | "1000" | "1001" =>
-- "000-" = CLASS II, SRC/DST: register direct
-- "1000" = CLASS I, SRC: register direct, DST: register direct
-- "1001" = CLASS I, SRC: register direct, DST: indexed
ctrl_nxt(ctrl_rf_as1_c downto ctrl_rf_as0_c) <= "00"; -- DST address mode = REG
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= ir(3 downto 0); -- source: reg B
ctrl_nxt(ctrl_alu_opb_wr_c) <= '1'; -- write OpB
if (spec_cmd_v = '1') then -- push or call
state_nxt <= PUSHCALL_0;
else
state_nxt <= TRANS_6;
end if;
-- "000-" = CLASS II, SRC/DST: register direct [ACTUAL DON'T CARE; STATE NOT USED]
-- "1000" = CLASS I, SRC: register direct, DST: register direct [ACTUAL DON'T CARE; STATE NOT USED]
-- "1001" = CLASS I, SRC: register direct, DST: indexed [ACTUAL DON'T CARE; STATE NOT USED]
-- ==> DONT CARE
 
when "0010" | "0011" | "1010" =>
-- "001-" = CLASS II, SRC/DST: indexed/symbolic/absolute [ACTUAL DON'T CARE; STATE NOT USED]
-- "1010" = CLASS I, SRC: indexed/symbolic/absolute, DST: register direct [ACTUAL DON'T CARE; STATE NOT USED]
ctrl_nxt(ctrl_rf_as1_c downto ctrl_rf_as0_c) <= "00"; -- DST address mode = REG
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= ir(3 downto 0); -- source: reg B
ctrl_nxt(ctrl_alu_opb_wr_c) <= '1'; -- write OpB
state_nxt <= TRANS_2;
-- "001-" = CLASS II, SRC/DST: indexed/symbolic/absolute [ACTUAL DON'T CARE; STATE NOT USED]
-- "1010" = CLASS I, SRC: indexed/symbolic/absolute, DST: register direct [ACTUAL DON'T CARE; STATE NOT USED]
-- ==> DONT CARE
 
when "0100" | "0101" | "1100" | "0110" | "0111" | "1110" =>
-- "010-" = CLASS II, SRC/DST: indirect
415,7 → 401,7
if (am(3) = '0') then -- CLASS II
state_nxt <= TRANS_6;
else -- CLASS I
state_nxt <= TRANS_2;
state_nxt <= TRANS_3;
end if;
end if;
 
446,46 → 432,25
 
when TRANS_2 => -- operand transfer cycle 2
-- ------------------------------------------------------------
-- (pseudo) defaults
-- "001-" = CLASS II: SRC/DST: indexed/symbolic/absolute
-- "1010" = CLASS I, SRC: indexed/symbolic/absolute, DST: register direct
-- "1011" = CLASS I, SRC: indexed/symbolic/absolute, DST: indexed
-- OTHERS = DONT CARE [state not reachable]
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= src; -- source: reg A
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "1--"; -- add memory data in (only relevant for first 'when')
ctrl_nxt(ctrl_adr_mar_sel_c) <= '1'; -- use result from adder
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "1--"; -- add memory data in
ctrl_nxt(ctrl_adr_mar_wr_c) <= '1'; -- write to MAR
mem_rd <= '1'; -- Memory read
mem_rd <= '1'; -- Memory read
state_nxt <= TRANS_3;
ctrl_nxt(ctrl_adr_mar_sel_c) <= '1'; -- use result from adder (only relevant for first 'when')
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "1--"; -- add memory data in (only relevant for first 'when')
mem_rd <= '1'; -- Memory read (only relevant for first 'when') [not so very energy efficient]
--
case am is -- addressing mode
when "0010" | "0011" | "1010" | "1011" =>
-- "001-" = CLASS II: SRC/DST: indexed/symbolic/absolute
-- "1010" = CLASS I, SRC: indexed/symbolic/absolute, DST: register direct
-- "1011" = CLASS I, SRC: indexed/symbolic/absolute, DST: indexed
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= src; -- source: reg A
--> ctrl_nxt(ctrl_adr_mar_sel_c) <= '1'; -- use result from adder
--> ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "1--"; -- add memory data in
ctrl_nxt(ctrl_adr_mar_wr_c) <= '1'; -- write to MAR
--> mem_rd <= '1'; -- Memory read
 
when "0100" | "0101" | "1100" | "1101" | "0110" | "0111" | "1110" | "1111" =>
-- "010-" = CLASS II: SRC/DST: indirect [STATE NOT USED]
-- "1100" = CLASS I, SRC: indirect, DST: register direct
-- "1101" = CLASS I, SRC: indirect, DST: indexed [STATE NOT USED]
--
-- "011-" = CLASS II: SRC/DST: indirect auto inc [STATE NOT USED]
-- "1110" = CLASS I, SRC: indirect auto inc, DST: register direct
-- "1111" = CLASS I, SRC: indirect auto inc, DST: indexed [STATE NOT USED]
ctrl_nxt(ctrl_rf_as1_c downto ctrl_rf_as0_c) <= "00"; -- DST address mode = REG
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= ir(3 downto 0); -- source: reg B
ctrl_nxt(ctrl_alu_opb_wr_c) <= '1'; -- write OpB
state_nxt <= TRANS_6;
 
when others => -- NOP
NULL;
end case;
 
when TRANS_3 => -- operand transfer cycle 3
-- ------------------------------------------------------------
-- (pseudo) defaults
state_nxt <= TRANS_4;
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= ir(3 downto 0); -- source: reg B
ctrl_nxt(ctrl_adr_mar_sel_c) <= '1'; -- use result from adder (only relevant for first 'when')
ctrl_nxt(ctrl_adr_mar_sel_c) <= '1'; -- use result from adder
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "1--"; -- add memory data in
--
case am is -- addressing mode
when "1001" | "1011" | "1101" | "1111" =>
495,15 → 460,20
-- "1111" = CLASS I, SRC: indirect auto inc, DST: indexed
ctrl_nxt(ctrl_rf_as1_c) <= '0'; -- DST address mode = REG or INDEXED
ctrl_nxt(ctrl_rf_as0_c) <= ir(7); -- DST address mode = REG or INDEXED
ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "1--"; -- add memory data in
--> ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= ir(3 downto 0); -- source: reg B
--> ctrl_nxt(ctrl_adr_off2_c downto ctrl_adr_off0_c) <= "1--"; -- add memory data in
--> ctrl_nxt(ctrl_adr_mar_sel_c) <= '1'; -- use result from adder
ctrl_nxt(ctrl_adr_mar_wr_c) <= '1'; -- write to MAR
mem_rd <= '1'; -- Memory read [even if MOV operation]
mem_rd <= '1'; -- Memory read
state_nxt <= TRANS_4;
 
when others =>
--> ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= ir(3 downto 0); -- source: reg B
ctrl_nxt(ctrl_rf_as1_c downto ctrl_rf_as0_c) <= "00"; -- DST address mode = REG
ctrl_nxt(ctrl_alu_opb_wr_c) <= '1'; -- write OpB
if (am(2 downto 1) = "01") then
state_nxt <= TRANS_4;
else
state_nxt <= TRANS_6;
end if;
end case;
 
when TRANS_4 => -- operand transfer cycle 4
512,30 → 482,22
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= src; -- source: reg A (only relevant for 3rd 'when')
--
case am is -- addressing mode
when "0010" | "0011" | "1010" =>
when "0010" | "0011" | "1010" | "1011" =>
-- "001-" = CLASS II, SRC/DST: indexed/symbolic/absolute
-- "1010" = CLASS I, SRC: indexed/symbolic/absolute, DST: register direct
-- "1011" = CLASS I, SRC: indexed/symbolic/absolute, DST: indexed
ctrl_nxt(ctrl_alu_in_sel_c) <= '1'; -- get data from memory
ctrl_nxt(ctrl_alu_opa_wr_c) <= '1'; -- write to OpA
if (spec_cmd_v = '1') then -- push or call
state_nxt <= PUSHCALL_0;
elsif ((am(3) and am(0)) = '1') and (move_cmd_v = '0') then -- skip processing of second operand when executing MOV instruction
state_nxt <= TRANS_5;
else
state_nxt <= TRANS_6;
end if;
 
when "1011" =>
-- "1011" = CLASS I, SRC: indexed/symbolic/absolute, DST: indexed
ctrl_nxt(ctrl_alu_in_sel_c) <= '1'; -- get data from memory
ctrl_nxt(ctrl_alu_opa_wr_c) <= '1'; -- write to OpA
if (move_cmd_v = '1') then -- skip processing of second operand when executing MOV instruction
state_nxt <= TRANS_6;
else
state_nxt <= TRANS_5;
end if;
 
when "1001" =>
-- "1001" = CLASS I, SRC: register direct, DST: indexed
--> ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= src; -- source: reg A
ctrl_nxt(ctrl_alu_opa_wr_c) <= '1'; -- write OpA
if (move_cmd_v = '1') then -- skip processing of second operand when executing MOV instruction
state_nxt <= TRANS_6;
546,7 → 508,8
when others => -- NOP / DONT CARE
-- "000-" = CLASS II, SRD/DST: DONT CARE
-- "1000" = CLASS I, SRC: register direct, DST: register direct = DONT CARE
-- others: DONT CARE
-- "-10-" : NOP
-- "-11-" : NOP
if (move_cmd_v = '1') then -- skip processing of second operand when executing MOV instruction
state_nxt <= TRANS_6;
else
560,7 → 523,7
ctrl_nxt(ctrl_alu_opb_wr_c) <= '1'; -- write to OpB
state_nxt <= TRANS_6;
 
when TRANS_6 => -- operand transfer cycle 6
when TRANS_6 => -- operand transfer cycle 6: RF or MEM write-back
-- ------------------------------------------------------------
ctrl_nxt(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) <= ir(3 downto 0); -- destination
ctrl_nxt(ctrl_rf_fup_c) <= not spec_cmd_v; -- update ALU status flags
/neo430/rtl/core/neo430_exirq.vhd
63,7 → 63,7
-- cpu interrupt --
cpu_irq_o : out std_ulogic;
-- external interrupt lines --
ext_irq_i : in std_ulogic_vector(7 downto 0); -- IRQ
ext_irq_i : in std_ulogic_vector(7 downto 0); -- IRQ, triggering on HIGH level
ext_ack_o : out std_ulogic_vector(7 downto 0) -- acknowledge
);
end neo430_exirq;
71,22 → 71,21
architecture neo430_exirq_rtl of neo430_exirq is
 
-- control register bits --
constant ctrl_src0_c : natural := 0; -- r/-: IRQ source bit 0
constant ctrl_src1_c : natural := 1; -- r/-: IRQ source bit 1
constant ctrl_src2_c : natural := 2; -- r/-: IRQ source bit 2
constant ctrl_en_c : natural := 3; -- r/w: unit enable
constant ctrl_sw_irq_c : natural := 4; -- -/w: enable SW IRQ trigger, auto-clears
constant ctrl_sw_irq_sel0_c : natural := 5; -- -/w: SW IRQ select bit 0
constant ctrl_sw_irq_sel1_c : natural := 6; -- -/w: SW IRQ select bit 1
constant ctrl_sw_irq_sel2_c : natural := 7; -- -/w: SW IRQ select bit 2
constant ctrl_en_irq0_c : natural := 8; -- r/w: IRQ channel 0 enable
constant ctrl_en_irq1_c : natural := 9; -- r/w: IRQ channel 1 enable
constant ctrl_en_irq2_c : natural := 10; -- r/w: IRQ channel 2 enable
constant ctrl_en_irq3_c : natural := 11; -- r/w: IRQ channel 3 enable
constant ctrl_en_irq4_c : natural := 12; -- r/w: IRQ channel 4 enable
constant ctrl_en_irq5_c : natural := 13; -- r/w: IRQ channel 5 enable
constant ctrl_en_irq6_c : natural := 14; -- r/w: IRQ channel 6 enable
constant ctrl_en_irq7_c : natural := 15; -- r/w: IRQ channel 7 enable
constant ctrl_irq_sel0_c : natural := 0; -- r/w: IRQ source bit 0 (r); SW IRQ select / ACK select (w)
constant ctrl_irq_sel1_c : natural := 1; -- r/w: IRQ source bit 1 (r); SW IRQ select / ACK select (w)
constant ctrl_irq_sel2_c : natural := 2; -- r/w: IRQ source bit 2 (r); SW IRQ select / ACK select (w)
constant ctrl_en_c : natural := 3; -- r/w: unit enable
constant ctrl_sw_irq_c : natural := 4; -- -/w: use irq_sel as SW IRQ trigger, auto-clears
constant ctrl_ack_irq_c : natural := 5; -- -/w: use irq_sel as ACK select, auto-clears
-- ...
constant ctrl_en_irq0_c : natural := 8; -- r/w: IRQ channel 0 enable
constant ctrl_en_irq1_c : natural := 9; -- r/w: IRQ channel 1 enable
constant ctrl_en_irq2_c : natural := 10; -- r/w: IRQ channel 2 enable
constant ctrl_en_irq3_c : natural := 11; -- r/w: IRQ channel 3 enable
constant ctrl_en_irq4_c : natural := 12; -- r/w: IRQ channel 4 enable
constant ctrl_en_irq5_c : natural := 13; -- r/w: IRQ channel 5 enable
constant ctrl_en_irq6_c : natural := 14; -- r/w: IRQ channel 6 enable
constant ctrl_en_irq7_c : natural := 15; -- r/w: IRQ channel 7 enable
 
-- IO space: module base address --
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
99,9 → 98,10
 
-- r/w accessible registers --
signal irq_enable : std_ulogic_vector(7 downto 0);
signal enable : std_ulogic;
signal enable : std_ulogic; -- global enable
signal irq_sel : std_ulogic_vector(2 downto 0);
signal sw_trig : std_ulogic;
signal sw_trig_src : std_ulogic_vector(2 downto 0);
signal ack_trig : std_ulogic;
 
-- irq input / ack output system --
signal irq_sync, irq_raw, sw_irq, irq_valid, ack_mask : std_ulogic_vector(7 downto 0);
125,13 → 125,15
wr_access: process(clk_i)
begin
if rising_edge(clk_i) then
sw_trig <= '0';
sw_trig <= '0';
ack_trig <= '0';
if (wren = '1') then
irq_sel <= data_i(ctrl_irq_sel2_c downto ctrl_irq_sel0_c);
enable <= data_i(ctrl_en_c);
irq_enable <= data_i(ctrl_en_irq7_c downto ctrl_en_irq0_c);
-- software irq trigger --
sw_trig <= data_i(ctrl_sw_irq_c);
sw_trig_src <= data_i(ctrl_sw_irq_sel2_c downto ctrl_sw_irq_sel0_c);
-- irq_sel options --
sw_trig <= data_i(ctrl_sw_irq_c);
ack_trig <= data_i(ctrl_ack_irq_c);
end if;
end if;
end process wr_access;
147,10 → 149,10
end if;
end process ext_irq_source_sync;
 
sw_irq_source: process(sw_trig, sw_trig_src)
sw_irq_source: process(sw_trig, irq_sel)
variable sw_irq_v : std_ulogic_vector(3 downto 0);
begin
sw_irq_v := sw_trig & sw_trig_src;
sw_irq_v := sw_trig & irq_sel;
case sw_irq_v is
when "1000" => sw_irq <= "00000001";
when "1001" => sw_irq <= "00000010";
192,9 → 194,8
cpu_irq_o <= '1'; -- trigger CPU
state <= '1'; -- go to active IRQ state
end if;
 
else -- active IRQ
if (rden = '1') then -- ACK when reading IRQ source
if (ack_trig = '1') then
ext_ack_o <= ack_mask;
state <= '0';
end if;
218,11 → 219,11
 
-- ACK priority decoder -----------------------------------------------------
-- -----------------------------------------------------------------------------
ack_priority_dec: process(state, irq_src_reg)
variable irq_src_v : std_ulogic_vector(3 downto 0);
ack_priority_dec: process(ack_trig, irq_src_reg)
variable irq_ack_v : std_ulogic_vector(3 downto 0);
begin
irq_src_v := state & irq_src_reg;
case irq_src_v is
irq_ack_v := ack_trig & irq_src_reg;
case irq_ack_v is
when "1000" => ack_mask <= "00000001";
when "1001" => ack_mask <= "00000010";
when "1010" => ack_mask <= "00000100";
243,7 → 244,7
if rising_edge(clk_i) then
data_o <= (others => '0');
if (rden = '1') then
data_o(ctrl_src2_c downto ctrl_src0_c) <= irq_src_reg;
data_o(ctrl_irq_sel2_c downto ctrl_irq_sel0_c) <= irq_src_reg;
data_o(ctrl_en_irq7_c downto ctrl_en_irq0_c) <= irq_enable;
data_o(ctrl_en_c) <= enable;
end if;
/neo430/rtl/core/neo430_muldiv.vhd
4,6 → 4,12
-- # NOTE: This unit uses "repeated trial subtraction" as division algorithm. #
-- # NOTE: This unit uses "shifted add" as multiplication algorithm. Set 'use_dsp_mul_c' in the #
-- # package file to TRUE to use DSP slices for multiplication. #
-- # #
-- # OpA is used for storing the first operand as well as for function configuration. Set this #
-- # register to 0 reset the unit. Afterwards, set it to 0b01 for multiplication or to 0b10 for #
-- # division. Afterwards, write the actual operand. The actual operation is started by #
-- # writing OpB. #
-- # #
-- # Division: DIVIDEND / DIVIDER = QUOTIENT + REMAINDER (16-bit) / DIVIDER (16-bit) #
-- # Multiplication: FACTOR1 * FACTOR2 = PRODUCT (32-bit) #
-- # ********************************************************************************************* #
68,10 → 74,14
signal addr : std_ulogic_vector(15 downto 0); -- access address
signal wr_en : std_ulogic; -- only full 16-bit word accesses!
 
-- control --
signal ctrl_state : std_ulogic;
signal operation : std_ulogic; -- '1' division, '0' multiplication
signal func_rst : std_ulogic;
 
-- accessible regs --
signal opa, opb : std_ulogic_vector(15 downto 0);
signal resx, resy : std_ulogic_vector(15 downto 0);
signal operation : std_ulogic;
 
-- arithmetic core & arbitration --
signal start : std_ulogic;
100,24 → 110,31
start <= '0';
if (wr_en = '1') then -- only full word accesses!
-- operands --
if (addr = muldiv_opa_addr_c) then -- dividend or factor 1
opa <= data_i;
if (addr = muldiv_opa_ctrl_addr_c) then -- reset/control OR dividend or mul_factor a
opa <= data_i;
end if;
if (addr = muldiv_opb_div_addr_c) or (addr = muldiv_opb_mul_addr_c) then -- divisor or factor 2
opb <= data_i;
start <= '1'; -- trigger operation
if (addr = muldiv_opb_addr_c) then -- divisor or mul_factor b
opb <= data_i;
start <= '1'; -- start operation
end if;
-- operation: division/multiplication --
if (addr = muldiv_opb_div_addr_c) then -- division
operation <= '1';
else -- multiplication
operation <= '0';
-- operation configuration --
if (func_rst = '1') then -- reset configuration
ctrl_state <= '0';
elsif (ctrl_state = '0') then -- get new configuration
if (wr_en = '1') then
operation <= opa(1); -- '1' division, '0' multiplication
ctrl_state <= '1';
end if;
-- else -- execute configuration
end if;
end if;
end if;
end process wr_access;
 
-- reset when OpA is zero --
func_rst <= '1' when (opa = x"0000") else '0';
 
 
-- Arithmetic core ----------------------------------------------------------
-- -----------------------------------------------------------------------------
arithmetic_core: process(clk_i)
/neo430/rtl/core/neo430_package.vhd
40,9 → 40,9
 
-- Processor Hardware Version -------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(15 downto 0) := x"0401"; -- no touchy!
constant hw_version_c : std_ulogic_vector(15 downto 0) := x"0404"; -- no touchy!
 
-- Advanced Hardware Configuration --------------------------------------------------------
-- Danger Zone (Advanced Hardware Configuration) ------------------------------------------
-- -------------------------------------------------------------------------------------------
constant use_dsp_mul_c : boolean := false; -- use DSP blocks for MULDIV's multiplication core (default=false)
constant use_xalu_c : boolean := false; -- implement extended ALU function (default=false)
90,17 → 90,22
 
-- IO: Multiplier/Divider Unit (MULDIV) --
constant muldiv_base_c : std_ulogic_vector(15 downto 0) := x"FF80";
constant muldiv_size_c : natural := 16; -- bytes
constant muldiv_size_c : natural := 8; -- bytes
 
constant muldiv_opa_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0000");
constant muldiv_opb_div_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0002");
constant muldiv_opb_mul_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0004");
--constant muldiv_???_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0006");
--constant muldiv_???_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0008");
--constant muldiv_???_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"000A");
constant muldiv_resx_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"000C");
constant muldiv_resy_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"000E");
constant muldiv_opa_ctrl_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0000");
constant muldiv_opb_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0002");
constant muldiv_resx_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0004");
constant muldiv_resy_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(muldiv_base_c) + x"0006");
 
-- IO: reserved --
--constant reserved_base_c : std_ulogic_vector(15 downto 0) := x"FF88";
--constant reserved_size_c : natural := 8; -- bytes
 
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0000");
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0002");
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0004");
--constant reserved_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(reserved_base_c) + x"0006");
 
-- IO: Wishbone32 Interface (WB32) --
constant wb32_base_c : std_ulogic_vector(15 downto 0) := x"FF90";
constant wb32_size_c : natural := 16; -- bytes
132,10 → 137,10
constant gpio_base_c : std_ulogic_vector(15 downto 0) := x"FFA8";
constant gpio_size_c : natural := 8; -- bytes
 
--constant gpio_???_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0000");
constant gpio_irqmask_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0002");
constant gpio_in_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0004");
constant gpio_out_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0006");
constant gpio_irqmask_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0000");
constant gpio_in_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0002");
constant gpio_out_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0004");
--constant gpio_???_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(gpio_base_c) + x"0006");
 
-- IO: High-Precision Timer (TIMER) --
constant timer_base_c : std_ulogic_vector(15 downto 0) := x"FFB0";
144,7 → 149,7
constant timer_ctrl_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0000");
constant timer_cnt_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0002");
constant timer_thres_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0004");
--constant timer_???_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0006");
constant timer_nco_addr_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(unsigned(timer_base_c) + x"0006");
 
-- IO: Watchdog Timer (WDT) --
constant wdt_base_c : std_ulogic_vector(15 downto 0) := x"FFB8";
258,34 → 263,33
constant ctrl_rf_adr3_c : natural := 4; -- source/destination register address bit 3
constant ctrl_rf_as0_c : natural := 5; -- source addressing mode bit 0
constant ctrl_rf_as1_c : natural := 6; -- source addressing mode bit 1
constant ctrl_rf_ad_c : natural := 7; -- destination addressing mode
constant ctrl_rf_fup_c : natural := 8; -- update ALU flags
constant ctrl_rf_wb_en_c : natural := 9; -- enable RF write back
constant ctrl_rf_dsleep_c : natural := 10; -- disable sleep mode
constant ctrl_rf_dgie_c : natural := 11; -- disable global interrupt enable
constant ctrl_rf_boot_c : natural := 12; -- inject PC boot address
constant ctrl_rf_fup_c : natural := 7; -- update ALU flags
constant ctrl_rf_wb_en_c : natural := 8; -- enable RF write back
constant ctrl_rf_dsleep_c : natural := 9; -- disable sleep mode
constant ctrl_rf_dgie_c : natural := 10; -- disable global interrupt enable
constant ctrl_rf_boot_c : natural := 11; -- inject PC boot address
-- alu --
constant ctrl_alu_in_sel_c : natural := 13; -- ALU OP input select
constant ctrl_alu_opa_wr_c : natural := 14; -- write ALU operand A
constant ctrl_alu_opb_wr_c : natural := 15; -- write ALU operand B
constant ctrl_alu_cmd0_c : natural := 16; -- ALU command bit 0
constant ctrl_alu_cmd1_c : natural := 17; -- ALU command bit 1
constant ctrl_alu_cmd2_c : natural := 18; -- ALU command bit 2
constant ctrl_alu_cmd3_c : natural := 19; -- ALU command bit 3
constant ctrl_alu_bw_c : natural := 20; -- byte(1)/word(0) operation
constant ctrl_alu_in_sel_c : natural := 12; -- ALU OP input select
constant ctrl_alu_opa_wr_c : natural := 13; -- write ALU operand A
constant ctrl_alu_opb_wr_c : natural := 14; -- write ALU operand B
constant ctrl_alu_cmd0_c : natural := 15; -- ALU command bit 0
constant ctrl_alu_cmd1_c : natural := 16; -- ALU command bit 1
constant ctrl_alu_cmd2_c : natural := 17; -- ALU command bit 2
constant ctrl_alu_cmd3_c : natural := 18; -- ALU command bit 3
constant ctrl_alu_bw_c : natural := 19; -- byte(1)/word(0) operation
-- address generator --
constant ctrl_adr_off0_c : natural := 21; -- address offset selection bit 0
constant ctrl_adr_off1_c : natural := 22; -- address offset selection bit 1
constant ctrl_adr_off2_c : natural := 23; -- address offset selection bit 2
constant ctrl_adr_mar_sel_c : natural := 24; -- select input for MAR
constant ctrl_adr_bp_en_c : natural := 25; -- mem addr output select, 0:MAR, 1:bypass
constant ctrl_adr_ivec_oe_c : natural := 26; -- output IRQ if 1, else output PC
constant ctrl_adr_mar_wr_c : natural := 27; -- write MAR
constant ctrl_adr_off0_c : natural := 20; -- address offset selection bit 0
constant ctrl_adr_off1_c : natural := 21; -- address offset selection bit 1
constant ctrl_adr_off2_c : natural := 22; -- address offset selection bit 2
constant ctrl_adr_mar_sel_c : natural := 23; -- select input for MAR
constant ctrl_adr_bp_en_c : natural := 24; -- mem addr output select, 0:MAR, 1:bypass
constant ctrl_adr_ivec_oe_c : natural := 25; -- output IRQ if 1, else output PC
constant ctrl_adr_mar_wr_c : natural := 26; -- write MAR
-- memory interface --
constant ctrl_mem_wr_c : natural := 28; -- write to memory
constant ctrl_mem_rd_c : natural := 29; -- read from memory
constant ctrl_mem_wr_c : natural := 27; -- write to memory
constant ctrl_mem_rd_c : natural := 28; -- read from memory
-- bus size --
constant ctrl_width_c : natural := 30; -- control bus size
constant ctrl_width_c : natural := 29; -- control bus size
 
-- Condition Codes ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
323,28 → 327,29
component neo430_top
generic (
-- general configuration --
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 32kB (default=4kB)
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 28kB (default=2kB)
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 32kB (default=4kB)
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 28kB (default=2kB)
-- additional configuration --
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
-- module configuration --
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true)
WB32_USE : boolean := true; -- implement WB32 unit? (default=true)
WDT_USE : boolean := true; -- implement WDT? (default=true)
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true)
TIMER_USE : boolean := true; -- implement timer? (default=true)
UART_USE : boolean := true; -- implement UART? (default=true)
CRC_USE : boolean := true; -- implement CRC unit? (default=true)
CFU_USE : boolean := false; -- implement custom functions unit? (default=false)
PWM_USE : boolean := true; -- implement PWM controller? (default=true)
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true)
SPI_USE : boolean := true; -- implement SPI? (default=true)
TRNG_USE : boolean := false; -- implement TRNG? (default=false)
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true)
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true)
WB32_USE : boolean := true; -- implement WB32 unit? (default=true)
WDT_USE : boolean := true; -- implement WDT? (default=true)
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true)
TIMER_USE : boolean := true; -- implement timer? (default=true)
UART_USE : boolean := true; -- implement UART? (default=true)
CRC_USE : boolean := true; -- implement CRC unit? (default=true)
CFU_USE : boolean := false; -- implement custom functions unit? (default=false)
PWM_USE : boolean := true; -- implement PWM controller? (default=true)
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true)
SPI_USE : boolean := true; -- implement SPI? (default=true)
TRNG_USE : boolean := false; -- implement TRNG? (default=false)
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true)
FREQ_GEN_USE : boolean := true; -- implement FREQ_GEN? (default=true)
-- boot configuration --
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true)
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false)
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true)
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false)
);
port (
-- global control --
355,6 → 360,8
gpio_i : in std_ulogic_vector(15 downto 0); -- parallel input
-- pwm channels --
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
-- timer frequency generator --
timer_fg_o : out std_ulogic; -- programmable frequency output
-- serial com --
uart_txd_o : out std_ulogic; -- UART send data
uart_rxd_i : in std_ulogic; -- UART receive data
647,6 → 654,8
-- clock generator --
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- frequency generator --
timer_fg_o : out std_ulogic; -- programmable frequency output
-- interrupt --
irq_o : out std_ulogic -- interrupt request
);
786,28 → 795,28
component neo430_sysconfig
generic (
-- general configuration --
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes
-- additional configuration --
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
-- module configuration --
MULDIV_USE : boolean := true; -- implement multiplier/divider unit?
WB32_USE : boolean := true; -- implement WB32 unit?
WDT_USE : boolean := true; -- implement WDT?
GPIO_USE : boolean := true; -- implement GPIO unit?
TIMER_USE : boolean := true; -- implement timer?
UART_USE : boolean := true; -- implement UART?
CRC_USE : boolean := true; -- implement CRC unit?
CFU_USE : boolean := true; -- implement CF unit?
PWM_USE : boolean := true; -- implement PWM controller?
TWI_USE : boolean := true; -- implement TWI?
SPI_USE : boolean := true; -- implement SPI?
TRNG_USE : boolean := true; -- implement TRNG?
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true)
MULDIV_USE : boolean := true; -- implement multiplier/divider unit?
WB32_USE : boolean := true; -- implement WB32 unit?
WDT_USE : boolean := true; -- implement WDT?
GPIO_USE : boolean := true; -- implement GPIO unit?
TIMER_USE : boolean := true; -- implement timer?
UART_USE : boolean := true; -- implement UART?
CRC_USE : boolean := true; -- implement CRC unit?
CFU_USE : boolean := true; -- implement CF unit?
PWM_USE : boolean := true; -- implement PWM controller?
TWI_USE : boolean := true; -- implement TWI?
SPI_USE : boolean := true; -- implement SPI?
TRNG_USE : boolean := true; -- implement TRNG?
EXIRQ_USE : boolean := true; -- implement EXIRQ?
-- boot configuration --
BOOTLD_USE : boolean := true; -- implement and use bootloader?
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory?
BOOTLD_USE : boolean := true; -- implement and use bootloader?
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory?
);
port (
clk_i : in std_ulogic; -- global clock line
/neo430/rtl/core/neo430_reg_file.vhd
99,8 → 99,7
sreg <= (others => '0'); -- here we NEED a true hardware reset
elsif rising_edge(clk_i) then
-- physical status register --
if ((ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_sr_c) and
(ctrl_i(ctrl_rf_ad_c) = '0') and (ctrl_i(ctrl_rf_wb_en_c) = '1')) then -- only write in reg-addr-mode!
if ((ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c) = reg_sr_c) and (ctrl_i(ctrl_rf_wb_en_c) = '1')) then -- valid SREG write
sreg(sreg_c_c) <= in_data(sreg_c_c);
sreg(sreg_z_c) <= in_data(sreg_z_c);
sreg(sreg_n_c) <= in_data(sreg_n_c);
173,7 → 172,7
rf_write: process(clk_i)
begin
if rising_edge(clk_i) then
if (ctrl_i(ctrl_rf_ad_c) = '0') and (ctrl_i(ctrl_rf_wb_en_c) = '1') then -- only write in reg-addr-mode!
if (ctrl_i(ctrl_rf_wb_en_c) = '1') then -- valid register file write
reg_file(to_integer(unsigned(ctrl_i(ctrl_rf_adr3_c downto ctrl_rf_adr0_c)))) <= in_data;
end if;
end if;
/neo430/rtl/core/neo430_sysconfig.vhd
45,28 → 45,28
entity neo430_sysconfig is
generic (
-- general configuration --
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes
-- additional configuration --
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
-- module configuration --
MULDIV_USE : boolean := true; -- implement multiplier/divider unit?
WB32_USE : boolean := true; -- implement WB32 unit?
WDT_USE : boolean := true; -- implement WDT?
GPIO_USE : boolean := true; -- implement GPIO unit?
TIMER_USE : boolean := true; -- implement timer?
UART_USE : boolean := true; -- implement UART?
CRC_USE : boolean := true; -- implement CRC unit?
CFU_USE : boolean := true; -- implement CF unit?
PWM_USE : boolean := true; -- implement PWM controller?
TWI_USE : boolean := true; -- implement TWI?
SPI_USE : boolean := true; -- implement SPI?
TRNG_USE : boolean := true; -- implement TRNG?
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true)
MULDIV_USE : boolean := true; -- implement multiplier/divider unit?
WB32_USE : boolean := true; -- implement WB32 unit?
WDT_USE : boolean := true; -- implement WDT?
GPIO_USE : boolean := true; -- implement GPIO unit?
TIMER_USE : boolean := true; -- implement timer?
UART_USE : boolean := true; -- implement UART?
CRC_USE : boolean := true; -- implement CRC unit?
CFU_USE : boolean := true; -- implement CF unit?
PWM_USE : boolean := true; -- implement PWM controller?
TWI_USE : boolean := true; -- implement TWI?
SPI_USE : boolean := true; -- implement SPI?
TRNG_USE : boolean := true; -- implement TRNG?
EXIRQ_USE : boolean := true; -- implement EXIRQ?
-- boot configuration --
BOOTLD_USE : boolean := true; -- implement and use bootloader?
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory?
BOOTLD_USE : boolean := true; -- implement and use bootloader?
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory?
);
port (
clk_i : in std_ulogic; -- global clock line
113,7 → 113,7
-- CPUID0: HW version --
sysinfo_mem(0) <= hw_version_c; -- HW version
 
-- CPUID1: System setup (features) --
-- CPUID1: System setup (available HW units / IO / peripheral devices) --
sysinfo_mem(1)(00) <= bool_to_ulogic_f(MULDIV_USE); -- MULDIV present?
sysinfo_mem(1)(01) <= bool_to_ulogic_f(WB32_USE); -- WB32 present?
sysinfo_mem(1)(02) <= bool_to_ulogic_f(WDT_USE); -- WDT present?
120,7 → 120,7
sysinfo_mem(1)(03) <= bool_to_ulogic_f(GPIO_USE); -- GPIO present?
sysinfo_mem(1)(04) <= bool_to_ulogic_f(TIMER_USE); -- TIMER present?
sysinfo_mem(1)(05) <= bool_to_ulogic_f(UART_USE); -- UART present?
sysinfo_mem(1)(06) <= bool_to_ulogic_f(use_xalu_c); -- extended ALU functions present?
sysinfo_mem(1)(06) <= '0'; -- reserved
sysinfo_mem(1)(07) <= bool_to_ulogic_f(BOOTLD_USE); -- bootloader present?
sysinfo_mem(1)(08) <= bool_to_ulogic_f(IMEM_AS_ROM); -- IMEM implemented as true ROM?
sysinfo_mem(1)(09) <= bool_to_ulogic_f(CRC_USE); -- CRC present?
/neo430/rtl/core/neo430_timer.vhd
5,6 → 5,8
-- # counter value reaches the programmable threshold an interrupt can be triggered. Optionally, #
-- # the counter can be automatically reset when reaching the threshold value to restart counting. #
-- # Configure THRES before enabling the timer to prevent false interrupt requests. #
-- # The time also features a numerically controlled oscillator (NCO) for generating arbitrary #
-- # frequency outputs: f_out = ((f_cpu / nco_prsc) * tuning_word[15:0]) / 2^17 #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
56,6 → 58,8
-- clock generator --
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- frequency generator --
timer_fg_o : out std_ulogic; -- programmable frequency output
-- interrupt --
irq_o : out std_ulogic -- interrupt request
);
68,13 → 72,17
constant lo_abb_c : natural := index_size_f(timer_size_c); -- low address boundary bit
 
-- control reg bits --
constant ctrl_en_bit_c : natural := 0; -- r/w: timer enable
constant ctrl_arst_bit_c : natural := 1; -- r/w: auto reset on match
constant ctrl_irq_en_bit_c : natural := 2; -- r/w: interrupt enable
constant ctrl_run_c : natural := 3; -- r/w: start/stop timer
constant ctrl_prsc0_bit_c : natural := 4; -- r/w: prescaler select bit 0
constant ctrl_prsc1_bit_c : natural := 5; -- r/w: prescaler select bit 1
constant ctrl_prsc2_bit_c : natural := 6; -- r/w: prescaler select bit 2
constant ctrl_en_c : natural := 0; -- r/w: timer enable
constant ctrl_arst_c : natural := 1; -- r/w: auto reset on match
constant ctrl_irq_en_c : natural := 2; -- r/w: interrupt enable
constant ctrl_run_c : natural := 3; -- r/w: start/stop timer
constant ctrl_prsc0_c : natural := 4; -- r/w: prescaler select bit 0
constant ctrl_prsc1_c : natural := 5; -- r/w: prescaler select bit 1
constant ctrl_prsc2_c : natural := 6; -- r/w: prescaler select bit 2
constant ctrl_nco_en_c : natural := 7; -- r/w: enable NCO
constant ctrl_nco_prsc0_c : natural := 8; -- r/w: NCO prescaler select bit 0
constant ctrl_nco_prsc1_c : natural := 9; -- r/w: NCO prescaler select bit 1
constant ctrl_nco_prsc2_c : natural := 10; -- r/w: NCO prescaler select bit 2
 
-- access control --
signal acc_en : std_ulogic; -- module access enable
84,7 → 92,7
-- timer regs --
signal cnt : std_ulogic_vector(15 downto 0); -- r/-: counter register
signal thres : std_ulogic_vector(15 downto 0); -- r/w: threshold register
signal ctrl : std_ulogic_vector(06 downto 0); -- r/w: control register
signal ctrl : std_ulogic_vector(10 downto 0); -- r/w: control register
 
-- prescaler clock generator --
signal prsc_tick : std_ulogic;
94,6 → 102,11
signal irq_fire : std_ulogic;
signal irq_fire_ff : std_ulogic;
 
-- nco --
signal nco_prsc_tick : std_ulogic;
signal nco_tuning_word : std_ulogic_vector(15 downto 0); -- -/w: NCO tuning word
signal nco_phase_accu : std_ulogic_vector(16 downto 0);
 
begin
 
-- Access Control -----------------------------------------------------------
113,36 → 126,43
thres <= data_i;
end if;
if (addr = timer_ctrl_addr_c) then
ctrl(ctrl_en_bit_c) <= data_i(ctrl_en_bit_c);
ctrl(ctrl_arst_bit_c) <= data_i(ctrl_arst_bit_c);
ctrl(ctrl_irq_en_bit_c) <= data_i(ctrl_irq_en_bit_c);
ctrl(ctrl_run_c) <= data_i(ctrl_run_c);
ctrl(ctrl_prsc0_bit_c) <= data_i(ctrl_prsc0_bit_c);
ctrl(ctrl_prsc1_bit_c) <= data_i(ctrl_prsc1_bit_c);
ctrl(ctrl_prsc2_bit_c) <= data_i(ctrl_prsc2_bit_c);
ctrl(ctrl_en_c) <= data_i(ctrl_en_c);
ctrl(ctrl_arst_c) <= data_i(ctrl_arst_c);
ctrl(ctrl_irq_en_c) <= data_i(ctrl_irq_en_c);
ctrl(ctrl_run_c) <= data_i(ctrl_run_c);
ctrl(ctrl_prsc0_c) <= data_i(ctrl_prsc0_c);
ctrl(ctrl_prsc1_c) <= data_i(ctrl_prsc1_c);
ctrl(ctrl_prsc2_c) <= data_i(ctrl_prsc2_c);
ctrl(ctrl_nco_en_c) <= data_i(ctrl_nco_en_c);
ctrl(ctrl_nco_prsc0_c) <= data_i(ctrl_nco_prsc0_c);
ctrl(ctrl_nco_prsc1_c) <= data_i(ctrl_nco_prsc1_c);
ctrl(ctrl_nco_prsc2_c) <= data_i(ctrl_nco_prsc2_c);
end if;
if (addr = timer_nco_addr_c) then
nco_tuning_word <= data_i;
end if;
end if;
end if;
end process wr_access;
 
-- enable external clock generator --
clkgen_en_o <= ctrl(ctrl_en_bit_c);
clkgen_en_o <= ctrl(ctrl_en_c);
 
 
-- Counter update -----------------------------------------------------------
-- -----------------------------------------------------------------------------
counter_update: process(clk_i)
timer_cnt_core: process(clk_i)
begin
if rising_edge(clk_i) then
-- clock_en buffer --
prsc_tick <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_bit_c downto ctrl_prsc0_bit_c))));
-- clock_enable buffer --
prsc_tick <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c))));
-- irq edge detector --
irq_fire_ff <= irq_fire;
-- counter update --
if (ctrl(ctrl_en_bit_c) = '0') then -- timer disabled
if (ctrl(ctrl_en_c) = '0') then -- timer disabled
cnt <= (others => '0');
elsif (ctrl(ctrl_run_c) = '1') then -- timer enabled, but is it started?
if (match = '1') and (ctrl(ctrl_arst_bit_c) = '1') then -- threshold match and auto reset?
if (match = '1') and (ctrl(ctrl_arst_c) = '1') then -- threshold match and auto reset?
cnt <= (others => '0');
elsif (match = '0') and (prsc_tick = '1') then -- count++
cnt <= std_ulogic_vector(unsigned(cnt) + 1);
149,18 → 169,37
end if;
end if;
end if;
end process counter_update;
end process timer_cnt_core;
 
-- match --
match <= '1' when (cnt = thres) else '0';
 
-- interrupt line --
irq_fire <= match and ctrl(ctrl_en_bit_c) and ctrl(ctrl_irq_en_bit_c) and ctrl(ctrl_run_c);
irq_fire <= match and ctrl(ctrl_en_c) and ctrl(ctrl_irq_en_c) and ctrl(ctrl_run_c);
 
-- edge detector --
irq_o <= irq_fire and (not irq_fire_ff);
 
 
-- NCO core (number controlled oscillator) ----------------------------------
-- -----------------------------------------------------------------------------
nco_core: process(clk_i)
begin
if rising_edge(clk_i) then
-- NCO clock enable --
nco_prsc_tick <= clkgen_i(to_integer(unsigned(ctrl(ctrl_nco_prsc2_c downto ctrl_nco_prsc0_c))));
-- phase accu --
if ((ctrl(ctrl_en_c) and ctrl(ctrl_nco_en_c)) = '0') then -- disabled
nco_phase_accu <= (others => '0');
elsif (nco_prsc_tick = '1') then -- enabled; wait for clock enable tick
nco_phase_accu <= std_ulogic_vector(unsigned(nco_phase_accu) + unsigned('0' & nco_tuning_word));
end if;
-- output --
timer_fg_o <= nco_phase_accu(nco_phase_accu'left); -- MSB (carry_out) is output
end if;
end process nco_core;
 
 
-- Read access --------------------------------------------------------------
-- -----------------------------------------------------------------------------
rd_access: process(clk_i)
169,17 → 208,23
data_o <= (others => '0');
if (rden_i = '1') and (acc_en = '1') then
if (addr = timer_ctrl_addr_c) then
data_o(ctrl_en_bit_c) <= ctrl(ctrl_en_bit_c);
data_o(ctrl_arst_bit_c) <= ctrl(ctrl_arst_bit_c);
data_o(ctrl_irq_en_bit_c) <= ctrl(ctrl_irq_en_bit_c);
data_o(ctrl_run_c) <= ctrl(ctrl_run_c);
data_o(ctrl_prsc0_bit_c) <= ctrl(ctrl_prsc0_bit_c);
data_o(ctrl_prsc1_bit_c) <= ctrl(ctrl_prsc1_bit_c);
data_o(ctrl_prsc2_bit_c) <= ctrl(ctrl_prsc2_bit_c);
data_o(ctrl_en_c) <= ctrl(ctrl_en_c);
data_o(ctrl_arst_c) <= ctrl(ctrl_arst_c);
data_o(ctrl_irq_en_c) <= ctrl(ctrl_irq_en_c);
data_o(ctrl_run_c) <= ctrl(ctrl_run_c);
data_o(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c);
data_o(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c);
data_o(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c);
data_o(ctrl_nco_en_c) <= ctrl(ctrl_nco_en_c);
data_o(ctrl_nco_prsc0_c) <= ctrl(ctrl_nco_prsc0_c);
data_o(ctrl_nco_prsc1_c) <= ctrl(ctrl_nco_prsc1_c);
data_o(ctrl_nco_prsc2_c) <= ctrl(ctrl_nco_prsc2_c);
elsif (addr = timer_cnt_addr_c) then
data_o <= cnt;
else -- timer_thres_addr_c
else--if (addr = timer_thres_addr_c) then
data_o <= thres;
-- else -- timer_nco_addr_c
-- data_o <= nco_tuning_word;
end if;
end if;
end if;
/neo430/rtl/core/neo430_top.vhd
16,7 → 16,7
-- # - Optional 16-bit multiplier/divider unit (MULDIV) #
-- # - Optional 16-bit IN and 16-bit OUT GPIO port with pin-change interrupt (GPIO) #
-- # - Optional 32-bit Wishbone interface (WB32) #
-- # - Optional High precision timer (TIMER) #
-- # - Optional High precision timer (TIMER) with frequency generator output #
-- # - Optional Universal Asynchronous Receiver and Transmitter (UART) #
-- # - Optional Serial Peripheral Interface (SPI) #
-- # - Optional Internal ROM for bootloader (BOOTLD) #
26,7 → 26,7
-- # - Optional Pulse Width Modulation controller (PWM) #
-- # - Optional Two Wire Serial Interface (TWI) #
-- # - Optional True Random Number Generator (TRNG) #
-- # - OPtional External Interrupts Controller (EXIRQ) #
-- # - Optional External Interrupts Controller (EXIRQ) #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
66,32 → 66,32
library neo430;
use neo430.neo430_package.all;
 
 
entity neo430_top is
generic (
-- general configuration --
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 48kB (default=4kB)
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 12kB (default=2kB)
CLOCK_SPEED : natural := 100000000; -- main clock in Hz
IMEM_SIZE : natural := 4*1024; -- internal IMEM size in bytes, max 48kB (default=4kB)
DMEM_SIZE : natural := 2*1024; -- internal DMEM size in bytes, max 12kB (default=2kB)
-- additional configuration --
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
USER_CODE : std_ulogic_vector(15 downto 0) := x"0000"; -- custom user code
-- module configuration --
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true)
WB32_USE : boolean := true; -- implement WB32 unit? (default=true)
WDT_USE : boolean := true; -- implement WDT? (default=true)
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true)
TIMER_USE : boolean := true; -- implement timer? (default=true)
UART_USE : boolean := true; -- implement UART? (default=true)
CRC_USE : boolean := true; -- implement CRC unit? (default=true)
CFU_USE : boolean := false; -- implement custom functions unit? (default=false)
PWM_USE : boolean := true; -- implement PWM controller? (default=true)
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true)
SPI_USE : boolean := true; -- implement SPI? (default=true)
TRNG_USE : boolean := false; -- implement TRNG? (default=false)
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true)
MULDIV_USE : boolean := true; -- implement multiplier/divider unit? (default=true)
WB32_USE : boolean := true; -- implement WB32 unit? (default=true)
WDT_USE : boolean := true; -- implement WDT? (default=true)
GPIO_USE : boolean := true; -- implement GPIO unit? (default=true)
TIMER_USE : boolean := true; -- implement timer? (default=true)
UART_USE : boolean := true; -- implement UART? (default=true)
CRC_USE : boolean := true; -- implement CRC unit? (default=true)
CFU_USE : boolean := false; -- implement custom functions unit? (default=false)
PWM_USE : boolean := true; -- implement PWM controller? (default=true)
TWI_USE : boolean := true; -- implement two wire serial interface? (default=true)
SPI_USE : boolean := true; -- implement SPI? (default=true)
TRNG_USE : boolean := false; -- implement TRNG? (default=false)
EXIRQ_USE : boolean := true; -- implement EXIRQ? (default=true)
FREQ_GEN_USE : boolean := true; -- implement FREQ_GEN? (default=true)
-- boot configuration --
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true)
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false)
BOOTLD_USE : boolean := true; -- implement and use bootloader? (default=true)
IMEM_AS_ROM : boolean := false -- implement IMEM as read-only memory? (default=false)
);
port (
-- global control --
102,6 → 102,8
gpio_i : in std_ulogic_vector(15 downto 0); -- parallel input
-- pwm channels --
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
-- timer frequency generator --
timer_fg_o : out std_ulogic; -- programmable frequency output
-- serial com --
uart_txd_o : out std_ulogic; -- UART send data
uart_rxd_i : in std_ulogic; -- UART receive data
121,32 → 123,31
wb_cyc_o : out std_ulogic; -- valid cycle
wb_ack_i : in std_ulogic; -- transfer acknowledge
-- external interrupts --
ext_irq_i : in std_ulogic_vector(07 downto 0); -- external interrupt request lines
ext_irq_i : in std_ulogic_vector(07 downto 0); -- external interrupt request lines (active HI)
ext_ack_o : out std_ulogic_vector(07 downto 0) -- external interrupt request acknowledges
);
end neo430_top;
 
 
architecture neo430_top_rtl of neo430_top is
 
-- generators --
signal rst_i_sync0 : std_ulogic;
signal rst_i_sync1 : std_ulogic;
signal rst_gen : std_ulogic_vector(03 downto 0) := (others => '0'); -- perform reset on bitstream upload
signal ext_rst : std_ulogic;
signal sys_rst : std_ulogic;
signal wdt_rst : std_ulogic;
signal clk_div : std_ulogic_vector(11 downto 0);
signal clk_div_ff : std_ulogic_vector(11 downto 0);
signal clk_gen : std_ulogic_vector(07 downto 0);
signal timer_cg_en : std_ulogic;
signal uart_cg_en : std_ulogic;
signal spi_cg_en : std_ulogic;
signal wdt_cg_en : std_ulogic;
signal pwm_cg_en : std_ulogic;
signal twi_cg_en : std_ulogic;
signal cfu_cg_en : std_ulogic;
 
signal rst_i_sync0 : std_ulogic;
signal rst_i_sync1 : std_ulogic;
signal rst_gen : std_ulogic_vector(03 downto 0) := (others => '0'); -- perform reset on bitstream upload
signal ext_rst : std_ulogic;
signal sys_rst : std_ulogic;
signal wdt_rst : std_ulogic;
signal clk_div : std_ulogic_vector(11 downto 0);
signal clk_div_ff : std_ulogic_vector(11 downto 0);
signal clk_gen : std_ulogic_vector(07 downto 0);
signal timer_cg_en : std_ulogic;
signal uart_cg_en : std_ulogic;
signal spi_cg_en : std_ulogic;
signal wdt_cg_en : std_ulogic;
signal pwm_cg_en : std_ulogic;
signal twi_cg_en : std_ulogic;
signal cfu_cg_en : std_ulogic;
type cpu_bus_t is record
rd_en : std_ulogic;
wr_en : std_ulogic_vector(01 downto 0);
181,16 → 182,16
signal sysconfig_rdata : std_ulogic_vector(15 downto 0);
 
-- interrupt system --
signal irq : std_ulogic_vector(03 downto 0);
signal irq_ack : std_ulogic_vector(03 downto 0);
signal timer_irq : std_ulogic;
signal uart_irq : std_ulogic;
signal spi_irq : std_ulogic;
signal twi_irq : std_ulogic;
signal gpio_irq : std_ulogic;
signal xirq_sync0 : std_ulogic;
signal xirq_sync1 : std_ulogic;
signal ext_irq : std_ulogic;
signal irq : std_ulogic_vector(03 downto 0);
signal irq_ack : std_ulogic_vector(03 downto 0);
signal timer_irq : std_ulogic;
signal uart_irq : std_ulogic;
signal spi_irq : std_ulogic;
signal twi_irq : std_ulogic;
signal gpio_irq : std_ulogic;
signal xirq_sync0 : std_ulogic;
signal xirq_sync1 : std_ulogic;
signal ext_irq : std_ulogic;
 
-- misc --
signal imem_up_en : std_ulogic;
526,6 → 527,8
-- clock generator --
clkgen_en_o => timer_cg_en, -- enable clock generator
clkgen_i => clk_gen,
-- frequency generator --
timer_fg_o => timer_fg_o, -- programmable frequency output
-- interrupt --
irq_o => timer_irq -- interrupt request
);
536,6 → 539,7
timer_rdata <= (others => '0');
timer_irq <= '0';
timer_cg_en <= '0';
timer_fg_o <= '0';
end generate;
 
 
749,28 → 753,28
neo430_sysconfig_inst: neo430_sysconfig
generic map (
-- general configuration --
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes
CLOCK_SPEED => CLOCK_SPEED, -- main clock in Hz
IMEM_SIZE => IMEM_SIZE, -- internal IMEM size in bytes
DMEM_SIZE => DMEM_SIZE, -- internal DMEM size in bytes
-- additional configuration --
USER_CODE => USER_CODE, -- custom user code
USER_CODE => USER_CODE, -- custom user code
-- module configuration --
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit?
WB32_USE => WB32_USE, -- implement WB32 unit?
WDT_USE => WDT_USE, -- implement WDT?
GPIO_USE => GPIO_USE, -- implement GPIO unit?
TIMER_USE => TIMER_USE, -- implement timer?
UART_USE => UART_USE, -- implement UART?
CRC_USE => CRC_USE, -- implement CRC unit?
CFU_USE => CFU_USE, -- implement CFU?
PWM_USE => PWM_USE, -- implement PWM?
TWI_USE => TWI_USE, -- implement TWI?
SPI_USE => SPI_USE, -- implement SPI?
TRNG_USE => TRNG_USE, -- implement TRNG?
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ?
MULDIV_USE => MULDIV_USE, -- implement multiplier/divider unit?
WB32_USE => WB32_USE, -- implement WB32 unit?
WDT_USE => WDT_USE, -- implement WDT?
GPIO_USE => GPIO_USE, -- implement GPIO unit?
TIMER_USE => TIMER_USE, -- implement timer?
UART_USE => UART_USE, -- implement UART?
CRC_USE => CRC_USE, -- implement CRC unit?
CFU_USE => CFU_USE, -- implement CFU?
PWM_USE => PWM_USE, -- implement PWM?
TWI_USE => TWI_USE, -- implement TWI?
SPI_USE => SPI_USE, -- implement SPI?
TRNG_USE => TRNG_USE, -- implement TRNG?
EXIRQ_USE => EXIRQ_USE, -- implement EXIRQ?
-- boot configuration --
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader?
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory?
BOOTLD_USE => BOOTLD_USE, -- implement and use bootloader?
IMEM_AS_ROM => IMEM_AS_ROM -- implement IMEM as read-only memory?
)
port map (
clk_i => clk_i, -- global clock line
/neo430/rtl/core/neo430_uart.vhd
258,7 → 258,7
data_o(ctrl_uart_tx_busy_c) <= uart_tx_busy;
else -- uart_rtx_addr_c
data_o(data_rx_avail_c) <= uart_rx_avail(0);
data_o(07 downto 0) <= uart_rx_reg;
data_o(07 downto 0) <= uart_rx_reg;
end if;
end if;
end if;
/neo430/rtl/top_templates/neo430_test.vhd
103,6 → 103,8
gpio_i => x"0000", -- parallel input
-- pwm channels --
pwm_o => open, -- pwm channels
-- timer frequency generator --
timer_fg_o => open, -- programmable frequency output
-- serial com --
uart_txd_o => uart_txd_o, -- UART send data
uart_rxd_i => uart_rxd_i, -- UART receive data
/neo430/rtl/top_templates/neo430_top_avm.vhd
74,6 → 74,8
gpio_i : in std_logic_vector(15 downto 0); -- parallel input
-- pwm channels --
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels
-- timer frequency generator --
timer_fg_o : out std_logic; -- programmable frequency output
-- UART --
uart_txd_o : out std_logic; -- UART send data
uart_rxd_i : in std_logic; -- UART receive data
140,6 → 142,7
signal spi_cs_o_int : std_ulogic_vector(05 downto 0);
signal irq_i_int : std_ulogic_vector(07 downto 0);
signal irq_ack_o_int : std_ulogic_vector(07 downto 0);
signal timer_fg_o_int : std_ulogic;
constant usrcode_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(USER_CODE);
 
-- misc --
224,6 → 227,7
spi_mosi_o <= std_logic(spi_mosi_o_int);
spi_cs_o <= std_logic_vector(spi_cs_o_int);
ext_ack_o <= std_logic_vector(irq_ack_o_int);
timer_fg_o <= std_logic(timer_fg_o_int);
 
 
-- Wishbone-to-Avalon Bridge ------------------------------------------------
/neo430/rtl/top_templates/neo430_top_axi4lite.vhd
71,6 → 71,8
gpio_i : in std_logic_vector(15 downto 0); -- parallel input
-- pwm channels --
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels
-- timer frequency generator --
timer_fg_o : out std_logic; -- programmable frequency output
-- UART --
uart_txd_o : out std_logic; -- UART send data
uart_rxd_i : in std_logic; -- UART receive data
142,6 → 144,7
signal spi_cs_o_int : std_ulogic_vector(05 downto 0);
signal irq_i_int : std_ulogic_vector(07 downto 0);
signal irq_ack_o_int : std_ulogic_vector(07 downto 0);
signal timer_fg_o_int : std_ulogic;
constant usrcode_c : std_ulogic_vector(15 downto 0) := std_ulogic_vector(USER_CODE);
 
-- AXI arbiter --
229,6 → 232,7
spi_mosi_o <= std_logic(spi_mosi_o_int);
spi_cs_o <= std_logic_vector(spi_cs_o_int);
ext_ack_o <= std_logic_vector(irq_ack_o_int);
timer_fg_o <= std_logic(timer_fg_o_int);
 
 
-- Wishbone-to-AXI4-Lite-compatible Bridge ----------------------------------
/neo430/rtl/top_templates/neo430_top_std_logic.vhd
74,6 → 74,8
gpio_i : in std_logic_vector(15 downto 0); -- parallel input
-- pwm channels --
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels
-- timer frequency generator --
timer_fg_o : out std_logic; -- programmable frequency output
-- serial com --
uart_txd_o : out std_logic; -- UART send data
uart_rxd_i : in std_logic; -- UART receive data
123,6 → 125,7
signal wb_stb_o_int : std_ulogic;
signal wb_cyc_o_int : std_ulogic;
signal wb_ack_i_int : std_ulogic;
signal timer_fg_o_int : std_ulogic;
 
begin
 
211,6 → 214,7
wb_stb_o <= std_logic(wb_stb_o_int);
wb_cyc_o <= std_logic(wb_cyc_o_int);
ext_ack_o <= std_logic_vector(irq_ack_o_int);
timer_fg_o <= std_logic(timer_fg_o_int);
 
 
end neo430_top_std_logic_rtl;
/neo430/sim/ISIM/neo430_tb.wcfg
12,15 → 12,15
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="1434752233333fs"></ZoomStartTime>
<ZoomEndTime time="1434861633334fs"></ZoomEndTime>
<Cursor1Time time="1430885000000fs"></Cursor1Time>
<ZoomStartTime time="1895335974026fs"></ZoomStartTime>
<ZoomEndTime time="1918047142859fs"></ZoomEndTime>
<Cursor1Time time="1928055455000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="167"></NameColumnWidth>
<ValueColumnWidth column_width="61"></ValueColumnWidth>
<NameColumnWidth column_width="175"></NameColumnWidth>
<ValueColumnWidth column_width="58"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="135" />
<WVObjectSize size="152" />
<wvobject type="divider" fp_name="divider6">
<obj_property name="label">Global</obj_property>
<obj_property name="DisplayName">label</obj_property>
84,8 → 84,8
<obj_property name="ObjectShortName">state</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_cpu_inst/neo430_control_inst/ctrl_o" type="array">
<obj_property name="ElementShortName">ctrl_o[29:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[29:0]</obj_property>
<obj_property name="ElementShortName">ctrl_o[28:0]</obj_property>
<obj_property name="ObjectShortName">ctrl_o[28:0]</obj_property>
</wvobject>
<wvobject type="divider" fp_name="divider9">
<obj_property name="label">CPU - RF</obj_property>
129,6 → 129,7
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_cpu_inst/neo430_addr_gen_inst/mem_addr_o" type="array">
<obj_property name="ElementShortName">mem_addr_o[15:0]</obj_property>
<obj_property name="ObjectShortName">mem_addr_o[15:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_cpu_inst/neo430_addr_gen_inst/irq_sel_i" type="array">
<obj_property name="ElementShortName">irq_sel_i[1:0]</obj_property>
142,6 → 143,10
<obj_property name="label">CPU - BUS Interface</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_cpu_inst/dio_swap" type="logic">
<obj_property name="ElementShortName">dio_swap</obj_property>
<obj_property name="ObjectShortName">dio_swap</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/io_acc" type="logic">
<obj_property name="ElementShortName">io_acc</obj_property>
<obj_property name="ObjectShortName">io_acc</obj_property>
203,14 → 208,30
<obj_property name="ElementShortName">uart_tx_done</obj_property>
<obj_property name="ObjectShortName">uart_tx_done</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_uart_inst_true/neo430_uart_inst/uart_rx_avail" type="logic">
<obj_property name="ElementShortName">uart_rx_avail</obj_property>
<obj_property name="ObjectShortName">uart_rx_avail</obj_property>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_uart_inst_true/neo430_uart_inst/uart_rx_busy" type="logic">
<obj_property name="ElementShortName">uart_rx_busy</obj_property>
<obj_property name="ObjectShortName">uart_rx_busy</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_uart_inst_true/neo430_uart_inst/uart_rx_busy_ff" type="logic">
<obj_property name="ElementShortName">uart_rx_busy_ff</obj_property>
<obj_property name="ObjectShortName">uart_rx_busy_ff</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_uart_inst_true/neo430_uart_inst/uart_rx_avail" type="array">
<obj_property name="ElementShortName">uart_rx_avail[1:0]</obj_property>
<obj_property name="ObjectShortName">uart_rx_avail[1:0]</obj_property>
</wvobject>
<wvobject type="divider" fp_name="divider44">
<obj_property name="label">IO: SPI</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/data_i" type="array">
<obj_property name="ElementShortName">data_i[15:0]</obj_property>
<obj_property name="ObjectShortName">data_i[15:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/data_o" type="array">
<obj_property name="ElementShortName">data_o[15:0]</obj_property>
<obj_property name="ObjectShortName">data_o[15:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/spi_sclk_o" type="logic">
<obj_property name="ElementShortName">spi_sclk_o</obj_property>
<obj_property name="ObjectShortName">spi_sclk_o</obj_property>
224,13 → 245,21
<obj_property name="ObjectShortName">spi_miso_i</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/spi_cs_o" type="array">
<obj_property name="ElementShortName">spi_cs_o[7:0]</obj_property>
<obj_property name="ObjectShortName">spi_cs_o[7:0]</obj_property>
<obj_property name="ElementShortName">spi_cs_o[5:0]</obj_property>
<obj_property name="ObjectShortName">spi_cs_o[5:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/spi_irq_o" type="logic">
<obj_property name="ElementShortName">spi_irq_o</obj_property>
<obj_property name="ObjectShortName">spi_irq_o</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/wr_en" type="logic">
<obj_property name="ElementShortName">wr_en</obj_property>
<obj_property name="ObjectShortName">wr_en</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/rd_en" type="logic">
<obj_property name="ElementShortName">rd_en</obj_property>
<obj_property name="ObjectShortName">rd_en</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/ctrl" type="array">
<obj_property name="ElementShortName">ctrl[15:0]</obj_property>
<obj_property name="ObjectShortName">ctrl[15:0]</obj_property>
239,13 → 268,29
<obj_property name="ElementShortName">spi_busy</obj_property>
<obj_property name="ObjectShortName">spi_busy</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/spi_state0" type="logic">
<obj_property name="ElementShortName">spi_state0</obj_property>
<obj_property name="ObjectShortName">spi_state0</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/spi_state1" type="logic">
<obj_property name="ElementShortName">spi_state1</obj_property>
<obj_property name="ObjectShortName">spi_state1</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/spi_rtx_sreg" type="array">
<obj_property name="ElementShortName">spi_rtx_sreg[15:0]</obj_property>
<obj_property name="ObjectShortName">spi_rtx_sreg[15:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_spi_inst_true/neo430_spi_inst/spi_bitcnt" type="array">
<obj_property name="ElementShortName">spi_bitcnt[4:0]</obj_property>
<obj_property name="ObjectShortName">spi_bitcnt[4:0]</obj_property>
</wvobject>
<wvobject type="divider" fp_name="divider22">
<obj_property name="label">IO: Timer</obj_property>
<obj_property name="DisplayName">label</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/ctrl" type="array">
<obj_property name="ElementShortName">ctrl[5:0]</obj_property>
<obj_property name="ObjectShortName">ctrl[5:0]</obj_property>
<obj_property name="ElementShortName">ctrl[10:0]</obj_property>
<obj_property name="ObjectShortName">ctrl[10:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/thres" type="array">
<obj_property name="ElementShortName">thres[15:0]</obj_property>
252,6 → 297,10
<obj_property name="ObjectShortName">thres[15:0]</obj_property>
<obj_property name="Radix">HEXRADIX</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/prsc_tick" type="logic">
<obj_property name="ElementShortName">prsc_tick</obj_property>
<obj_property name="ObjectShortName">prsc_tick</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/cnt" type="array">
<obj_property name="ElementShortName">cnt[15:0]</obj_property>
<obj_property name="ObjectShortName">cnt[15:0]</obj_property>
260,6 → 309,22
<obj_property name="ElementShortName">irq_o</obj_property>
<obj_property name="ObjectShortName">irq_o</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/nco_prsc_tick" type="logic">
<obj_property name="ElementShortName">nco_prsc_tick</obj_property>
<obj_property name="ObjectShortName">nco_prsc_tick</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/nco_tuning_word" type="array">
<obj_property name="ElementShortName">nco_tuning_word[15:0]</obj_property>
<obj_property name="ObjectShortName">nco_tuning_word[15:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/nco_phase_accu" type="array">
<obj_property name="ElementShortName">nco_phase_accu[16:0]</obj_property>
<obj_property name="ObjectShortName">nco_phase_accu[16:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_timer_inst_true/neo430_timer_inst/timer_fg_o" type="logic">
<obj_property name="ElementShortName">timer_fg_o</obj_property>
<obj_property name="ObjectShortName">timer_fg_o</obj_property>
</wvobject>
<wvobject type="divider" fp_name="divider22">
<obj_property name="label">IO: GPIO</obj_property>
<obj_property name="DisplayName">label</obj_property>
383,6 → 448,14
<obj_property name="ElementShortName">resy[15:0]</obj_property>
<obj_property name="ObjectShortName">resy[15:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_muldiv_inst_true/neo430_muldiv_inst/func_rst" type="logic">
<obj_property name="ElementShortName">func_rst</obj_property>
<obj_property name="ObjectShortName">func_rst</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_muldiv_inst_true/neo430_muldiv_inst/ctrl_state" type="logic">
<obj_property name="ElementShortName">ctrl_state</obj_property>
<obj_property name="ObjectShortName">ctrl_state</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_muldiv_inst_true/neo430_muldiv_inst/operation" type="logic">
<obj_property name="ElementShortName">operation</obj_property>
<obj_property name="ObjectShortName">operation</obj_property>
484,8 → 557,8
<obj_property name="Radix">BINARYRADIX</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_twi_inst_true/neo430_twi_inst/ctrl" type="array">
<obj_property name="ElementShortName">ctrl[7:0]</obj_property>
<obj_property name="ObjectShortName">ctrl[7:0]</obj_property>
<obj_property name="ElementShortName">ctrl[8:0]</obj_property>
<obj_property name="ObjectShortName">ctrl[8:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_twi_inst_true/neo430_twi_inst/twi_bitcnt" type="array">
<obj_property name="ElementShortName">twi_bitcnt[3:0]</obj_property>
563,10 → 636,6
<obj_property name="ElementShortName">sw_trig</obj_property>
<obj_property name="ObjectShortName">sw_trig</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_exirq_inst_true/neo430_exirq_inst/sw_trig_src" type="array">
<obj_property name="ElementShortName">sw_trig_src[2:0]</obj_property>
<obj_property name="ObjectShortName">sw_trig_src[2:0]</obj_property>
</wvobject>
<wvobject fp_name="/neo430_tb/neo430_top_inst/neo430_exirq_inst_true/neo430_exirq_inst/sw_irq" type="array">
<obj_property name="ElementShortName">sw_irq[7:0]</obj_property>
<obj_property name="ObjectShortName">sw_irq[7:0]</obj_property>
/neo430/sim/neo430_tb.vhd
103,28 → 103,28
neo430_top_inst: neo430_top
generic map (
-- general configuration --
CLOCK_SPEED => f_clk_c, -- main clock in Hz
IMEM_SIZE => 4*1024, -- internal IMEM size in bytes, max 48kB (default=4kB)
DMEM_SIZE => 2*1024, -- internal DMEM size in bytes, max 12kB (default=2kB)
CLOCK_SPEED => f_clk_c, -- main clock in Hz
IMEM_SIZE => 4*1024, -- internal IMEM size in bytes, max 48kB (default=4kB)
DMEM_SIZE => 2*1024, -- internal DMEM size in bytes, max 12kB (default=2kB)
-- additional configuration --
USER_CODE => x"4788", -- custom user code
USER_CODE => x"4788", -- custom user code
-- module configuration --
MULDIV_USE => true, -- implement multiplier/divider unit? (default=true)
WB32_USE => true, -- implement WB32 unit? (default=true)
WDT_USE => true, -- implement WBT? (default=true)
GPIO_USE => true, -- implement GPIO unit? (default=true)
TIMER_USE => true, -- implement timer? (default=true)
UART_USE => true, -- implement UART? (default=true)
CRC_USE => true, -- implement CRC unit? (default=true)
CFU_USE => false, -- implement custom functions unit? (default=false)
PWM_USE => true, -- implement PWM controller? (default=true)
TWI_USE => true, -- implement two wire serial interface? (default=true)
SPI_USE => true, -- implement SPI? (default=true)
TRNG_USE => false, -- implement TRNG? (default=false) - CANNOT BE SIMULATED!
EXIRQ_USE => true, -- implement EXIRQ? (default=true)
MULDIV_USE => true, -- implement multiplier/divider unit? (default=true)
WB32_USE => true, -- implement WB32 unit? (default=true)
WDT_USE => true, -- implement WBT? (default=true)
GPIO_USE => true, -- implement GPIO unit? (default=true)
TIMER_USE => true, -- implement timer? (default=true)
UART_USE => true, -- implement UART? (default=true)
CRC_USE => true, -- implement CRC unit? (default=true)
CFU_USE => false, -- implement custom functions unit? (default=false)
PWM_USE => true, -- implement PWM controller? (default=true)
TWI_USE => true, -- implement two wire serial interface? (default=true)
SPI_USE => true, -- implement SPI? (default=true)
TRNG_USE => false, -- implement TRNG? (default=false) - CANNOT BE SIMULATED!
EXIRQ_USE => true, -- implement EXIRQ? (default=true)
-- boot configuration --
BOOTLD_USE => false, -- implement and use bootloader? (default=true)
IMEM_AS_ROM => false -- implement IMEM as read-only memory? (default=false)
BOOTLD_USE => false, -- implement and use bootloader? (default=true)
IMEM_AS_ROM => false -- implement IMEM as read-only memory? (default=false)
)
port map (
-- global control --
131,10 → 131,12
clk_i => clk_gen, -- global clock, rising edge
rst_i => rst_gen, -- global reset, async, low-active
-- gpio --
gpio_o => open, -- parallel output
gpio_i => x"0000", -- parallel input
gpio_o => open, -- parallel output
gpio_i => x"0000", -- parallel input
-- pwm channels --
pwm_o => open, -- pwm channels
pwm_o => open, -- pwm channels
-- timer frequency generator --
timer_fg_o => open, -- programmable frequency output
-- serial com --
uart_txd_o => uart_txd, -- UART send data
uart_rxd_i => uart_txd, -- UART receive data
/neo430/sw/bootloader/bootloader.c
139,15 → 139,15
// disable EXIRQ
EXIRQ_CT = 0;
 
// init GPIO
GPIO_IRQMASK = 0; // no pin change interrupt please, thanks
neo430_gpio_port_set(1<<STATUS_LED); // activate status LED, clear all others
 
// init interrupt vectors
IRQVEC_TIMER = (uint16_t)(&timer_irq_handler); // timer match
//IRQVEC_EXT = 0; // unused
//IRQVEC_SERIAL = 0; // unused
 
// init GPIO
GPIO_IRQMASK = 0; // no pin change interrupt please, thanks
neo430_gpio_port_set(1<<STATUS_LED); // activate status LED, clear all others
 
// set Baud rate & init UART control register:
// enable UART, no IRQs
neo430_uart_setup(BAUD_RATE);
159,6 → 159,7
 
// Timeout counter: init timer, irq tick @ ~1Hz (prescaler = 4096)
// THR = f_main / (1Hz + 4096) -1
TMR_NCO = 0; // disable frequency generator
TMR_CT = 0; // reset timer
//uint32_t clock = CLOCKSPEED_32bit >> 14; // divide by 4096
TMR_THRES = (CLOCKSPEED_HI << 2) -1; // "fake" ;D
290,7 → 291,7
"h: Help\n"
"r: Restart\n"
"u: Upload\n"
"p: Program\n"
"p: Prog\n"
"e: Execute");
}
 
/neo430/sw/example/coremark/core_portme.c
79,7 → 79,7
or other system parameters - e.g. reading the current value of cpu cycles counter.
*/
void stop_time(void) {
neo430_timer_stop();
neo430_timer_pause();
//GETMYTIME(&stop_time_val );
}
/* Function : get_time
135,7 → 135,7
(1<<TMR_CT_ARST) | // auto-reset on match
(1<<TMR_CT_IRQ) | // interrupt enable
(0<<TMR_CT_RUN); // timer not running yet
neo430_timer_config_period(NEO430_TIMER_F);
neo430_timer_config_freq(NEO430_TIMER_F);
 
neo430_printf("NEO430: clock speed : %n Hz\n", CLOCKSPEED_32bit);
neo430_printf("NEO430: timer THRES : %u\n", TMR_THRES);
/neo430/sw/example/exirq_test/main.c
86,7 → 86,7
exirq_config.address[7] = (uint16_t)(&ext_irq_ch7_handler);
 
// only enable the actually used IRQ channels
exirq_config.enable = 0b10001111;
exirq_config.enable = 0b10001111; // each bit represents the according channel
 
// program configuration and activate EXIRQ controller
neo430_exirq_config(exirq_config);
/neo430/sw/example/hw_analysis/main.c
113,10 → 113,6
neo430_printf("- SPI: ");
print_state(ft & (1<<SYS_SPI_EN));
 
// XALIU
neo430_printf("- Extended ALU Ops.: ");
print_state(ft & (1<<SYS_XALU_EN));
 
// Bootloader installed
neo430_printf("- Internal Bootloader: ");
print_state(ft & (1<<SYS_BTLD_EN));
/neo430/sw/example/muldiv_test/main.c
70,7 → 70,7
// multiply test
prod_ref = (uint32_t)a * (uint32_t)b;
prod = neo430_umul32(a, b);
neo430_printf("UNSIGNED %u: %u * %u = %n vs ref. %n\n", i, a, b, prod, prod_ref);
neo430_printf("UNSIGNED %u: %u * %u = P: %n vs ref. P: %n\n", i, a, b, prod, prod_ref);
 
// division test
if (b == 0) // dont divide by zero
78,7 → 78,7
quot_ref = a / b;
rem_ref = a % b;
quot = neo430_umoddiv16(&rem, a, b);
neo430_printf("UNSIGNED %u: %u / %u = %u & %u vs ref. %u & %u\n", i, a, b, quot, rem, quot_ref, rem_ref);
neo430_printf("UNSIGNED %u: %u / %u = Q: %u & R: %u vs ref. Q: %u & R: %u\n", i, a, b, quot, rem, quot_ref, rem_ref);
 
 
// get "random" operands
91,12 → 91,12
squot_ref = sa / sb;
srem_ref = sa % sb;
squot = neo430_moddiv16(&srem, sa, sb);
neo430_printf("SIGNED %u: %i / %i = %i & %i vs ref. %i & %i\n", i, sa, sb, squot, srem, squot_ref, srem_ref);
neo430_printf("SIGNED %u: %i / %i = Q: %i & R: %i vs ref. Q: %i & R: %i\n", i, sa, sb, squot, srem, squot_ref, srem_ref);
 
// multiply test - signed
sprod_ref = (int32_t)sa * (int32_t)sb;
sprod = neo430_mul32(sa, sb);
neo430_printf("SIGNED %u: %i * %i = %l vs ref. %l\n", i, sa, sb, sprod, sprod_ref);
neo430_printf("SIGNED %u: %i * %i = P: %l vs ref. P: %l\n", i, sa, sb, sprod, sprod_ref);
 
 
// all correct?
/neo430/sw/example/nested_irqs/main.c
83,7 → 83,7
 
// configure timer frequency
neo430_timer_disable();
if (neo430_timer_config_period(1000)) // 1kHz to increment every 1ms
if (neo430_timer_config_freq(1000)) // 1kHz to increment every 1ms
neo430_uart_br_print("Invalid TIMER frequency!\n");
 
neo430_printf("THR: %x, CTR: %x\n", TMR_THRES, TMR_CT);
/neo430/sw/example/timer_simple/main.c
76,7 → 76,7
 
// configure timer frequency
neo430_timer_disable();
if (neo430_timer_config_period(BLINK_FREQ))
if (neo430_timer_config_freq(BLINK_FREQ))
neo430_uart_br_print("Invalid TIMER frequency!\n");
 
TMR_CT |= (1<<TMR_CT_EN) | (1<<TMR_CT_ARST) | (1<<TMR_CT_IRQ) | (1<<TMR_CT_RUN); // enable timer, auto-reset, irq enabled, timer start
84,11 → 84,26
// enable global IRQs
neo430_eint();
 
// do something else...
while (1) {
neo430_sleep(); // go to power down mode
 
// test frequency generator
neo430_timer_nco_enable();
uint32_t nco_target_frequency = 0, nco_real_frequency;
 
while(1) {
neo430_uart_br_print("Target freq.: 0x");
neo430_uart_print_hex_dword(nco_target_frequency);
 
nco_real_frequency = neo430_timer_nco_set(nco_target_frequency);
 
neo430_uart_br_print(", Real freq.: 0x");
neo430_uart_print_hex_dword(nco_real_frequency);
neo430_uart_br_print("\n");
 
nco_target_frequency++; // go through all possible frequencies
neo430_cpu_delay_ms(250); // wait 250ms
}
 
 
return 0;
}
 
/neo430/sw/lib/neo430/include/neo430.h
86,18 → 86,27
// ----------------------------------------------------------------------------
// Unsigned Multiplier/Divider Unit (MULDIV)
// ----------------------------------------------------------------------------
#define MULDIV_OPA (*(REG16 0xFF80)) // -/w: operand A (dividend or factor1)
#define MULDIV_OPB_DIV (*(REG16 0xFF82)) // -/w: operand B (divisor) for division
#define MULDIV_OPB_MUL (*(REG16 0xFF84)) // -/w: operand B (factor2) for multiplication
//#define reserved (*(REG16 0xFF86))
//#define reserved (*(REG16 0xFF88))
//#define reserved (*(REG16 0xFF8A))
#define MULDIV_RESX (*(ROM16 0xFF8C)) // r/-: quotient or product low word
#define MULDIV_RESY (*(ROM16 0xFF8E)) // r/-: remainder or product high word
#define MULDIV_R32bit (*(ROM32 (&MULDIV_RESX))) // r/-: read result as 32-bit data word
#define MULDIV_OPA_CTRL (*(REG16 0xFF80)) // -/w: operand A (dividend or factor1) / function config
#define MULDIV_OPB (*(REG16 0xFF82)) // -/w: operand B (factor2) for multiplication
#define MULDIV_RESX (*(ROM16 0xFF84)) // r/-: quotient or product low word
#define MULDIV_RESY (*(ROM16 0xFF86)) // r/-: remainder or product high word
#define MULDIV_R32bit (*(ROM32 (&MULDIV_RESX))) // r/-: read result as 32-bit data word
 
// function config bits
#define MULDIV_CONFIG_MUL ((uint16_t)(0b01 << 0))
#define MULDIV_CONFIG_DIV ((uint16_t)(0b10 << 0))
 
 
// ----------------------------------------------------------------------------
// reserved
// ----------------------------------------------------------------------------
//#define reserved (*(REG16 0xFF88)) // -/-: reserved
//#define reserved (*(REG16 0xFF8A)) // -/-: reserved
//#define reserved (*(REG16 0xFF8E)) // -/-: reserved
//#define reserved (*(REG16 0xFF8E)) // -/-: reserved
 
 
// ----------------------------------------------------------------------------
// Wishbone Bus Adapter (WB32)
// ----------------------------------------------------------------------------
#define WB32_CT (*(REG16 0xFF90)) // r/w: control register
198,10 → 207,10
// ----------------------------------------------------------------------------
// General Purpose Inputs/Outputs (GPIO)
// ----------------------------------------------------------------------------
//#define reserved (*(REG16 0xFFA8)) // reserved
#define GPIO_IRQMASK (*(REG16 0xFFAA)) // -/w: irq mask register
#define GPIO_INPUT (*(ROM16 0xFFAC)) // r/-: parallel input
#define GPIO_OUTPUT (*(REG16 0xFFAE)) // r/w: parallel output
#define GPIO_IRQMASK (*(REG16 0xFFA8)) // -/w: irq mask register
#define GPIO_INPUT (*(ROM16 0xFFAA)) // r/-: parallel input
#define GPIO_OUTPUT (*(REG16 0xFFAC)) // r/w: parallel output
//#define reserved (*(REG16 0xFFAE)) // reserved
 
 
// ----------------------------------------------------------------------------
210,16 → 219,20
#define TMR_CT (*(REG16 0xFFB0)) // r/w: control register
#define TMR_CNT (*(ROM16 0xFFB2)) // r/-: counter register
#define TMR_THRES (*(REG16 0xFFB4)) // r/w: threshold register
//#define reserved (*(REG16 0xFFB6))
#define TMR_NCO (*(REG16 0xFFB6)) // -/w: frequency generator
 
// Timer control register
#define TMR_CT_EN 0 // r/w: timer enable
#define TMR_CT_ARST 1 // r/w: auto reset on match
#define TMR_CT_IRQ 2 // r/w: interrupt enable
#define TMR_CT_RUN 3 // r/w: start/stop timer
#define TMR_CT_PRSC0 4 // r/w: clock prescaler select bit 0
#define TMR_CT_PRSC1 5 // r/w: clock prescaler select bit 1
#define TMR_CT_PRSC2 6 // r/w: clock prescaler select bit 2
#define TMR_CT_EN 0 // r/w: timer unit global enable
#define TMR_CT_ARST 1 // r/w: auto reset on match
#define TMR_CT_IRQ 2 // r/w: interrupt enable
#define TMR_CT_RUN 3 // r/w: start/stop timer
#define TMR_CT_PRSC0 4 // r/w: clock prescaler select bit 0
#define TMR_CT_PRSC1 5 // r/w: clock prescaler select bit 1
#define TMR_CT_PRSC2 6 // r/w: clock prescaler select bit 2
#define TMR_CT_NCO_EN 7 // r/w: NCO enable
#define TMR_CT_NCO_PRSC0 8 // r/w: NCO prescaler select bit 0
#define TMR_CT_NCO_PRSC1 9 // r/w: NCO prescaler select bit 1
#define TMR_CT_NCO_PRSC2 10 // r/w: NCO prescaler select bit 2
 
// Timer clock prescaler select:
#define TMR_PRSC_2 0 // CLK/2
388,14 → 401,13
#define EXIRQ_CT (*(REG16 0xFFEE)) // r/w: control register
 
// EXIRQ control register
#define EXIRQ_CT_SRC0 0 // r/-: IRQ source bit 0
#define EXIRQ_CT_SRC1 1 // r/-: IRQ source bit 1
#define EXIRQ_CT_SRC2 2 // r/-: IRQ source bit 2
#define EXIRQ_CT_SEL0 0 // r/w: IRQ source bit 0 / SW_IRQ select / ACK select
#define EXIRQ_CT_SEL1 1 // r/w: IRQ source bit 1 / SW_IRQ select / ACK select
#define EXIRQ_CT_SEL2 2 // r/w: IRQ source bit 2 / SW_IRQ select / ACK select
#define EXIRQ_CT_EN 3 // r/w: unit enable
#define EXIRQ_CT_SW_IRQ 4 // -/w: enable SW IRQ trigger, auto-clears
#define EXIRQ_CT_SW_IRQ_SEL0 5 // -/w: SW IRQ select bit 0, read as zero
#define EXIRQ_CT_SW_IRQ_SEL1 6 // -/w: SW IRQ select bit 1, read as zero
#define EXIRQ_CT_SW_IRQ_SEL2 7 // -/w: SW IRQ select bit 2, read as zero
#define EXIRQ_CT_SW_IRQ 4 // -/w: use irq_sel as SW IRQ trigger, auto-clears
#define EXIRQ_CT_ACK_IRQ 5 // -/w: use irq_sel as ACK select, auto-clears
// ...
#define EXIRQ_CT_IRQ0_EN 8 // r/w: Enable IRQ channel 0
#define EXIRQ_CT_IRQ1_EN 9 // r/w: Enable IRQ channel 1
#define EXIRQ_CT_IRQ2_EN 10 // r/w: Enable IRQ channel 2
432,22 → 444,22
#define CLOCKSPEED_32bit (*(ROM32 (&CLOCKSPEED_LO))) // r/-: clock speed (in Hz)
 
// SYS features
#define SYS_MULDIV_EN 0 // r/-: MULDIV synthesized
#define SYS_WB32_EN 1 // r/-: WB32 synthesized
#define SYS_WDT_EN 2 // r/-: WDT synthesized
#define SYS_GPIO_EN 3 // r/-: GPIO synthesized
#define SYS_TIMER_EN 4 // r/-: TIMER synthesized
#define SYS_UART_EN 5 // r/-: UART synthesized
#define SYS_XALU_EN 6 // r/-: Extended ALU operations synthesized
#define SYS_BTLD_EN 7 // r/-: Bootloader installed and enabled
#define SYS_IROM_EN 8 // r/-: Implement IMEM as true ROM
#define SYS_CRC_EN 9 // r/-: CRC synthesized
#define SYS_CFU_EN 10 // r/-: CFU synthesized
#define SYS_PWM_EN 11 // r/-: PWM controller synthesized
#define SYS_TWI_EN 12 // r/-: TWI synthesized
#define SYS_SPI_EN 13 // r/-: SPI synthesized
#define SYS_TRNG_EN 14 // r/-: TRNG synthesized
#define SYS_EXIRQ_EN 15 // r/-: EXIRQ synthesized
#define SYS_MULDIV_EN 0 // r/-: MULDIV synthesized
#define SYS_WB32_EN 1 // r/-: WB32 synthesized
#define SYS_WDT_EN 2 // r/-: WDT synthesized
#define SYS_GPIO_EN 3 // r/-: GPIO synthesized
#define SYS_TIMER_EN 4 // r/-: TIMER synthesized
#define SYS_UART_EN 5 // r/-: UART synthesized
//#define SYS_???_EN 6 // r/-: reserved
#define SYS_BTLD_EN 7 // r/-: Bootloader installed and enabled
#define SYS_IROM_EN 8 // r/-: Implement IMEM as true ROM
#define SYS_CRC_EN 9 // r/-: CRC synthesized
#define SYS_CFU_EN 10 // r/-: CFU synthesized
#define SYS_PWM_EN 11 // r/-: PWM controller synthesized
#define SYS_TWI_EN 12 // r/-: TWI synthesized
#define SYS_SPI_EN 13 // r/-: SPI synthesized
#define SYS_TRNG_EN 14 // r/-: TRNG synthesized
#define SYS_EXIRQ_EN 15 // r/-: EXIRQ synthesized
 
 
// ----------------------------------------------------------------------------
/neo430/sw/lib/neo430/include/neo430_exirq.h
45,10 → 45,9
static uint16_t neo430_exirq_vectors[8] __attribute__((unused)); // do not ouput a warning when this variable is unused
 
// prototypes
void neo430_exirq_enable(void); // activate EXIRQ controller
void neo430_exirq_disable(void); // deactivate EXIRQ controller
void neo430_exirq_config(struct neo430_exirq_config_t config); // configure EXIRQ controller
void neo430_exirq_sw_irq(uint8_t id); // trigger interrupt by software
void __attribute__((__interrupt__)) exirq_irq_handler(void); // EXIRQ IRQ handler
void neo430_exirq_enable(void); // activate EXIRQ controller
void neo430_exirq_disable(void); // deactivate EXIRQ controller
void neo430_exirq_config(struct neo430_exirq_config_t config); // configure EXIRQ controller
void neo430_exirq_sw_irq(uint8_t id); // trigger interrupt by software
 
#endif // neo430_exirq_h
/neo430/sw/lib/neo430/include/neo430_timer.h
1,5 → 1,5
// #################################################################################################
// # < neo430_timer.h - Tim helper functions ;) > #
// # < neo430_timer.h - Timer helper functions > #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
36,12 → 36,13
#define neo430_timer_h
 
// prototypes
void neo430_timer_enable(void); // enable timer unit
void neo430_timer_disable(void); // disable timer unit
void neo430_timer_stop(void); // stop timer
void neo430_timer_reset(void); // reset timer
void neo430_timer_run(void); // run timer
void neo430_timer_pause(void); // pause timer
uint8_t neo430_timer_config_period(uint32_t f_timer); // configure (irq) frequency
void neo430_timer_enable(void); // enable timer unit
void neo430_timer_disable(void); // disable timer unit
void neo430_timer_run(void); // run timer
void neo430_timer_pause(void); // pause timer
uint8_t neo430_timer_config_freq(uint32_t f_timer); // configure timer frequency
void neo430_timer_nco_enable(void); // enable programmable frequency output
void neo430_timer_nco_disable(void); // disable programmable frequency output
uint32_t neo430_timer_nco_set(uint32_t frequency); // set programmable output frequency, returns actual output frequency
 
#endif // neo430_timer_h
/neo430/sw/lib/neo430/include/neo430_uart.h
39,28 → 39,28
#include <stdarg.h>
 
// prototypes
void neo430_uart_setup(uint32_t baudrate); // activate and configure UART
void neo430_uart_disable(void); // deactivate uart
uint32_t neo430_uart_get_baudrate(void); // compute actual baudrate using UART's current configuration
void neo430_uart_putc(char c); // send single char
char neo430_uart_getc(void); // wait and read single char
uint16_t neo430_uart_char_received(void); // test if a char has been received
char neo430_uart_char_read(void); // get a received char
void neo430_uart_print(char *s); // print a text string
void neo430_uart_br_print(char *s); // print a text string and allow easy line breaks
uint16_t neo430_uart_scan(char *buffer, uint16_t max_size, uint16_t echo); // read several chars into buffer
void neo430_uart_print_hex_char(char c); // print byte as a hex char
void neo430_uart_print_hex_byte(uint8_t b); // print byte as 2 hex numbers
void neo430_uart_print_hex_word(uint16_t w); // print word as 4 hex numbers
void neo430_uart_print_hex_dword(uint32_t dw); // print double word as 8 hex numbers
void neo430_uart_print_bin_byte(uint8_t b); // print byte in binary form
void neo430_uart_print_bin_word(uint16_t w); // print word in binary form
void neo430_uart_print_bin_dword(uint32_t dw); // print double word in binary form
void neo430_itoa(uint32_t x, const uint16_t leading_zeros, char *res); // convert double word to decimal number
void neo430_printf(char *format, ...); // print format string
void neo430_fp_print(int32_t num, const uint16_t fp); // print fixed point number
uint32_t neo430_hexstr_to_uint(char *buffer, uint8_t length); // convert hex string to number
void neo430_uart_bs(uint16_t n); // return terminal cursor n positions
void neo430_uart_print_fpf_32(int32_t num, const int fpf_c, const int num_frac_digits_c); // print fixed-point number
void neo430_uart_setup(uint32_t baudrate); // activate and configure UART
void neo430_uart_disable(void); // deactivate uart
uint32_t neo430_uart_get_baudrate(void); // compute actual baudrate using UART's current configuration
void neo430_uart_putc(char c); // send single char
char neo430_uart_getc(void); // wait and read single char
uint16_t neo430_uart_char_received(void); // test if a char has been received
char neo430_uart_char_read(void); // get a received char
void neo430_uart_print(char *s); // print a text string
void neo430_uart_br_print(char *s); // print a text string and allow easy line breaks
uint16_t neo430_uart_scan(char *buffer, uint16_t max_size, uint16_t echo); // read several chars into buffer
void neo430_uart_print_hex_char(char c); // print byte as a hex char
void neo430_uart_print_hex_byte(uint8_t b); // print byte as 2 hex numbers
void neo430_uart_print_hex_word(uint16_t w); // print word as 4 hex numbers
void neo430_uart_print_hex_dword(uint32_t dw); // print double word as 8 hex numbers
void neo430_uart_print_hex_qword(uint64_t qw); // print quad word as 16 hex numbers
void neo430_uart_print_bin_byte(uint8_t b); // print byte in binary form
void neo430_uart_print_bin_word(uint16_t w); // print word in binary form
void neo430_uart_print_bin_dword(uint32_t dw); // print double word in binary form
void neo430_itoa(uint32_t x, uint16_t leading_zeros, char *res); // convert double word to decimal number
void neo430_printf(char *format, ...); // print format string
uint32_t neo430_hexstr_to_uint(char *buffer, uint8_t length); // convert hex string to number
void neo430_uart_bs(uint16_t n); // return terminal cursor n positions
void neo430_uart_print_fpf_32(int32_t num, uint16_t fpf_c, uint16_t num_frac_digits_c); // print fixed-point number
 
#endif // neo430_uart_h
/neo430/sw/lib/neo430/source/neo430_exirq.c
35,7 → 35,10
#include "neo430.h"
#include "neo430_exirq.h"
 
// Private function prototypes
static void __attribute__((__interrupt__)) _exirq_irq_handler_(void);
 
 
/* ------------------------------------------------------------
* INFO Enable external interrupts controller
* ------------------------------------------------------------ */
74,7 → 77,7
neo430_exirq_vectors[7] = config.address[7];
 
// set correct CPU external interrupts request handler address
IRQVEC_EXT = (uint16_t)(&exirq_irq_handler);
IRQVEC_EXT = (uint16_t)(&_exirq_irq_handler_);
 
// configure channel enables
uint16_t enable = (uint16_t)config.enable;
91,7 → 94,8
uint16_t irq_sel = (uint16_t)(id & 7);
 
// apply sw irq enable bit and according irq select
EXIRQ_CT |= (1<<EXIRQ_CT_SW_IRQ) | (irq_sel<<EXIRQ_CT_SW_IRQ_SEL0);
uint16_t exirq_ctrl = EXIRQ_CT & (~(0b111 << EXIRQ_CT_SEL0)); // clear IRQ src output
EXIRQ_CT = exirq_ctrl | (1<<EXIRQ_CT_SW_IRQ) | (irq_sel<<EXIRQ_CT_SEL0);
}
 
 
99,9 → 103,12
* INFO Actual external interrupts controller IRQ handler
* INFO This function is automatically installed
* ------------------------------------------------------------ */
void __attribute__((__interrupt__)) exirq_irq_handler(void) {
static void __attribute__((__interrupt__)) _exirq_irq_handler_(void) {
 
uint16_t src = EXIRQ_CT & (7<<EXIRQ_CT_SRC0); // get IRQ source
register uint16_t exirq_ctrl = EXIRQ_CT;
 
EXIRQ_CT = exirq_ctrl | (1 << EXIRQ_CT_ACK_IRQ); // ACK IRQ
 
register uint16_t src = exirq_ctrl & (0b111 << EXIRQ_CT_SEL0); // get IRQ source
neo430_call_address(neo430_exirq_vectors[src]); // call according handler
}
 
/neo430/sw/lib/neo430/source/neo430_muldiv.c
35,7 → 35,11
#include "neo430.h"
#include "neo430_muldiv.h"
 
// private prototypes
static inline void neo430_muldiv_set_mul(void);
static inline void neo430_muldiv_set_div(void);
 
 
/* ------------------------------------------------------------
* INFO Unsigned 16x16-bit multiplication
* PARAM 16-bit factor a
44,8 → 48,9
* ------------------------------------------------------------ */
uint32_t neo430_umul32(uint16_t a, uint16_t b) {
 
MULDIV_OPA = a;
MULDIV_OPB_MUL = b;
neo430_muldiv_set_mul();
MULDIV_OPA_CTRL = a;
MULDIV_OPB = b;
 
// HW processing delay
asm volatile("nop");
72,8 → 77,9
if (b < 0)
b = 0 - b;
 
MULDIV_OPA = (uint16_t)a;
MULDIV_OPB_MUL = (uint16_t)b;
neo430_muldiv_set_mul();
MULDIV_OPA_CTRL = (uint16_t)a;
MULDIV_OPB = (uint16_t)b;
 
// HW processing delay
asm volatile("nop");
97,8 → 103,9
* ------------------------------------------------------------ */
uint16_t neo430_udiv16(uint16_t dividend, uint16_t divisor) {
 
MULDIV_OPA = dividend;
MULDIV_OPB_DIV = divisor;
neo430_muldiv_set_div();
MULDIV_OPA_CTRL = dividend;
MULDIV_OPB = divisor;
 
// HW processing delay
asm volatile("nop");
123,8 → 130,9
if (divisor < 0)
divisor = 0 - divisor;
 
MULDIV_OPA = (uint16_t)dividend;
MULDIV_OPB_DIV = (uint16_t)divisor;
neo430_muldiv_set_div();
MULDIV_OPA_CTRL = (uint16_t)dividend;
MULDIV_OPB = (uint16_t)divisor;
 
// HW processing delay
asm volatile("nop");
148,8 → 156,9
* ------------------------------------------------------------ */
uint16_t neo430_umod16(uint16_t dividend, uint16_t divisor) {
 
MULDIV_OPA = dividend;
MULDIV_OPB_DIV = divisor;
neo430_muldiv_set_div();
MULDIV_OPA_CTRL = dividend;
MULDIV_OPB = divisor;
 
// HW processing delay
asm volatile("nop");
176,8 → 185,9
if (divisor < 0)
divisor = 0 - divisor;
 
MULDIV_OPA = (uint16_t)dividend_int;
MULDIV_OPB_DIV = (uint16_t)divisor;
neo430_muldiv_set_div();
MULDIV_OPA_CTRL = (uint16_t)dividend_int;
MULDIV_OPB = (uint16_t)divisor;
 
// HW processing delay
asm volatile("nop");
202,8 → 212,9
* ------------------------------------------------------------ */
uint16_t neo430_umoddiv16(uint16_t *remainder, uint16_t dividend, uint16_t divisor) {
 
MULDIV_OPA = dividend;
MULDIV_OPB_DIV = divisor;
neo430_muldiv_set_div();
MULDIV_OPA_CTRL = dividend;
MULDIV_OPB = divisor;
 
// HW processing delay
asm volatile("nop");
233,8 → 244,9
if (divisor < 0)
divisor = 0 - divisor;
 
MULDIV_OPA = (uint16_t)dividend_int;
MULDIV_OPB_DIV = (uint16_t)divisor;
neo430_muldiv_set_div();
MULDIV_OPA_CTRL = (uint16_t)dividend_int;
MULDIV_OPB = (uint16_t)divisor;
 
// HW processing delay
asm volatile("nop");
254,3 → 266,24
else
return q;
}
 
 
/* ------------------------------------------------------------
* INFO Configure MULDIV for multiplication
* ------------------------------------------------------------ */
static inline void neo430_muldiv_set_mul(void) {
 
MULDIV_OPA_CTRL = 0x0000; // reset
MULDIV_OPA_CTRL = MULDIV_CONFIG_MUL; // configure for multiplication
}
 
 
/* ------------------------------------------------------------
* INFO Configure MULDIV for division
* ------------------------------------------------------------ */
static inline void neo430_muldiv_set_div(void) {
 
MULDIV_OPA_CTRL = 0x0000; // reset
MULDIV_OPA_CTRL = MULDIV_CONFIG_DIV; // configure for division
}
 
/neo430/sw/lib/neo430/source/neo430_timer.c
35,7 → 35,10
#include "neo430.h"
#include "neo430_timer.h"
 
// Private function prototypes
static uint32_t neo430_timer_nco_real_output(uint16_t tuning_word, uint16_t prsc_shift);
 
 
/* ------------------------------------------------------------
* INFO Activate Timer
* ------------------------------------------------------------ */
55,25 → 58,6
 
 
/* ------------------------------------------------------------
* INFO Stop Timer
* ------------------------------------------------------------ */
void neo430_timer_stop(void) {
 
TMR_CT &= ~(1<<TMR_CT_EN);
}
 
 
/* ------------------------------------------------------------
* INFO Reset Timer
* ------------------------------------------------------------ */
void neo430_timer_reset(void) {
 
neo430_timer_disable();
neo430_timer_enable();
}
 
 
/* ------------------------------------------------------------
* INFO Start Timer
* ------------------------------------------------------------ */
void neo430_timer_run(void) {
96,7 → 80,7
* PARAM Timer frequency in Hz (1Hz ... F_CPU/2)
* RETURN 0 if successful, !=0 if error
* ------------------------------------------------------------ */
uint8_t neo430_timer_config_period(uint32_t f_timer) {
uint8_t neo430_timer_config_freq(uint32_t f_timer) {
 
uint32_t clock = CLOCKSPEED_32bit;
uint32_t ticks = (clock / f_timer) >> 1; // divide by lowest prescaler (= f/2)
125,3 → 109,110
 
return 0;
}
 
 
/* ------------------------------------------------------------
* INFO Enable programmable frequency output (NCO)
* ------------------------------------------------------------ */
void neo430_timer_nco_enable(void) {
 
TMR_CT |= (1<<TMR_CT_NCO_EN);
}
 
 
/* ------------------------------------------------------------
* INFO Disable programmable frequency output (NCO)
* ------------------------------------------------------------ */
void neo430_timer_nco_disable(void) {
 
TMR_CT &= ~(1<<TMR_CT_NCO_EN);
}
 
 
/* ------------------------------------------------------------
* INFO Set frequency programmable frequency output
* INFO f_out = ((f_cpu / nco_prsc) * tuning_word[15:0]) / 2^17
* PARAM frequency: output frequency in Hz (no fractions possible here)
* RETURN the actual output frequency
* ------------------------------------------------------------ */
uint32_t neo430_timer_nco_set(uint32_t frequency) {
 
// tuning_word = (f_out * 2^17) / (f_cpu / nco_prsc)
 
uint32_t f_cpu = CLOCKSPEED_32bit;
 
int16_t i;
uint16_t prsc_shift = 12; // start with highest prescaler (4096 => 12)
 
if (frequency > (f_cpu/4)) {
return 0;
}
 
uint64_t freq_tmp;
uint32_t freq_real;
uint32_t freq_diff;
 
uint32_t freq_diff_best = 0xffffffff; // max
uint16_t tuning_word_best = 0;
uint16_t prsc_best = 0;
uint32_t freq_real_best = 0;
 
// check all possible prescaler
for(i=7; i>=0; i--) {
 
freq_tmp = (uint64_t)frequency;
freq_tmp = freq_tmp << (17 + prsc_shift); // multiply via bit shifts
freq_tmp = freq_tmp / f_cpu;
 
uint16_t tuning_word = (uint16_t)(freq_tmp);
 
// add 1 to tuning word (for rounding issues)
freq_real = neo430_timer_nco_real_output(tuning_word+1, prsc_shift);
 
freq_diff = freq_real - frequency;
if ((int32_t)freq_diff < 0) {
freq_diff = 0 - freq_diff;
}
 
// best result yet?
if (freq_diff < freq_diff_best) {
tuning_word_best = tuning_word;
prsc_best = i;
freq_diff_best = freq_diff;
freq_real_best = freq_real;
}
 
// compute next prescaler
if ((i == 5) || (i == 3)) {
prsc_shift = prsc_shift - 3;
}
else {
prsc_shift = prsc_shift - 1;
}
}
 
// write config to NCO
uint16_t timer_ctrl = TMR_CT;
timer_ctrl &= ~(0b111 << TMR_CT_NCO_PRSC0); // clear old prescaler config
TMR_CT = timer_ctrl | (prsc_best << TMR_CT_NCO_PRSC0); // set new prescaler config
TMR_NCO = tuning_word_best; // set timer's NCO tuning word
 
return freq_real_best;
}
 
 
/* ------------------------------------------------------------
* INFO Compute actual NCO output frequency based on tuning word and prescaler
* RETURN the actual output frequency in Hz
* ------------------------------------------------------------ */
static uint32_t neo430_timer_nco_real_output(uint16_t tuning_word, uint16_t prsc_shift) {
 
// f_out = ((f_cpu/nco_prsc) * tuning_word[15:0]) / 2^17
 
uint32_t f_cpu = CLOCKSPEED_32bit;
uint64_t f_out = (uint64_t)f_cpu;
f_out = f_out * tuning_word;
f_out = f_out >> (17 + prsc_shift); // divide by 2^17 * PRSC
 
return (uint32_t)f_out;
}
/neo430/sw/lib/neo430/source/neo430_uart.c
135,8 → 135,9
uint16_t d = 0;
while (1) {
d = UART_RTX;
if ((d & (1<<UART_RTX_AVAIL)) != 0) // char received?
if ((d & (1<<UART_RTX_AVAIL)) != 0) { // char received?
return (char)d;
}
}
}
 
170,8 → 171,9
void neo430_uart_print(char *s){
 
char c = 0;
while ((c = *s++))
while ((c = *s++)) {
neo430_uart_putc(c);
}
}
 
 
184,8 → 186,9
 
char c = 0;
while ((c = *s++)) {
if (c == '\n')
if (c == '\n') {
neo430_uart_putc('\r');
}
neo430_uart_putc(c);
}
}
280,6 → 283,17
 
 
/* ------------------------------------------------------------
* INFO Print 64-bit hexadecimal value (16 digits)
* PARAM uint64_t value to be printed
* ------------------------------------------------------------ */
void neo430_uart_print_hex_qword(uint64_t qw) {
 
neo430_uart_print_hex_dword((uint32_t)(qw >> 32));
neo430_uart_print_hex_dword((uint32_t)(qw >> 0));
}
 
 
/* ------------------------------------------------------------
* INFO Print 8-bit binary value (8 digits)
* PARAM uint8_t value to be printed
* ------------------------------------------------------------ */
296,7 → 310,7
 
 
/* ------------------------------------------------------------
* INFO Print 16-bit decimal value (16 digits)
* INFO Print 16-bit binary value (16 digits)
* PARAM uint16_t value to be printed
* ------------------------------------------------------------ */
void neo430_uart_print_bin_word(uint16_t w) {
307,7 → 321,7
 
 
/* ------------------------------------------------------------
* INFO Print 32-bit decimal value (32 digits)
* INFO Print 32-bit binary value (32 digits)
* PARAM uint32_t value to be printed
* ------------------------------------------------------------ */
void neo430_uart_print_bin_dword(uint32_t dw) {
324,9 → 338,9
* PARAM show #leading_zeros leading zeros
* PARAM pointer to array (11 elements!!!) to store conversion result string
* ------------------------------------------------------------ */
void neo430_itoa(uint32_t x, const uint16_t leading_zeros, char *res) {
void neo430_itoa(uint32_t x, uint16_t leading_zeros, char *res) {
 
static const char numbers[10] = "0123456789";
const char numbers[10] = "0123456789";
char buffer1[11];
uint16_t i, j;
 
433,36 → 447,6
 
 
/* ------------------------------------------------------------
* INFO Print fixed point number
* INFO HIGHLY EXPERIMENTAL!
* PARAM fixed point number (32-bit)
* PARAM number of fractional bits
* ------------------------------------------------------------ */
void neo430_fp_print(int32_t num, const uint16_t fp) {
 
char string_buf[11];
 
// print integer part
int32_t num_int = num;
 
if (num_int < (int32_t)0) {
num_int = -num_int;
neo430_uart_putc('-');
}
neo430_itoa((uint32_t)num_int >> fp, 0, string_buf);
neo430_uart_br_print(string_buf);
 
neo430_uart_putc('.');
 
// print fractional part (3 digits)
uint32_t frac_part = (uint32_t)(num_int & ((1<<fp)-1));
frac_part = (frac_part * 1000) / (1<<fp);
neo430_itoa(frac_part, 2, string_buf);
neo430_uart_br_print(string_buf);
}
 
 
/* ------------------------------------------------------------
* INFO Convert N hex chars into uint32
* PARAM Pointer to buffer with hex chars
* PARAM Number of hex chars to convert (1..8)
509,10 → 493,9
* PARAM fpf_c: Number of bin fractional bits in input (max 32)
* PARAM num_frac_digits_c: Number of fractional digits to show (max 8)
* ------------------------------------------------------------ */
void neo430_uart_print_fpf_32(int32_t num, const int fpf_c, const int num_frac_digits_c) {
void neo430_uart_print_fpf_32(int32_t num, uint16_t fpf_c, uint16_t num_frac_digits_c) {
 
char string_buf[11];
int i;
uint16_t i;
 
// make positive
if (num < 0) {
521,32 → 504,30
}
uint32_t num_int = (uint32_t)num;
 
// compute resolution
uint32_t frac_dec_base = 1;
for (i=0; i<num_frac_digits_c; i++) {
frac_dec_base *= 10;
}
frac_dec_base >>= 1;
 
// print integer part
uint32_t int_data = num_int >> fpf_c;
neo430_itoa((uint32_t)int_data, 0, string_buf);
neo430_uart_br_print(string_buf);
char int_buf[11];
neo430_itoa((uint32_t)(num_int >> fpf_c), 0, int_buf);
neo430_uart_br_print(int_buf);
neo430_uart_putc('.');
 
 
// compute fractional part's shift mask
uint32_t frac_dec_mask = 1;
for (i=0; i<fpf_c-1; i++) {
frac_dec_mask <<= 1;
// compute fractional resolution
uint32_t frac_dec_base = 1;
for (i=0; i<num_frac_digits_c; i++) {
frac_dec_base = frac_dec_base * 10;
}
frac_dec_base = frac_dec_base >> 1;
 
// compute fractional part's bit-insulation shift mask
uint32_t frac_dec_mask = 1L << (fpf_c-1);
 
 
// compute actual fractional part
uint32_t frac_data = num_int & ((1 << fpf_c)-1);
uint32_t frac_sum = 0;
for (i=0; i<fpf_c; i++) {
 
if (frac_data & frac_dec_mask) { // frac bit set?
uint32_t frac_data = num_int & ((1 << fpf_c)-1); // only keep fractional bits
uint32_t frac_sum = 1;
for (i=0; i<fpf_c; i++) { // test each fractional bit
if (frac_data & frac_dec_mask) { // insulate current fractional bit
frac_sum += frac_dec_base;
}
frac_dec_mask >>= 1; // go from MSB to LSB
554,8 → 535,9
}
 
// print fractional part
neo430_itoa((uint32_t)frac_sum, num_frac_digits_c-1, string_buf);
string_buf[num_frac_digits_c] = '\0'; // truncate
neo430_uart_br_print(string_buf);
char frac_buf[11];
neo430_itoa((uint32_t)frac_sum, num_frac_digits_c-1, frac_buf);
frac_buf[num_frac_digits_c] = '\0'; // truncate
neo430_uart_br_print(frac_buf);
}
 

powered by: WebSVN 2.1.0

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