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

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 34 to Rev 35
    Reverse comparison

Rev 34 → Rev 35

/neorv32/trunk/docs/figures/neorv32_axi_soc.png Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
neorv32/trunk/docs/figures/neorv32_axi_soc.png Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: neorv32/trunk/docs/figures/neorv32_processor.png =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: neorv32/trunk/docs/NEORV32.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: neorv32/trunk/rtl/core/neorv32_application_image.vhd =================================================================== --- neorv32/trunk/rtl/core/neorv32_application_image.vhd (revision 34) +++ neorv32/trunk/rtl/core/neorv32_application_image.vhd (revision 35) @@ -6,7 +6,7 @@ package neorv32_application_image is - type application_init_image_t is array (0 to 668) of std_ulogic_vector(31 downto 0); + type application_init_image_t is array (0 to 669) of std_ulogic_vector(31 downto 0); constant application_init_image : application_init_image_t := ( 00000000 => x"00000093", 00000001 => x"00000113", @@ -60,7 +60,7 @@ 00000049 => x"00158593", 00000050 => x"ff5ff06f", 00000051 => x"00001597", - 00000052 => x"9a458593", + 00000052 => x"9a858593", 00000053 => x"80000617", 00000054 => x"f2c60613", 00000055 => x"80000697", @@ -104,18 +104,18 @@ 00000093 => x"00112623", 00000094 => x"00812423", 00000095 => x"478000ef", - 00000096 => x"5a8000ef", + 00000096 => x"568000ef", 00000097 => x"02050a63", 00000098 => x"410000ef", 00000099 => x"78800513", 00000100 => x"500000ef", 00000101 => x"00000513", - 00000102 => x"5a0000ef", + 00000102 => x"560000ef", 00000103 => x"00000413", 00000104 => x"0ff47513", - 00000105 => x"594000ef", + 00000105 => x"554000ef", 00000106 => x"0c800513", - 00000107 => x"53c000ef", + 00000107 => x"554000ef", 00000108 => x"00140413", 00000109 => x"fedff06f", 00000110 => x"76400513", @@ -242,7 +242,7 @@ 00000231 => x"00112e23", 00000232 => x"01c00413", 00000233 => x"2ec000ef", - 00000234 => x"a6048493", + 00000234 => x"a6448493", 00000235 => x"ffc00993", 00000236 => x"008957b3", 00000237 => x"00f7f793", @@ -280,13 +280,13 @@ 00000269 => x"0400006f", 00000270 => x"00001737", 00000271 => x"00279793", - 00000272 => x"9b870713", + 00000272 => x"9bc70713", 00000273 => x"00e787b3", 00000274 => x"0007a783", 00000275 => x"00078067", 00000276 => x"00001737", 00000277 => x"00241793", - 00000278 => x"9fc70713", + 00000278 => x"a0070713", 00000279 => x"00e787b3", 00000280 => x"0007a783", 00000281 => x"00078067", @@ -299,7 +299,7 @@ 00000288 => x"34002573", 00000289 => x"ef5ff0ef", 00000290 => x"00001537", - 00000291 => x"9ac50513", + 00000291 => x"9b050513", 00000292 => x"200000ef", 00000293 => x"34302573", 00000294 => x"ee1ff0ef", @@ -306,7 +306,7 @@ 00000295 => x"00812403", 00000296 => x"00c12083", 00000297 => x"00001537", - 00000298 => x"a5850513", + 00000298 => x"a5c50513", 00000299 => x"01010113", 00000300 => x"1e00006f", 00000301 => x"00001537", @@ -373,7 +373,7 @@ 00000362 => x"301027f3", 00000363 => x"00079863", 00000364 => x"00001537", - 00000365 => x"a2c50513", + 00000365 => x"a3050513", 00000366 => x"0d8000ef", 00000367 => x"1e000793", 00000368 => x"30579073", @@ -450,28 +450,28 @@ 00000439 => x"00048513", 00000440 => x"fa1ff0ef", 00000441 => x"fc9ff06f", - 00000442 => x"00050593", - 00000443 => x"fe002503", - 00000444 => x"ff010113", - 00000445 => x"00112623", - 00000446 => x"00f55513", - 00000447 => x"044000ef", - 00000448 => x"00051863", - 00000449 => x"00c12083", - 00000450 => x"01010113", - 00000451 => x"00008067", - 00000452 => x"00000013", - 00000453 => x"00000013", - 00000454 => x"00000013", - 00000455 => x"00000013", - 00000456 => x"fff50513", - 00000457 => x"fddff06f", - 00000458 => x"fe802503", - 00000459 => x"01055513", - 00000460 => x"00157513", - 00000461 => x"00008067", - 00000462 => x"f8a02223", - 00000463 => x"00008067", + 00000442 => x"fe802503", + 00000443 => x"01055513", + 00000444 => x"00157513", + 00000445 => x"00008067", + 00000446 => x"f8a02223", + 00000447 => x"00008067", + 00000448 => x"00050593", + 00000449 => x"fe002503", + 00000450 => x"ff010113", + 00000451 => x"00112623", + 00000452 => x"00f55513", + 00000453 => x"02c000ef", + 00000454 => x"00051863", + 00000455 => x"00c12083", + 00000456 => x"01010113", + 00000457 => x"00008067", + 00000458 => x"00000013", + 00000459 => x"00000013", + 00000460 => x"00000013", + 00000461 => x"00000013", + 00000462 => x"fff50513", + 00000463 => x"fddff06f", 00000464 => x"00050613", 00000465 => x"00000513", 00000466 => x"0015f693", @@ -626,56 +626,57 @@ 00000615 => x"75616320", 00000616 => x"203a6573", 00000617 => x"00000000", - 00000618 => x"00204020", - 00000619 => x"544d202c", - 00000620 => x"3d4c4156", - 00000621 => x"00000000", - 00000622 => x"00000514", - 00000623 => x"00000420", + 00000618 => x"50204020", + 00000619 => x"00003d43", + 00000620 => x"544d202c", + 00000621 => x"3d4c4156", + 00000622 => x"00000000", + 00000623 => x"00000514", 00000624 => x"00000420", 00000625 => x"00000420", - 00000626 => x"00000520", - 00000627 => x"00000420", + 00000626 => x"00000420", + 00000627 => x"00000520", 00000628 => x"00000420", 00000629 => x"00000420", - 00000630 => x"0000052c", - 00000631 => x"00000420", + 00000630 => x"00000420", + 00000631 => x"0000052c", 00000632 => x"00000420", 00000633 => x"00000420", 00000634 => x"00000420", - 00000635 => x"00000538", - 00000636 => x"00000544", - 00000637 => x"00000550", - 00000638 => x"0000055c", - 00000639 => x"00000468", - 00000640 => x"000004b4", - 00000641 => x"000004c0", - 00000642 => x"000004cc", - 00000643 => x"000004d8", - 00000644 => x"000004e4", - 00000645 => x"000004f0", - 00000646 => x"000004fc", - 00000647 => x"00000420", + 00000635 => x"00000420", + 00000636 => x"00000538", + 00000637 => x"00000544", + 00000638 => x"00000550", + 00000639 => x"0000055c", + 00000640 => x"00000468", + 00000641 => x"000004b4", + 00000642 => x"000004c0", + 00000643 => x"000004cc", + 00000644 => x"000004d8", + 00000645 => x"000004e4", + 00000646 => x"000004f0", + 00000647 => x"000004fc", 00000648 => x"00000420", 00000649 => x"00000420", - 00000650 => x"00000508", - 00000651 => x"4554523c", - 00000652 => x"4157203e", - 00000653 => x"4e494e52", - 00000654 => x"43202147", - 00000655 => x"43205550", - 00000656 => x"73205253", - 00000657 => x"65747379", - 00000658 => x"6f6e206d", - 00000659 => x"76612074", - 00000660 => x"616c6961", - 00000661 => x"21656c62", - 00000662 => x"522f3c20", - 00000663 => x"003e4554", - 00000664 => x"33323130", - 00000665 => x"37363534", - 00000666 => x"42413938", - 00000667 => x"46454443", + 00000650 => x"00000420", + 00000651 => x"00000508", + 00000652 => x"4554523c", + 00000653 => x"4157203e", + 00000654 => x"4e494e52", + 00000655 => x"43202147", + 00000656 => x"43205550", + 00000657 => x"73205253", + 00000658 => x"65747379", + 00000659 => x"6f6e206d", + 00000660 => x"76612074", + 00000661 => x"616c6961", + 00000662 => x"21656c62", + 00000663 => x"522f3c20", + 00000664 => x"003e4554", + 00000665 => x"33323130", + 00000666 => x"37363534", + 00000667 => x"42413938", + 00000668 => x"46454443", others => x"00000000" );
/neorv32/trunk/rtl/core/neorv32_bootloader_image.vhd
126,7 → 126,7
00000115 => x"f1450513",
00000116 => x"0007a023",
00000117 => x"2fd000ef",
00000118 => x"14d000ef",
00000118 => x"159000ef",
00000119 => x"ffff1537",
00000120 => x"f4c50513",
00000121 => x"2ed000ef",
189,7 → 189,7
00000178 => x"00b41463",
00000179 => x"fc9566e3",
00000180 => x"00100513",
00000181 => x"5a8000ef",
00000181 => x"5b4000ef",
00000182 => x"0b4000ef",
00000183 => x"ffff1937",
00000184 => x"ffff19b7",
218,7 → 218,7
00000207 => x"03740063",
00000208 => x"07300793",
00000209 => x"00f41663",
00000210 => x"660000ef",
00000210 => x"66c000ef",
00000211 => x"fb1ff06f",
00000212 => x"06c00793",
00000213 => x"00f41863",
475,9 → 475,9
00000464 => x"00898533",
00000465 => x"f41ff0ef",
00000466 => x"fc5ff06f",
00000467 => x"fd010113",
00000468 => x"02812423",
00000469 => x"fe802403",
00000467 => x"fe802783",
00000468 => x"fd010113",
00000469 => x"02812423",
00000470 => x"02112623",
00000471 => x"02912223",
00000472 => x"03212023",
486,285 → 486,285
00000475 => x"01512a23",
00000476 => x"01612823",
00000477 => x"01712623",
00000478 => x"00847413",
00000479 => x"00040663",
00000480 => x"00400513",
00000481 => x"c69ff0ef",
00000482 => x"00050493",
00000483 => x"02051863",
00000484 => x"ffff1537",
00000485 => x"e9c50513",
00000486 => x"538000ef",
00000487 => x"008005b7",
00000488 => x"00048513",
00000489 => x"f31ff0ef",
00000490 => x"4788d7b7",
00000491 => x"afe78793",
00000492 => x"02f50463",
00000493 => x"00000513",
00000494 => x"fcdff06f",
00000495 => x"ffff1537",
00000496 => x"ebc50513",
00000497 => x"50c000ef",
00000498 => x"e15ff0ef",
00000499 => x"fc0518e3",
00000500 => x"00300513",
00000501 => x"fb1ff06f",
00000502 => x"008009b7",
00000503 => x"00498593",
00000504 => x"00048513",
00000505 => x"ef1ff0ef",
00000506 => x"00050a13",
00000507 => x"00898593",
00000508 => x"00048513",
00000509 => x"ee1ff0ef",
00000510 => x"ff002b83",
00000511 => x"00050a93",
00000512 => x"ffca7b13",
00000513 => x"00000913",
00000514 => x"00c98993",
00000515 => x"013905b3",
00000516 => x"052b1863",
00000517 => x"01540433",
00000518 => x"00200513",
00000519 => x"f60414e3",
00000520 => x"ffff1537",
00000521 => x"ec850513",
00000522 => x"4a8000ef",
00000523 => x"02c12083",
00000524 => x"02812403",
00000525 => x"800007b7",
00000526 => x"0147a023",
00000527 => x"02412483",
00000528 => x"02012903",
00000529 => x"01c12983",
00000530 => x"01812a03",
00000531 => x"01412a83",
00000532 => x"01012b03",
00000533 => x"00c12b83",
00000534 => x"03010113",
00000535 => x"00008067",
00000536 => x"00048513",
00000537 => x"e71ff0ef",
00000538 => x"012b87b3",
00000539 => x"00a40433",
00000540 => x"00a7a023",
00000541 => x"00490913",
00000542 => x"f95ff06f",
00000543 => x"ff010113",
00000544 => x"00112623",
00000545 => x"ec9ff0ef",
00000546 => x"ffff1537",
00000547 => x"ecc50513",
00000548 => x"440000ef",
00000549 => x"b05ff0ef",
00000550 => x"0000006f",
00000551 => x"ff010113",
00000552 => x"00112623",
00000553 => x"00812423",
00000554 => x"00912223",
00000555 => x"00058413",
00000556 => x"00050493",
00000557 => x"d6dff0ef",
00000558 => x"00000513",
00000559 => x"4b8000ef",
00000560 => x"00200513",
00000561 => x"4f4000ef",
00000562 => x"00048513",
00000563 => x"d7dff0ef",
00000564 => x"00040513",
00000565 => x"4e4000ef",
00000566 => x"00000513",
00000567 => x"4b8000ef",
00000568 => x"cb9ff0ef",
00000569 => x"00157513",
00000570 => x"fe051ce3",
00000571 => x"00c12083",
00000572 => x"00812403",
00000573 => x"00412483",
00000574 => x"01010113",
00000575 => x"00008067",
00000576 => x"fe010113",
00000577 => x"00812c23",
00000578 => x"00912a23",
00000579 => x"01212823",
00000580 => x"00112e23",
00000581 => x"00b12623",
00000582 => x"00300413",
00000583 => x"00350493",
00000584 => x"fff00913",
00000585 => x"00c10793",
00000586 => x"008787b3",
00000587 => x"0007c583",
00000588 => x"40848533",
00000589 => x"fff40413",
00000590 => x"f65ff0ef",
00000591 => x"ff2414e3",
00000592 => x"01c12083",
00000593 => x"01812403",
00000594 => x"01412483",
00000595 => x"01012903",
00000596 => x"02010113",
00000597 => x"00008067",
00000598 => x"ff010113",
00000599 => x"00112623",
00000600 => x"00812423",
00000601 => x"00050413",
00000602 => x"cb9ff0ef",
00000603 => x"00000513",
00000604 => x"404000ef",
00000605 => x"0d800513",
00000606 => x"440000ef",
00000607 => x"00040513",
00000608 => x"cc9ff0ef",
00000609 => x"00000513",
00000610 => x"40c000ef",
00000611 => x"c0dff0ef",
00000612 => x"00157513",
00000613 => x"fe051ce3",
00000614 => x"00c12083",
00000615 => x"00812403",
00000616 => x"01010113",
00000617 => x"00008067",
00000618 => x"fe010113",
00000619 => x"800007b7",
00000620 => x"00812c23",
00000621 => x"0007a403",
00000622 => x"00112e23",
00000623 => x"00912a23",
00000624 => x"01212823",
00000625 => x"01312623",
00000626 => x"01412423",
00000627 => x"01512223",
00000628 => x"02041863",
00000629 => x"ffff1537",
00000630 => x"e5450513",
00000631 => x"01812403",
00000632 => x"01c12083",
00000633 => x"01412483",
00000634 => x"01012903",
00000635 => x"00c12983",
00000636 => x"00812a03",
00000637 => x"00412a83",
00000638 => x"02010113",
00000639 => x"2d40006f",
00000640 => x"ffff1537",
00000641 => x"ed050513",
00000642 => x"2c8000ef",
00000643 => x"00040513",
00000644 => x"a15ff0ef",
00000645 => x"ffff1537",
00000646 => x"edc50513",
00000647 => x"2b4000ef",
00000648 => x"00800537",
00000649 => x"a01ff0ef",
00000650 => x"ffff1537",
00000651 => x"ef850513",
00000652 => x"2a0000ef",
00000653 => x"280000ef",
00000654 => x"00050493",
00000655 => x"268000ef",
00000656 => x"07900793",
00000657 => x"0af49e63",
00000658 => x"b95ff0ef",
00000659 => x"00051663",
00000660 => x"00300513",
00000661 => x"999ff0ef",
00000662 => x"ffff1537",
00000663 => x"f0450513",
00000664 => x"01045493",
00000665 => x"26c000ef",
00000666 => x"00148493",
00000667 => x"00800937",
00000668 => x"fff00993",
00000669 => x"00010a37",
00000670 => x"fff48493",
00000671 => x"07349063",
00000672 => x"4788d5b7",
00000673 => x"afe58593",
00000674 => x"00800537",
00000675 => x"e75ff0ef",
00000676 => x"00800537",
00000677 => x"00040593",
00000678 => x"00450513",
00000679 => x"e65ff0ef",
00000680 => x"ff002a03",
00000681 => x"008009b7",
00000682 => x"ffc47413",
00000683 => x"00000493",
00000684 => x"00000913",
00000685 => x"00c98a93",
00000686 => x"01548533",
00000687 => x"009a07b3",
00000688 => x"02849663",
00000689 => x"00898513",
00000690 => x"412005b3",
00000691 => x"e35ff0ef",
00000692 => x"ffff1537",
00000693 => x"ec850513",
00000694 => x"f05ff06f",
00000695 => x"00090513",
00000696 => x"e79ff0ef",
00000697 => x"01490933",
00000698 => x"f91ff06f",
00000699 => x"0007a583",
00000700 => x"00448493",
00000701 => x"00b90933",
00000702 => x"e09ff0ef",
00000703 => x"fbdff06f",
00000704 => x"01c12083",
00000705 => x"01812403",
00000706 => x"01412483",
00000707 => x"01012903",
00000708 => x"00c12983",
00000709 => x"00812a03",
00000710 => x"00412a83",
00000711 => x"02010113",
00000712 => x"00008067",
00000713 => x"fe010113",
00000714 => x"00912a23",
00000715 => x"01212823",
00000716 => x"01312623",
00000717 => x"01412423",
00000718 => x"00112e23",
00000719 => x"00812c23",
00000720 => x"00000493",
00000721 => x"00900993",
00000722 => x"00300a13",
00000723 => x"00400913",
00000724 => x"f1302473",
00000725 => x"40900533",
00000726 => x"00351513",
00000727 => x"01850513",
00000728 => x"00a45433",
00000729 => x"0ff47413",
00000730 => x"00000513",
00000731 => x"0489ea63",
00000732 => x"00050863",
00000733 => x"03050513",
00000734 => x"0ff57513",
00000735 => x"128000ef",
00000736 => x"03040513",
00000737 => x"0ff57513",
00000738 => x"11c000ef",
00000739 => x"01448663",
00000740 => x"02e00513",
00000741 => x"110000ef",
00000742 => x"00148493",
00000743 => x"fb249ae3",
00000744 => x"01c12083",
00000745 => x"01812403",
00000746 => x"01412483",
00000747 => x"01012903",
00000748 => x"00c12983",
00000749 => x"00812a03",
00000750 => x"02010113",
00000751 => x"00008067",
00000752 => x"ff640413",
00000753 => x"00150513",
00000754 => x"0ff47413",
00000755 => x"0ff57513",
00000756 => x"f9dff06f",
00000478 => x"0087f793",
00000479 => x"00050413",
00000480 => x"00078a63",
00000481 => x"fe802783",
00000482 => x"00400513",
00000483 => x"0047f793",
00000484 => x"04079663",
00000485 => x"02041863",
00000486 => x"ffff1537",
00000487 => x"e9c50513",
00000488 => x"530000ef",
00000489 => x"008005b7",
00000490 => x"00040513",
00000491 => x"f29ff0ef",
00000492 => x"4788d7b7",
00000493 => x"afe78793",
00000494 => x"02f50463",
00000495 => x"00000513",
00000496 => x"01c0006f",
00000497 => x"ffff1537",
00000498 => x"ebc50513",
00000499 => x"504000ef",
00000500 => x"e0dff0ef",
00000501 => x"fc0518e3",
00000502 => x"00300513",
00000503 => x"c11ff0ef",
00000504 => x"008009b7",
00000505 => x"00498593",
00000506 => x"00040513",
00000507 => x"ee9ff0ef",
00000508 => x"00050a13",
00000509 => x"00898593",
00000510 => x"00040513",
00000511 => x"ed9ff0ef",
00000512 => x"ff002b83",
00000513 => x"00050a93",
00000514 => x"ffca7b13",
00000515 => x"00000913",
00000516 => x"00000493",
00000517 => x"00c98993",
00000518 => x"013905b3",
00000519 => x"052b1863",
00000520 => x"015484b3",
00000521 => x"00200513",
00000522 => x"fa049ae3",
00000523 => x"ffff1537",
00000524 => x"ec850513",
00000525 => x"49c000ef",
00000526 => x"02c12083",
00000527 => x"02812403",
00000528 => x"800007b7",
00000529 => x"0147a023",
00000530 => x"02412483",
00000531 => x"02012903",
00000532 => x"01c12983",
00000533 => x"01812a03",
00000534 => x"01412a83",
00000535 => x"01012b03",
00000536 => x"00c12b83",
00000537 => x"03010113",
00000538 => x"00008067",
00000539 => x"00040513",
00000540 => x"e65ff0ef",
00000541 => x"012b87b3",
00000542 => x"00a484b3",
00000543 => x"00a7a023",
00000544 => x"00490913",
00000545 => x"f95ff06f",
00000546 => x"ff010113",
00000547 => x"00112623",
00000548 => x"ebdff0ef",
00000549 => x"ffff1537",
00000550 => x"ecc50513",
00000551 => x"434000ef",
00000552 => x"af9ff0ef",
00000553 => x"0000006f",
00000554 => x"ff010113",
00000555 => x"00112623",
00000556 => x"00812423",
00000557 => x"00912223",
00000558 => x"00058413",
00000559 => x"00050493",
00000560 => x"d61ff0ef",
00000561 => x"00000513",
00000562 => x"4ac000ef",
00000563 => x"00200513",
00000564 => x"4e8000ef",
00000565 => x"00048513",
00000566 => x"d71ff0ef",
00000567 => x"00040513",
00000568 => x"4d8000ef",
00000569 => x"00000513",
00000570 => x"4ac000ef",
00000571 => x"cadff0ef",
00000572 => x"00157513",
00000573 => x"fe051ce3",
00000574 => x"00c12083",
00000575 => x"00812403",
00000576 => x"00412483",
00000577 => x"01010113",
00000578 => x"00008067",
00000579 => x"fe010113",
00000580 => x"00812c23",
00000581 => x"00912a23",
00000582 => x"01212823",
00000583 => x"00112e23",
00000584 => x"00b12623",
00000585 => x"00300413",
00000586 => x"00350493",
00000587 => x"fff00913",
00000588 => x"00c10793",
00000589 => x"008787b3",
00000590 => x"0007c583",
00000591 => x"40848533",
00000592 => x"fff40413",
00000593 => x"f65ff0ef",
00000594 => x"ff2414e3",
00000595 => x"01c12083",
00000596 => x"01812403",
00000597 => x"01412483",
00000598 => x"01012903",
00000599 => x"02010113",
00000600 => x"00008067",
00000601 => x"ff010113",
00000602 => x"00112623",
00000603 => x"00812423",
00000604 => x"00050413",
00000605 => x"cadff0ef",
00000606 => x"00000513",
00000607 => x"3f8000ef",
00000608 => x"0d800513",
00000609 => x"434000ef",
00000610 => x"00040513",
00000611 => x"cbdff0ef",
00000612 => x"00000513",
00000613 => x"400000ef",
00000614 => x"c01ff0ef",
00000615 => x"00157513",
00000616 => x"fe051ce3",
00000617 => x"00c12083",
00000618 => x"00812403",
00000619 => x"01010113",
00000620 => x"00008067",
00000621 => x"fe010113",
00000622 => x"800007b7",
00000623 => x"00812c23",
00000624 => x"0007a403",
00000625 => x"00112e23",
00000626 => x"00912a23",
00000627 => x"01212823",
00000628 => x"01312623",
00000629 => x"01412423",
00000630 => x"01512223",
00000631 => x"02041863",
00000632 => x"ffff1537",
00000633 => x"e5450513",
00000634 => x"01812403",
00000635 => x"01c12083",
00000636 => x"01412483",
00000637 => x"01012903",
00000638 => x"00c12983",
00000639 => x"00812a03",
00000640 => x"00412a83",
00000641 => x"02010113",
00000642 => x"2c80006f",
00000643 => x"ffff1537",
00000644 => x"ed050513",
00000645 => x"2bc000ef",
00000646 => x"00040513",
00000647 => x"a09ff0ef",
00000648 => x"ffff1537",
00000649 => x"edc50513",
00000650 => x"2a8000ef",
00000651 => x"00800537",
00000652 => x"9f5ff0ef",
00000653 => x"ffff1537",
00000654 => x"ef850513",
00000655 => x"294000ef",
00000656 => x"274000ef",
00000657 => x"00050493",
00000658 => x"25c000ef",
00000659 => x"07900793",
00000660 => x"0af49e63",
00000661 => x"b89ff0ef",
00000662 => x"00051663",
00000663 => x"00300513",
00000664 => x"98dff0ef",
00000665 => x"ffff1537",
00000666 => x"f0450513",
00000667 => x"01045493",
00000668 => x"260000ef",
00000669 => x"00148493",
00000670 => x"00800937",
00000671 => x"fff00993",
00000672 => x"00010a37",
00000673 => x"fff48493",
00000674 => x"07349063",
00000675 => x"4788d5b7",
00000676 => x"afe58593",
00000677 => x"00800537",
00000678 => x"e75ff0ef",
00000679 => x"00800537",
00000680 => x"00040593",
00000681 => x"00450513",
00000682 => x"e65ff0ef",
00000683 => x"ff002a03",
00000684 => x"008009b7",
00000685 => x"ffc47413",
00000686 => x"00000493",
00000687 => x"00000913",
00000688 => x"00c98a93",
00000689 => x"01548533",
00000690 => x"009a07b3",
00000691 => x"02849663",
00000692 => x"00898513",
00000693 => x"412005b3",
00000694 => x"e35ff0ef",
00000695 => x"ffff1537",
00000696 => x"ec850513",
00000697 => x"f05ff06f",
00000698 => x"00090513",
00000699 => x"e79ff0ef",
00000700 => x"01490933",
00000701 => x"f91ff06f",
00000702 => x"0007a583",
00000703 => x"00448493",
00000704 => x"00b90933",
00000705 => x"e09ff0ef",
00000706 => x"fbdff06f",
00000707 => x"01c12083",
00000708 => x"01812403",
00000709 => x"01412483",
00000710 => x"01012903",
00000711 => x"00c12983",
00000712 => x"00812a03",
00000713 => x"00412a83",
00000714 => x"02010113",
00000715 => x"00008067",
00000716 => x"fe010113",
00000717 => x"00912a23",
00000718 => x"01312623",
00000719 => x"01412423",
00000720 => x"00112e23",
00000721 => x"00812c23",
00000722 => x"01212823",
00000723 => x"00000493",
00000724 => x"00300a13",
00000725 => x"00400993",
00000726 => x"f13027f3",
00000727 => x"40900733",
00000728 => x"00371713",
00000729 => x"01870713",
00000730 => x"00e7d7b3",
00000731 => x"0ff7f793",
00000732 => x"0047d513",
00000733 => x"40a00933",
00000734 => x"00491913",
00000735 => x"03078793",
00000736 => x"0ff97913",
00000737 => x"0ff7f413",
00000738 => x"00050663",
00000739 => x"03050513",
00000740 => x"114000ef",
00000741 => x"01240533",
00000742 => x"0ff57513",
00000743 => x"108000ef",
00000744 => x"01448663",
00000745 => x"02e00513",
00000746 => x"0fc000ef",
00000747 => x"00148493",
00000748 => x"fb3494e3",
00000749 => x"01c12083",
00000750 => x"01812403",
00000751 => x"01412483",
00000752 => x"01012903",
00000753 => x"00c12983",
00000754 => x"00812a03",
00000755 => x"02010113",
00000756 => x"00008067",
00000757 => x"ff010113",
00000758 => x"f9402783",
00000759 => x"f9002703",
983,7 → 983,7
00000972 => x"4c420a0a",
00000973 => x"203a5644",
00000974 => x"2074634f",
00000975 => x"32203731",
00000975 => x"32203232",
00000976 => x"0a303230",
00000977 => x"3a565748",
00000978 => x"00002020",
/neorv32/trunk/rtl/core/neorv32_cpu.vhd
85,6 → 85,7
i_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic := '0'; -- bus transfer error
i_bus_fence_o : out std_ulogic; -- executed FENCEI operation
i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- data bus interface --
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
96,6 → 97,7
d_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic := '0'; -- bus transfer error
d_bus_fence_o : out std_ulogic; -- executed FENCE operation
d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- system time input from MTIME --
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
-- interrupts (risc-v compliant) --
369,5 → 371,9
d_bus_fence_o => d_bus_fence_o -- fence operation
);
 
-- current privilege level --
i_bus_priv_o <= priv_mode;
d_bus_priv_o <= priv_mode;
 
 
end neorv32_cpu_rtl;
/neorv32/trunk/rtl/core/neorv32_cpu_control.vhd
551,7 → 551,7
instruction_buffer_data: process(clk_i)
begin
if rising_edge(clk_i) then
if (i_buf.we = '1') and (i_buf.clear = '0') then
if (i_buf.we = '1') then
i_buf.rdata <= i_buf.wdata;
end if;
end if;
1535,14 → 1535,14
for j in 0 to 3 loop -- bytes in pmpcfg CSR
if ((j+1) <= PMP_NUM_REGIONS) then
if (csr.pmpcfg(0+j)(7) = '0') then -- unlocked pmpcfg access
csr.pmpcfg(0+j)(0) <= csr.wdata(j*8+0); -- R
csr.pmpcfg(0+j)(1) <= csr.wdata(j*8+1); -- W
csr.pmpcfg(0+j)(2) <= csr.wdata(j*8+2); -- X
csr.pmpcfg(0+j)(0) <= csr.wdata(j*8+0); -- R (rights.read)
csr.pmpcfg(0+j)(1) <= csr.wdata(j*8+1); -- W (rights.write)
csr.pmpcfg(0+j)(2) <= csr.wdata(j*8+2); -- X (rights.execute)
csr.pmpcfg(0+j)(3) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_L
csr.pmpcfg(0+j)(4) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_H - NAPOT/OFF only
csr.pmpcfg(0+j)(5) <= '0'; -- reserved
csr.pmpcfg(0+j)(6) <= '0'; -- reserved
csr.pmpcfg(0+j)(7) <= csr.wdata(j*8+7); -- L
csr.pmpcfg(0+j)(7) <= csr.wdata(j*8+7); -- L (locked / rights also enforced in m-mode)
end if;
end if;
end loop; -- j (bytes in CSR)
1553,14 → 1553,14
for j in 0 to 3 loop -- bytes in pmpcfg CSR
if ((j+1+4) <= PMP_NUM_REGIONS) then
if (csr.pmpcfg(4+j)(7) = '0') then -- unlocked pmpcfg access
csr.pmpcfg(4+j)(0) <= csr.wdata(j*8+0); -- R
csr.pmpcfg(4+j)(1) <= csr.wdata(j*8+1); -- W
csr.pmpcfg(4+j)(2) <= csr.wdata(j*8+2); -- X
csr.pmpcfg(4+j)(0) <= csr.wdata(j*8+0); -- R (rights.read)
csr.pmpcfg(4+j)(1) <= csr.wdata(j*8+1); -- W (rights.write)
csr.pmpcfg(4+j)(2) <= csr.wdata(j*8+2); -- X (rights.execute)
csr.pmpcfg(4+j)(3) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_L
csr.pmpcfg(4+j)(4) <= csr.wdata(j*8+3) and csr.wdata(j*8+4); -- A_H - NAPOT/OFF only
csr.pmpcfg(4+j)(5) <= '0'; -- reserved
csr.pmpcfg(4+j)(6) <= '0'; -- reserved
csr.pmpcfg(4+j)(7) <= csr.wdata(j*8+7); -- L
csr.pmpcfg(4+j)(7) <= csr.wdata(j*8+7); -- L (locked / rights also enforced in m-mode)
end if;
end if;
end loop; -- j (bytes in CSR)
1731,8 → 1731,8
csr_read_access: process(clk_i)
begin
if rising_edge(clk_i) then
csr.rdata <= (others => '0'); -- default
csr.re <= csr.re_nxt; -- read access?
csr.rdata <= (others => '0'); -- default output
if (CPU_EXTENSION_RISCV_Zicsr = true) and (csr.re = '1') then
case execute_engine.i_reg(instr_csr_id_msb_c downto instr_csr_id_lsb_c) is
 
1768,7 → 1768,7
csr.rdata <= csr.mscratch;
when csr_mepc_c => -- R/W: mepc - machine exception program counter
csr.rdata <= csr.mepc(data_width_c-1 downto 1) & '0';
when csr_mcause_c => -- R/-: mcause - machine trap cause
when csr_mcause_c => -- R/W: mcause - machine trap cause
csr.rdata <= csr.mcause;
when csr_mtval_c => -- R/W: mtval - machine bad address or instruction
csr.rdata <= csr.mtval;
/neorv32/trunk/rtl/core/neorv32_package.vhd
41,7 → 41,7
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- data width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040509"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01040600"; -- no touchy!
constant pmp_max_r_c : natural := 8; -- max PMP regions - FIXED!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!
 
471,7 → 471,6
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
MEM_EXT_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
-- Processor peripherals --
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE : boolean := true; -- implement machine system timer (MTIME)?
499,6 → 498,7
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge
wb_err_i : in std_ulogic := '0'; -- transfer error
-- Advanced memory control signals (available if MEM_EXT_USE = true) --
priv_o : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
fence_o : out std_ulogic; -- indicates an executed FENCE operation
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation
-- GPIO --
513,8 → 513,8
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- TWI --
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
twi_scl_io : inout std_logic := 'H'; -- twi serial clock line
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM --
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
-- Interrupts --
561,6 → 561,7
i_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic := '0'; -- bus transfer error
i_bus_fence_o : out std_ulogic; -- executed FENCEI operation
i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- data bus interface --
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
572,6 → 573,7
d_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic := '0'; -- bus transfer error
d_bus_fence_o : out std_ulogic; -- executed FENCE operation
d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- system time input from MTIME --
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
-- interrupts (risc-v compliant) --
1065,14 → 1067,13
-- -------------------------------------------------------------------------------------------
component neorv32_wishbone
generic (
INTERFACE_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
WB_PIPELINED_MODE : boolean := false; -- false: classic/standard wishbone mode, true: pipelined wishbone mode
WB_PIPELINED_MODE : boolean := false; -- false: classic/standard wishbone mode, true: pipelined wishbone mode
-- Internal instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024 -- size of processor-internal data memory in bytes
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024 -- size of processor-internal data memory in bytes
);
port (
-- global control --
/neorv32/trunk/rtl/core/neorv32_top.vhd
74,7 → 74,6
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
MEM_EXT_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
-- Processor peripherals --
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE : boolean := true; -- implement machine system timer (MTIME)?
102,6 → 101,7
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge
wb_err_i : in std_ulogic := '0'; -- transfer error
-- Advanced memory control signals (available if MEM_EXT_USE = true) --
priv_o : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
fence_o : out std_ulogic; -- indicates an executed FENCE operation
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation
-- GPIO (available if IO_GPIO_USE = true) --
116,8 → 116,8
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- TWI (available if IO_TWI_USE = true) --
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
twi_scl_io : inout std_logic := 'H'; -- twi serial clock line
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_USE = true) --
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
-- Interrupts --
169,6 → 169,7
ack : std_ulogic; -- bus transfer acknowledge
err : std_ulogic; -- bus transfer error
fence : std_ulogic; -- fence(i) instruction executed
priv : std_ulogic_vector(1 downto 0); -- current privilege level
end record;
signal cpu_i, cpu_d, p_bus : bus_interface_t;
 
344,6 → 345,7
i_bus_ack_i => cpu_i.ack, -- bus transfer acknowledge
i_bus_err_i => cpu_i.err, -- bus transfer error
i_bus_fence_o => cpu_i.fence, -- executed FENCEI operation
i_bus_priv_o => cpu_i.priv, -- privilege level
-- data bus interface --
d_bus_addr_o => cpu_d.addr, -- bus access address
d_bus_rdata_i => cpu_d.rdata, -- bus read data
355,6 → 357,7
d_bus_ack_i => cpu_d.ack, -- bus transfer acknowledge
d_bus_err_i => cpu_d.err, -- bus transfer error
d_bus_fence_o => cpu_d.fence, -- executed FENCE operation
d_bus_priv_o => cpu_d.priv, -- privilege level
-- system time input from MTIME --
time_i => mtime_time, -- current system time
-- interrupts (risc-v compliant) --
366,6 → 369,7
);
 
-- advanced memory control --
priv_o <= cpu_i.priv; -- is the same as "cpu_d.priv"
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation
fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation
 
521,14 → 525,13
if (MEM_EXT_USE = true) generate
neorv32_wishbone_inst: neorv32_wishbone
generic map (
INTERFACE_REG_STAGES => MEM_EXT_REG_STAGES, -- number of interface register stages (0,1,2)
WB_PIPELINED_MODE => wb_pipe_mode_c, -- false: classic/standard wishbone mode, true: pipelined wishbone mode
WB_PIPELINED_MODE => wb_pipe_mode_c, -- false: classic/standard wishbone mode, true: pipelined wishbone mode
-- Internal instruction memory --
MEM_INT_IMEM_USE => MEM_INT_IMEM_USE, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_USE => MEM_INT_IMEM_USE, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_USE => MEM_INT_DMEM_USE, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE -- size of processor-internal data memory in bytes
MEM_INT_DMEM_USE => MEM_INT_DMEM_USE, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE -- size of processor-internal data memory in bytes
)
port map (
-- global control --
779,8 → 782,8
if (IO_TWI_USE = false) generate
twi_rdata <= (others => '0');
twi_ack <= '0';
-- twi_sda_io <= 'H';
-- twi_scl_io <= 'H';
-- twi_sda_io <= 'Z';
-- twi_scl_io <= 'Z';
twi_cg_en <= '0';
twi_irq <= '0';
end generate;
/neorv32/trunk/rtl/core/neorv32_twi.vhd
74,11 → 74,12
constant ctrl_twi_en_c : natural := 0; -- r/w: TWI enable
constant ctrl_twi_start_c : natural := 1; -- -/w: Generate START condition
constant ctrl_twi_stop_c : natural := 2; -- -/w: Generate STOP condition
constant ctrl_twi_irq_en_c : natural := 3; -- r/w: transmission done interrupt
constant ctrl_twi_irq_en_c : natural := 3; -- r/w: Enable transmission done interrupt
constant ctrl_twi_prsc0_c : natural := 4; -- r/w: CLK prsc bit 0
constant ctrl_twi_prsc1_c : natural := 5; -- r/w: CLK prsc bit 1
constant ctrl_twi_prsc2_c : natural := 6; -- r/w: CLK prsc bit 2
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by controller for transmission
constant ctrl_twi_cksten_c : natural := 8; -- r/w: enable clock stretching by peripheral
--
constant ctrl_twi_ack_c : natural := 30; -- r/-: Set if ACK received
constant ctrl_twi_busy_c : natural := 31; -- r/-: Set if TWI unit is busy
98,7 → 99,7
signal twi_clk_halt : std_ulogic;
 
-- twi transceiver core --
signal ctrl : std_ulogic_vector(7 downto 0); -- unit's control register
signal ctrl : std_ulogic_vector(8 downto 0); -- unit's control register
signal arbiter : std_ulogic_vector(2 downto 0);
signal twi_bitcnt : std_ulogic_vector(3 downto 0);
signal twi_rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
141,6 → 142,7
data_o(ctrl_twi_prsc1_c) <= ctrl(ctrl_twi_prsc1_c);
data_o(ctrl_twi_prsc2_c) <= ctrl(ctrl_twi_prsc2_c);
data_o(ctrl_twi_mack_c) <= ctrl(ctrl_twi_mack_c);
data_o(ctrl_twi_cksten_c) <= ctrl(ctrl_twi_cksten_c);
--
data_o(ctrl_twi_ack_c) <= not twi_rtx_sreg(0);
data_o(ctrl_twi_busy_c) <= arbiter(1) or arbiter(0);
272,12 → 274,13
 
-- Clock Stretching Detector --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clock_stretching: process(arbiter, twi_scl_o, twi_scl_i_ff1)
clock_stretching: process(ctrl, arbiter, twi_scl_o, twi_scl_i_ff1)
begin
-- clock stretching by the peripheral can happen at "any time"
if (arbiter(2) = '1') and -- module enabled
(twi_scl_o = '1') and -- controller wants to pull scl high
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral
if (arbiter(2) = '1') and -- module enabled
(ctrl(ctrl_twi_cksten_c) = '1') and -- clock stretching enabled
(twi_scl_o = '1') and -- controller wants to pull scl high
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral
twi_clk_halt <= '1';
else
twi_clk_halt <= '0';
/neorv32/trunk/rtl/core/neorv32_wishbone.vhd
1,15 → 1,15
-- #################################################################################################
-- # << NEORV32 - External Bus Interface (WISHBONE) >> #
-- # ********************************************************************************************* #
-- # The interface is either unregistered (INTERFACE_REG_STAGES = 0), only outgoing signals are #
-- # registered (INTERFACE_REG_STAGES = 1) or incoming and outgoing signals are registered #
-- # (INTERFACE_REG_STAGES = 2). This interface supports classic/standard Wishbone transactions #
-- # (WB_PIPELINED_MODE = false) and also pipelined transactions for improved timing #
-- # (WB_PIPELINED_MODE = true). #
-- # The interface provides registers for all outgoing signals. If the host cancels a running #
-- # transfer, the Wishbone arbiter still waits some time for the bus system to ACK to transfer. #
-- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
-- # All bus accesses from the CPU, which do not target the internal IO region, the internal boot- #
-- # loader or the internal instruction or data memories (if implemented), are delegated via this #
-- # Wishbone gateway to the external bus interface. #
-- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
-- # This interface supports classic/standard Wishbone transactions (WB_PIPELINED_MODE = false) #
-- # and also pipelined transactions (WB_PIPELINED_MODE = true). #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
51,14 → 51,13
 
entity neorv32_wishbone is
generic (
INTERFACE_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
WB_PIPELINED_MODE : boolean := false; -- false: classic/standard wishbone mode, true: pipelined wishbone mode
WB_PIPELINED_MODE : boolean := false; -- false: classic/standard wishbone mode, true: pipelined wishbone mode
-- Internal instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes
-- Internal data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024 -- size of processor-internal data memory in bytes
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 4*1024 -- size of processor-internal data memory in bytes
);
port (
-- global control --
89,35 → 88,40
 
architecture neorv32_wishbone_rtl of neorv32_wishbone is
 
-- constants --
constant wb_timeout_c : natural := bus_timeout_c/2;
 
-- access control --
signal int_imem_acc, int_imem_acc_real : std_ulogic;
signal int_dmem_acc, int_dmem_acc_real : std_ulogic;
signal int_boot_acc : std_ulogic;
signal wb_access : std_ulogic;
signal wb_access_ff, wb_access_ff_ff : std_ulogic;
signal rb_en : std_ulogic;
 
-- bus arbiter --
signal wb_we_ff : std_ulogic;
signal wb_stb_ff0 : std_ulogic;
signal wb_stb_ff1 : std_ulogic;
signal wb_cyc_ff : std_ulogic;
signal wb_ack_ff : std_ulogic;
signal wb_err_ff : std_ulogic;
-- bus arbiter
type ctrl_state_t is (IDLE, BUSY, CANCELED);
type ctrl_t is record
state : ctrl_state_t;
state_prev : ctrl_state_t;
we : std_ulogic;
rd_req : std_ulogic;
wr_req : std_ulogic;
adr : std_ulogic_vector(31 downto 0);
wdat : std_ulogic_vector(31 downto 0);
rdat : std_ulogic_vector(31 downto 0);
sel : std_ulogic_vector(3 downto 0);
ack : std_ulogic;
err : std_ulogic;
timeout : std_ulogic_vector(index_size_f(wb_timeout_c)-1 downto 0);
end record;
signal ctrl : ctrl_t;
 
-- wishbone mode: standard / pipelined --
signal stb_int_std : std_ulogic;
signal stb_int_pipe : std_ulogic;
signal stb_int, cyc_int : std_ulogic;
 
-- data read-back --
signal wb_rdata : std_ulogic_vector(31 downto 0);
 
begin
 
-- Sanity Check ---------------------------------------------------------------------------
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert (INTERFACE_REG_STAGES <= 2) report "NEORV32 CONFIG ERROR! Number of external memory interface buffer stages must be 0, 1 or 2." severity error;
assert (INTERFACE_REG_STAGES /= 0) report "NEORV32 CONFIG WARNING! External memory interface without register stages is still experimental for peripherals with more than 1 cycle latency." severity warning;
assert not (bus_timeout_c <= 15) report "NEORV32 PROCESSOR CONFIG ERROR: Bus timeout (bus_timeout_c) should be >16 for interfacing external modules." severity error;
 
 
-- Access Control -------------------------------------------------------------------------
134,112 → 138,98
--int_io_acc <= '1' when (addr_i >= io_base_c) else '0';
 
-- actual external bus access? --
wb_access <= (not int_imem_acc_real) and (not int_dmem_acc_real) and (not int_boot_acc) and (wren_i or rden_i);
wb_access <= (not int_imem_acc_real) and (not int_dmem_acc_real) and (not int_boot_acc);
 
 
-- Bus Arbiter -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
bus_arbiter: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
wb_we_ff <= '0';
wb_cyc_ff <= '0';
wb_stb_ff1 <= '0';
wb_stb_ff0 <= '0';
wb_ack_ff <= '0';
wb_err_ff <= '0';
wb_access_ff <= '0';
wb_access_ff_ff <= '0';
ctrl.state <= IDLE;
ctrl.state_prev <= IDLE;
ctrl.we <= '0';
ctrl.rd_req <= '0';
ctrl.wr_req <= '0';
ctrl.adr <= (others => '0');
ctrl.wdat <= (others => '0');
ctrl.rdat <= (others => '0');
ctrl.sel <= (others => '0');
ctrl.timeout <= (others => '0');
ctrl.ack <= '0';
ctrl.err <= '0';
elsif rising_edge(clk_i) then
-- read/write --
wb_we_ff <= (wb_we_ff or wren_i) and wb_access and (not wb_ack_i) and (not wb_err_i) and (not cancel_i);
-- bus cycle --
if (INTERFACE_REG_STAGES = 0) then
wb_cyc_ff <= '0'; -- unused
else
wb_cyc_ff <= (wb_cyc_ff or wb_access) and (not wb_ack_i) and (not wb_err_i) and (not cancel_i);
end if;
-- bus strobe --
wb_stb_ff1 <= wb_stb_ff0;
wb_stb_ff0 <= wb_access;
-- bus ack --
wb_ack_ff <= wb_ack_i;
-- bus err --
wb_err_ff <= wb_err_i;
-- access still active? --
wb_access_ff_ff <= wb_access_ff;
if (wb_access = '1') then
wb_access_ff <= '1';
elsif ((wb_ack_i or wb_err_i or cancel_i) = '1') then
wb_access_ff <= '0';
end if;
end if;
end process bus_arbiter;
-- defaults --
ctrl.state_prev <= ctrl.state;
ctrl.rdat <= (others => '0');
ctrl.ack <= '0';
ctrl.err <= '0';
ctrl.timeout <= std_ulogic_vector(to_unsigned(wb_timeout_c, index_size_f(wb_timeout_c)));
 
-- valid bus cycle --
wb_cyc_o <= wb_access when (INTERFACE_REG_STAGES = 0) else wb_cyc_ff;
-- state machine --
case ctrl.state is
 
-- bus strobe --
stb_int_std <= wb_access when (INTERFACE_REG_STAGES = 0) else wb_cyc_ff; -- same as wb_cyc
stb_int_pipe <= (wb_access and (not wb_stb_ff0)) when (INTERFACE_REG_STAGES = 0) else (wb_stb_ff0 and (not wb_stb_ff1)); -- wb_access rising edge detector
--
wb_stb_o <= stb_int_std when (WB_PIPELINED_MODE = false) else stb_int_pipe; -- standard or pipelined mode
when IDLE => -- waiting for host request
-- ------------------------------------------------------------
ctrl.rd_req <= '0';
ctrl.wr_req <= '0';
-- buffer all outgoing signals --
ctrl.we <= wren_i;
ctrl.adr <= addr_i;
ctrl.wdat <= data_i;
ctrl.sel <= ben_i;
-- valid read/write access --
if ((wb_access and (wren_i or ctrl.wr_req or rden_i or ctrl.rd_req)) = '1') then
ctrl.state <= BUSY;
end if;
 
-- cpu ack --
ack_o <= wb_ack_ff when (INTERFACE_REG_STAGES = 2) else wb_ack_i;
when BUSY => -- transfer in progress
-- ------------------------------------------------------------
ctrl.rdat <= wb_dat_i;
if (cancel_i = '1') then -- transfer canceled by host
ctrl.state <= CANCELED;
elsif (wb_err_i = '1') then -- abnormal bus termination
ctrl.err <= '1';
ctrl.state <= CANCELED;
elsif (wb_ack_i = '1') then -- normal bus termination
ctrl.ack <= '1';
ctrl.state <= IDLE;
end if;
 
-- cpu err --
err_o <= wb_err_ff when (INTERFACE_REG_STAGES = 2) else wb_err_i;
when CANCELED => --
-- ------------------------------------------------------------
ctrl.wr_req <= ctrl.wr_req or wren_i; -- buffer new request
ctrl.rd_req <= ctrl.rd_req or rden_i; -- buffer new request
-- wait for bus.peripheral to ACK transfer (as "aborted" but still somehow "completed")
-- or wait for a timeout and force termination
ctrl.timeout <= std_ulogic_vector(unsigned(ctrl.timeout) - 1); -- timeout counter
if (wb_ack_i = '1') or (or_all_f(ctrl.timeout) = '0') then
ctrl.state <= IDLE;
end if;
 
-- cpu read-data --
rb_en <= wb_access_ff_ff when (INTERFACE_REG_STAGES = 2) else wb_access_ff;
data_o <= wb_rdata when (rb_en = '1') else (others => '0');
when others => -- undefined
-- ------------------------------------------------------------
ctrl.state <= IDLE;
 
end case;
end if;
end process bus_arbiter;
 
-- Bus Buffer -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
interface_reg_level_zero:
if (INTERFACE_REG_STAGES = 0) generate -- 0 register levels: direct connection
wb_rdata <= wb_dat_i;
wb_adr_o <= addr_i;
wb_dat_o <= data_i;
wb_sel_o <= ben_i;
wb_we_o <= wren_i or wb_we_ff;
end generate;
 
interface_reg_level_one:
if (INTERFACE_REG_STAGES = 1) generate -- 1 register levels: buffer outgoing signals
buffer_stages_one: process(clk_i)
begin
if rising_edge(clk_i) then
if (wb_cyc_ff = '0') then
wb_adr_o <= addr_i;
wb_dat_o <= data_i;
wb_sel_o <= ben_i;
wb_we_o <= wren_i or wb_we_ff;
end if;
end if;
end process buffer_stages_one;
wb_rdata <= wb_dat_i;
end generate;
-- host access --
data_o <= ctrl.rdat;
ack_o <= ctrl.ack;
err_o <= ctrl.err;
 
interface_reg_level_two:
if (INTERFACE_REG_STAGES = 2) generate -- 2 register levels: buffer incoming and outgoing signals
buffer_stages_two: process(clk_i)
begin
if rising_edge(clk_i) then
if (wb_cyc_ff = '0') then
wb_adr_o <= addr_i;
wb_dat_o <= data_i;
wb_sel_o <= ben_i;
wb_we_o <= wren_i or wb_we_ff;
end if;
if (wb_ack_i = '1') then
wb_rdata <= wb_dat_i;
end if;
end if;
end process buffer_stages_two;
end generate;
-- wishbone interface --
wb_adr_o <= ctrl.adr;
wb_dat_o <= ctrl.wdat;
wb_we_o <= ctrl.we;
wb_sel_o <= ctrl.sel;
wb_stb_o <= stb_int when (WB_PIPELINED_MODE = true) else cyc_int;
wb_cyc_o <= cyc_int;
 
stb_int <= '1' when ((ctrl.state = BUSY) and (ctrl.state_prev = IDLE)) else '0';
cyc_int <= '0' when (ctrl.state = IDLE) else '1';
 
 
end neorv32_wishbone_rtl;
/neorv32/trunk/rtl/top_templates/README.md
3,21 → 3,31
The top entity of the NEORV32 processor is `rtl/core/neorv32_top.vhd`. This folder provides additional
top entities/wrappers that instantiate the processor's top entity to provide a different interface.
 
If you want to use one of the provides top entities from this folder, *also* add the according file to the project's
HDL file list and select the according top_template file as top entity or instatiate the top_template file in your design.
 
### `neorv32_test_setup.vhd`
 
### [`neorv32_test_setup.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_test_setup.vhd)
 
This entity is intended as "FPGA hello world" example for playing with the NEORV32. It uses only some of the
provided peripherals and provides a very simple and basic interface - only the clock, reset, UART and a subset
of the GPIO output port are propagated to the outer world.
 
 
### `neorv32_cpu_stdlogic.vhd`
### [`neorv32_cpu_stdlogic.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_cpu_stdlogic.vhd)
 
Same entity (generics and interface ports) as the default NEORV32 CPU top entity (`rtl/core/neorv32_cpu.vhd`),
but with _resolved_ port signals: All ports are of type `std_logic` or `std_logic_vector`, respectively.
 
 
### `neorv32_top_stdlogic.vhd`
### [`neorv32_top_axi4lite.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_top_axi4lite)
 
This setup provides all the peripheal/IO signals of the default processor top entity, but features an **AXI4-Lite**-compatible bus interface
instead of the default Wishbone b4 interface. The AXI signal naming corresponds to the Xilinx user guide. The Xilinx Vivado IP packer
is able to automatically detect the AXI interface ports. All ports signals of this top entity are of type `std_logic` or `std_logic_vector`, respectively.
 
 
### [`neorv32_top_stdlogic.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_top_stdlogic.vhd)
 
Same entity (generics and interface ports) as the default NEORV32 Processor top entity (`rtl/core/neorv32_top.vhd`),
but with _resolved_ port signals: All ports are of type `std_logic` or `std_logic_vector`, respectively.
/neorv32/trunk/rtl/top_templates/neorv32_cpu_stdlogic.vhd
74,6 → 74,7
i_bus_ack_i : in std_logic := '0'; -- bus transfer acknowledge
i_bus_err_i : in std_logic := '0'; -- bus transfer error
i_bus_fence_o : out std_logic; -- executed FENCEI operation
i_bus_priv_o : out std_logic_vector(1 downto 0); -- privilege level
-- data bus interface --
d_bus_addr_o : out std_logic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_logic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
85,6 → 86,7
d_bus_ack_i : in std_logic := '0'; -- bus transfer acknowledge
d_bus_err_i : in std_logic := '0'; -- bus transfer error
d_bus_fence_o : out std_logic; -- executed FENCE operation
d_bus_priv_o : out std_logic_vector(1 downto 0); -- privilege level
-- system time input from MTIME --
time_i : in std_logic_vector(63 downto 0) := (others => '0'); -- current system time
-- interrupts (risc-v compliant) --
114,6 → 116,7
signal i_bus_ack_i_int, d_bus_ack_i_int : std_ulogic;
signal i_bus_err_i_int, d_bus_err_i_int : std_ulogic;
signal i_bus_fence_o_int, d_bus_fence_o_int : std_ulogic;
signal i_bus_priv_o_int, d_bus_priv_o_int : std_ulogic_vector(1 downto 0);
--
signal time_i_int : std_ulogic_vector(63 downto 0);
--
160,6 → 163,7
i_bus_ack_i => i_bus_ack_i_int, -- bus transfer acknowledge
i_bus_err_i => i_bus_err_i_int, -- bus transfer error
i_bus_fence_o => i_bus_fence_o_int, -- executed FENCEI operation
i_bus_priv_o => i_bus_priv_o_int, -- privilege level
-- data bus interface --
d_bus_addr_o => d_bus_addr_o_int, -- bus access address
d_bus_rdata_i => d_bus_rdata_i_int, -- bus read data
171,6 → 175,7
d_bus_ack_i => d_bus_ack_i_int, -- bus transfer acknowledge
d_bus_err_i => d_bus_err_i_int, -- bus transfer error
d_bus_fence_o => d_bus_fence_o_int, -- executed FENCEI operation
d_bus_priv_o => d_bus_priv_o_int, -- privilege level
-- system time input from MTIME --
time_i => time_i_int, -- current system time
-- interrupts (risc-v compliant) --
195,6 → 200,7
i_bus_ack_i_int <= std_ulogic(i_bus_ack_i);
i_bus_err_i_int <= std_ulogic(i_bus_err_i);
i_bus_fence_o <= std_logic(i_bus_fence_o_int);
i_bus_priv_o <= std_logic_vector(i_bus_priv_o_int);
 
d_bus_addr_o <= std_logic_vector(d_bus_addr_o_int);
d_bus_rdata_i_int <= std_ulogic_vector(d_bus_rdata_i);
206,6 → 212,7
d_bus_ack_i_int <= std_ulogic(d_bus_ack_i);
d_bus_err_i_int <= std_ulogic(d_bus_err_i);
d_bus_fence_o <= std_logic(d_bus_fence_o_int);
d_bus_priv_o <= std_logic_vector(d_bus_priv_o_int);
time_i_int <= std_ulogic_vector(time_i);
/neorv32/trunk/rtl/top_templates/neorv32_test_setup.vhd
95,7 → 95,6
MEM_INT_DMEM_SIZE => 8*1024, -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE => false, -- implement external memory bus interface?
MEM_EXT_REG_STAGES => 2, -- number of interface register stages (0,1,2)
-- Processor peripherals --
IO_GPIO_USE => true, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE => true, -- implement machine system timer (MTIME)?
123,6 → 122,7
wb_ack_i => '0', -- transfer acknowledge
wb_err_i => '0', -- transfer error
-- Advanced memory control signals --
priv_o => open, -- current CPU privilege level
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
-- GPIO --
/neorv32/trunk/rtl/top_templates/neorv32_top_axi4lite.vhd
0,0 → 1,373
-- #################################################################################################
-- # << NEORV32 - Processor Top Entity with AXI4-Lite Compatible Master Interface >> #
-- # ********************************************************************************************* #
-- # "AXI", "AXI4" and "AXI4-Lite" are trademarks of Arm Holdings plc. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
-- # #
-- # 1. Redistributions of source code must retain the above copyright notice, this list of #
-- # conditions and the following disclaimer. #
-- # #
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
-- # conditions and the following disclaimer in the documentation and/or other materials #
-- # provided with the distribution. #
-- # #
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
-- # endorse or promote products derived from this software without specific prior written #
-- # permission. #
-- # #
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
-- # OF THE POSSIBILITY OF SUCH DAMAGE. #
-- # ********************************************************************************************* #
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
-- #################################################################################################
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
library neorv32;
use neorv32.neorv32_package.all;
 
entity neorv32_top_axi4lite is
generic (
-- General --
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension?
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension?
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei : boolean := true; -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE : boolean := false; -- implement PMP?
PMP_NUM_REGIONS : natural := 4; -- number of regions (max 8)
PMP_GRANULARITY : natural := 14; -- minimal region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE : boolean := true; -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM
-- Internal Data memory --
MEM_INT_DMEM_USE : boolean := true; -- implement processor-internal data memory
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- Processor peripherals --
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE : boolean := true; -- implement machine system timer (MTIME)?
IO_UART_USE : boolean := true; -- implement universal asynchronous receiver/transmitter (UART)?
IO_SPI_USE : boolean := true; -- implement serial peripheral interface (SPI)?
IO_TWI_USE : boolean := true; -- implement two-wire interface (TWI)?
IO_PWM_USE : boolean := true; -- implement pulse-width modulation unit (PWM)?
IO_WDT_USE : boolean := true; -- implement watch dog timer (WDT)?
IO_TRNG_USE : boolean := false; -- implement true random number generator (TRNG)?
IO_CFU0_USE : boolean := false; -- implement custom functions unit 0 (CFU0)?
IO_CFU1_USE : boolean := false -- implement custom functions unit 1 (CFU1)?
);
port (
-- AXI Lite-Compatible Master Interface --
-- Clock and Reset --
m_axi_aclk : in std_logic;
m_axi_aresetn : in std_logic;
-- Write Address Channel --
m_axi_awaddr : out std_logic_vector(31 downto 0);
m_axi_awprot : out std_logic_vector(2 downto 0);
m_axi_awvalid : out std_logic;
m_axi_awready : in std_logic;
-- Write Data Channel --
m_axi_wdata : out std_logic_vector(31 downto 0);
m_axi_wstrb : out std_logic_vector(3 downto 0);
m_axi_wvalid : out std_logic;
m_axi_wready : in std_logic;
-- Read Address Channel --
m_axi_araddr : out std_logic_vector(31 downto 0);
m_axi_arprot : out std_logic_vector(2 downto 0);
m_axi_arvalid : out std_logic;
m_axi_arready : in std_logic;
-- Read Data Channel --
m_axi_rdata : in std_logic_vector(31 downto 0);
m_axi_rresp : in std_logic_vector(1 downto 0);
m_axi_rvalid : in std_logic;
m_axi_rready : out std_logic;
-- Write Response Channel --
m_axi_bresp : in std_logic_vector(1 downto 0);
m_axi_bvalid : in std_logic;
m_axi_bready : out std_logic;
-- ------------------------------------------------------------
-- GPIO --
gpio_o : out std_logic_vector(31 downto 0); -- parallel output
gpio_i : in std_logic_vector(31 downto 0) := (others => '0'); -- parallel input
-- UART --
uart_txd_o : out std_logic; -- UART send data
uart_rxd_i : in std_logic := '0'; -- UART receive data
-- SPI --
spi_sck_o : out std_logic; -- SPI serial clock
spi_sdo_o : out std_logic; -- controller data out, peripheral data in
spi_sdi_i : in std_logic := '0'; -- controller data in, peripheral data out
spi_csn_o : out std_logic_vector(07 downto 0); -- SPI CS
-- TWI --
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM --
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels
-- Interrupts --
mtime_irq_i : in std_logic := '0'; -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i : in std_logic := '0'; -- machine software interrupt
mext_irq_i : in std_logic := '0' -- machine external interrupt
);
end neorv32_top_axi4lite;
 
architecture neorv32_top_axi4lite_rtl of neorv32_top_axi4lite is
 
-- type conversion --
constant USER_CODE_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(USER_CODE);
--
signal clk_i_int : std_ulogic;
signal rstn_i_int : std_ulogic;
--
signal gpio_o_int : std_ulogic_vector(31 downto 0);
signal gpio_i_int : std_ulogic_vector(31 downto 0);
--
signal priv_level : std_ulogic_vector(1 downto 0);
--
signal uart_txd_o_int : std_ulogic;
signal uart_rxd_i_int : std_ulogic;
--
signal spi_sck_o_int : std_ulogic;
signal spi_sdo_o_int : std_ulogic;
signal spi_sdi_i_int : std_ulogic;
signal spi_csn_o_int : std_ulogic_vector(07 downto 0);
--
signal pwm_o_int : std_ulogic_vector(03 downto 0);
--
signal mtime_irq_i_int : std_ulogic;
signal msw_irq_i_int : std_ulogic;
signal mext_irq_i_int : std_ulogic;
 
-- internal wishbone bus --
type wb_bus_t is record
adr : std_ulogic_vector(31 downto 0); -- address
di : std_ulogic_vector(31 downto 0); -- processor input data
do : std_ulogic_vector(31 downto 0); -- processor output data
we : std_ulogic; -- write enable
sel : std_ulogic_vector(03 downto 0); -- byte enable
stb : std_ulogic; -- strobe
cyc : std_ulogic; -- valid cycle
ack : std_ulogic; -- transfer acknowledge
err : std_ulogic; -- transfer error
end record;
signal wb_core : wb_bus_t;
 
-- AXI bridge control --
type ctrl_t is record
radr_received : std_ulogic;
wadr_received : std_ulogic;
wdat_received : std_ulogic;
end record;
signal ctrl : ctrl_t;
 
signal ack_read, ack_write : std_ulogic; -- normal transfer termination
signal err_read, err_write : std_ulogic; -- error transfer termination
 
begin
 
-- Sanity Checks --------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG ERROR: AXI4-Lite bridge requires STANDARD Wishbone mode (package.wb_pipe_mode_c = false)!" severity error;
 
 
-- The Core Of The Problem ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_top_inst: neorv32_top
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader?
USER_CODE => USER_CODE_INT, -- custom user code
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension?
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension?
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system?
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.?
-- Extension Options --
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations
-- Physical Memory Protection (PMP) --
PMP_USE => PMP_USE, -- implement PMP?
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (max 16)
PMP_GRANULARITY => PMP_GRANULARITY, -- region granularity (1=8B, 2=16B, 3=32B, ...) default is 64k
-- Internal Instruction memory --
MEM_INT_IMEM_USE => MEM_INT_IMEM_USE, -- implement processor-internal instruction memory
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes
MEM_INT_IMEM_ROM => MEM_INT_IMEM_ROM, -- implement processor-internal instruction memory as ROM
-- Internal Data memory --
MEM_INT_DMEM_USE => MEM_INT_DMEM_USE, -- implement processor-internal data memory
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE => true, -- implement external memory bus interface?
-- Processor peripherals --
IO_GPIO_USE => IO_GPIO_USE, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE => IO_MTIME_USE, -- implement machine system timer (MTIME)?
IO_UART_USE => IO_UART_USE, -- implement universal asynchronous receiver/transmitter (UART)?
IO_SPI_USE => IO_SPI_USE, -- implement serial peripheral interface (SPI)?
IO_TWI_USE => IO_TWI_USE, -- implement two-wire interface (TWI)?
IO_PWM_USE => IO_PWM_USE, -- implement pulse-width modulation unit (PWM)?
IO_WDT_USE => IO_WDT_USE, -- implement watch dog timer (WDT)?
IO_TRNG_USE => IO_TRNG_USE, -- implement true random number generator (TRNG)?
IO_CFU0_USE => IO_CFU0_USE, -- implement custom functions unit 0 (CFU0)?
IO_CFU1_USE => IO_CFU1_USE -- implement custom functions unit 1 (CFU1)?
)
port map (
-- Global control --
clk_i => clk_i_int, -- global clock, rising edge
rstn_i => rstn_i_int, -- global reset, low-active, async
-- Wishbone bus interface --
wb_adr_o => wb_core.adr, -- address
wb_dat_i => wb_core.di, -- read data
wb_dat_o => wb_core.do, -- write data
wb_we_o => wb_core.we, -- read/write
wb_sel_o => wb_core.sel, -- byte enable
wb_stb_o => wb_core.stb, -- strobe
wb_cyc_o => wb_core.cyc, -- valid cycle
wb_ack_i => wb_core.ack, -- transfer acknowledge
wb_err_i => wb_core.err, -- transfer error
-- Advanced memory control signals --
priv_o => priv_level, -- current CPU privilege level
fence_o => open, -- indicates an executed FENCE operation
fencei_o => open, -- indicates an executed FENCEI operation
-- GPIO --
gpio_o => gpio_o_int, -- parallel output
gpio_i => gpio_i_int, -- parallel input
-- UART --
uart_txd_o => uart_txd_o_int, -- UART send data
uart_rxd_i => uart_rxd_i_int, -- UART receive data
-- SPI --
spi_sck_o => spi_sck_o_int, -- SPI serial clock
spi_sdo_o => spi_sdo_o_int, -- controller data out, peripheral data in
spi_sdi_i => spi_sdi_i_int, -- controller data in, peripheral data out
spi_csn_o => spi_csn_o_int, -- SPI CS
-- TWI --
twi_sda_io => twi_sda_io, -- twi serial data line
twi_scl_io => twi_scl_io, -- twi serial clock line
-- PWM --
pwm_o => pwm_o_int, -- pwm channels
-- Interrupts --
mtime_irq_i => mtime_irq_i_int, -- machine timer interrupt, available if IO_MTIME_USE = false
msw_irq_i => msw_irq_i_int, -- machine software interrupt
mext_irq_i => mext_irq_i_int -- machine external interrupt
);
 
-- type conversion --
gpio_o <= std_logic_vector(gpio_o_int);
gpio_i_int <= std_ulogic_vector(gpio_i);
 
uart_txd_o <= std_logic(uart_txd_o_int);
uart_rxd_i_int <= std_ulogic(uart_rxd_i);
 
spi_sck_o <= std_logic(spi_sck_o_int);
spi_sdo_o <= std_logic(spi_sdo_o_int);
spi_sdi_i_int <= std_ulogic(spi_sdi_i);
spi_csn_o <= std_logic_vector(spi_csn_o_int);
 
pwm_o <= std_logic_vector(pwm_o_int);
 
msw_irq_i_int <= std_ulogic(msw_irq_i);
mext_irq_i_int <= std_ulogic(mext_irq_i);
 
-- Wishbone to AXI4-Lite Bridge -----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
 
-- access arbiter --
axi_access_arbiter: process(rstn_i_int, clk_i_int)
begin
if (rstn_i_int = '0') then
ctrl.radr_received <= '0';
ctrl.wadr_received <= '0';
ctrl.wdat_received <= '0';
elsif rising_edge(clk_i_int) then
if (wb_core.cyc = '0') then -- idle
ctrl.radr_received <= '0';
ctrl.wadr_received <= '0';
ctrl.wdat_received <= '0';
else -- busy
-- "read address received" flag --
if (wb_core.we = '0') then -- pending READ
if (m_axi_arready = '1') then -- read address received?
ctrl.radr_received <= '1';
end if;
end if;
-- "write address received" flag --
if (wb_core.we = '1') then -- pending WRITE
if (m_axi_awready = '1') then -- write address received?
ctrl.wadr_received <= '1';
end if;
end if;
-- "write data received" flag --
if (wb_core.we = '1') then -- pending WRITE
if (m_axi_wready = '1') then
ctrl.wdat_received <= '1';
end if;
end if;
end if;
end if;
end process axi_access_arbiter;
 
 
-- AXI4-Lite Global Signals --
clk_i_int <= std_ulogic(m_axi_aclk);
rstn_i_int <= std_ulogic(m_axi_aresetn);
 
 
-- AXI4-Lite Read Address Channel --
m_axi_araddr <= std_logic_vector(wb_core.adr);
m_axi_arvalid <= std_logic((wb_core.cyc and (not wb_core.we)) and (not ctrl.radr_received));
m_axi_arprot <= "000"; -- recommended by Xilinx -- "001" when (priv_level = priv_mode_m_c) else "000"; -- always: data-access, secure; privileged only when CPU is in machine mode
 
-- AXI4-Lite Read Data Channel --
m_axi_rready <= std_logic(wb_core.cyc and (not wb_core.we));
wb_core.di <= std_ulogic_vector(m_axi_rdata);
ack_read <= std_ulogic(m_axi_rvalid);
err_read <= '0' when (m_axi_rresp = "00") else '1'; -- read response = ok? check this signal only when m_axi_rvalid = '1'
 
 
-- AXI4-Lite Write Address Channel --
m_axi_awaddr <= std_logic_vector(wb_core.adr);
m_axi_awvalid <= std_logic((wb_core.cyc and wb_core.we) and (not ctrl.wadr_received));
m_axi_awprot <= "000"; -- recommended by Xilinx -- "001" when (priv_level = priv_mode_m_c) else "000"; -- always: data-access, secure; privileged only when CPU is in machine mode
 
-- AXI4-Lite Write Data Channel --
m_axi_wdata <= std_logic_vector(wb_core.do);
m_axi_wvalid <= std_logic((wb_core.cyc and wb_core.we) and (not ctrl.wdat_received));
m_axi_wstrb <= std_logic_vector(wb_core.sel); -- byte-enable
 
-- AXI4-Lite Write Response Channel --
m_axi_bready <= std_logic(wb_core.cyc and wb_core.we);
ack_write <= std_ulogic(m_axi_bvalid);
err_write <= '0' when (m_axi_bresp = "00") else '1'; -- write response = ok? check this signal only when m_axi_bvalid = '1'
 
 
-- Wishbone transfer termination --
wb_core.ack <= ack_read or ack_write;
wb_core.err <= (ack_read and err_read) or (ack_write and err_write);
 
 
end neorv32_top_axi4lite_rtl;
/neorv32/trunk/rtl/top_templates/neorv32_top_stdlogic.vhd
68,7 → 68,6
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
MEM_EXT_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
-- Processor peripherals --
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE : boolean := true; -- implement machine system timer (MTIME)?
96,6 → 95,7
wb_ack_i : in std_logic := '0'; -- transfer acknowledge
wb_err_i : in std_logic := '0'; -- transfer error
-- Advanced memory control signals (available if MEM_EXT_USE = true) --
priv_o : out std_logic_vector(1 downto 0); -- current CPU privilege level
fence_o : out std_logic; -- indicates an executed FENCE operation
fencei_o : out std_logic; -- indicates an executed FENCEI operation
-- GPIO (available if IO_GPIO_USE = true) --
110,8 → 110,8
spi_sdi_i : in std_logic := '0'; -- controller data in, peripheral data out
spi_csn_o : out std_logic_vector(07 downto 0); -- SPI CS
-- TWI (available if IO_TWI_USE = true) --
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
twi_scl_io : inout std_logic := 'H'; -- twi serial clock line
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_USE = true) --
pwm_o : out std_logic_vector(03 downto 0); -- pwm channels
-- Interrupts --
139,6 → 139,7
signal wb_ack_i_int : std_ulogic;
signal wb_err_i_int : std_ulogic;
--
signal priv_o_int : std_ulogic_vector(1 downto 0);
signal fence_o_int : std_ulogic;
signal fencei_o_int : std_ulogic;
--
192,7 → 193,6
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE => MEM_EXT_USE, -- implement external memory bus interface?
MEM_EXT_REG_STAGES => MEM_EXT_REG_STAGES, -- number of interface register stages (0,1,2)
-- Processor peripherals --
IO_GPIO_USE => IO_GPIO_USE, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE => IO_MTIME_USE, -- implement machine system timer (MTIME)?
220,6 → 220,7
wb_ack_i => wb_ack_i_int, -- transfer acknowledge
wb_err_i => wb_err_i_int, -- transfer error
-- Advanced memory control signals --
priv_o => priv_o_int, -- current CPU privilege level
fence_o => fence_o_int, -- indicates an executed FENCE operation
fencei_o => fencei_o_int, -- indicates an executed FENCEI operation
-- GPIO --
258,6 → 259,7
wb_ack_i_int <= std_ulogic(wb_ack_i);
wb_err_i_int <= std_ulogic(wb_err_i);
 
priv_o <= std_logic_vector(priv_o_int);
fence_o <= std_logic(fence_o_int);
fencei_o <= std_logic(fencei_o_int);
 
276,6 → 278,6
 
msw_irq_i_int <= std_ulogic(msw_irq_i);
mext_irq_i_int <= std_ulogic(mext_irq_i);
 
 
end neorv32_top_stdlogic_rtl;
/neorv32/trunk/rtl/README.md
1,16 → 1,16
## VHDL Source File Folders
 
### `core`
### [`core`](https://github.com/stnolting/neorv32/tree/master/rtl/core)
 
This folder contains the the core VHDL files for the NEORV32 CPU and the NEORV32 Processor. When creating a new synthesis/simulation project make
sure that all `*.vhd` files from this folder are added to a **new** design library called `neorv32`.
 
### `fpga_specifc`
### [`fpga_specifc`](https://github.com/stnolting/neorv32/tree/master/rtl/fpga_specific)
 
This folder provides FPGA- or technology-specific *alternatives* for certain CPU and/or processor modules (for example optimized memory modules using
FPGA-specific primitves).
 
### `top_templates`
### [`top_templates`](https://github.com/stnolting/neorv32/tree/master/rtl/top_templates)
 
Alternative top entities for the CPU and/or the processor. Actually, these *alternative* top entities are wrappers, which instantiate the *real* top entity of
processor/CPU and provide a different interface.
/neorv32/trunk/sim/ghdl/ghdl_sim.sh
66,6 → 66,7
#
ghdl -a --work=neorv32 $srcdir_top_templates/neorv32_cpu_stdlogic.vhd
ghdl -a --work=neorv32 $srcdir_top_templates/neorv32_test_setup.vhd
ghdl -a --work=neorv32 $srcdir_top_templates/neorv32_top_axi4lite.vhd
ghdl -a --work=neorv32 $srcdir_top_templates/neorv32_top_stdlogic.vhd
#
ghdl -a --work=neorv32 $srcdir_sim/*.vhd
/neorv32/trunk/sim/neorv32_tb.vhd
181,7 → 181,6
MEM_INT_DMEM_SIZE => 8*1024, -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE => true, -- implement external memory bus interface?
MEM_EXT_REG_STAGES => 2, -- number of interface register stages (0,1,2)
-- Processor peripherals --
IO_GPIO_USE => true, -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE => true, -- implement machine system timer (MTIME)?
312,7 → 311,7
if (wb_mem_latency_c > 1) then
for i in 1 to wb_mem_latency_c-1 loop
wb_mem.rdata(i) <= wb_mem.rdata(i-1);
wb_mem.rb_en(i) <= wb_mem.rb_en(i-1);
wb_mem.rb_en(i) <= wb_mem.rb_en(i-1) and wb_cpu.cyc;
wb_mem.ack(i) <= wb_mem.ack(i-1) and wb_cpu.cyc;
end loop;
end if;
324,7 → 323,7
 
-- output to cpu --
wb_cpu.rdata <= wb_mem.rdata(wb_mem_latency_c-1) when (wb_mem.rb_en(wb_mem_latency_c-1) = '1') else (others=> '0'); -- data output gate
wb_cpu.ack <= wb_mem.ack(wb_mem_latency_c-1) and wb_cpu.cyc; -- another AND for classic/standard wishbone transactions
wb_cpu.ack <= wb_mem.ack(wb_mem_latency_c-1);
wb_cpu.err <= '0';
 
 
/neorv32/trunk/sw/bootloader/bootloader.c
415,8 → 415,9
**************************************************************************/
void get_exe(int src) {
 
// is instruction memory (IMEM) read-only?
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM)) {
// is MEM implemented and read-only?
if ((SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM)) &&
(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM))) {
system_error(ERROR_ROM);
}
 
/neorv32/trunk/sw/example/cpu_test/main.c
49,8 → 49,6
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
//** Set 1 to run external memory test */
#define EXT_MEM_TEST 1
//** Reachable unaligned address */
#define ADDR_UNALIGNED 0x00000002
//** Unreachable aligned address */
60,15 → 58,6
/**@}*/
 
 
/**********************************************************************//**
* @name Exception handler acknowledges
**************************************************************************/
/**@{*/
/** Global volatile variable to store exception handler answer */
volatile uint32_t exception_handler_answer;
/**@}*/
 
 
// Prototypes
void global_trap_handler(void);
void test_ok(void);
97,8 → 86,8
**************************************************************************/
int main() {
 
register uint32_t tmp_a;
uint32_t i;
register uint32_t tmp_a, tmp_b, tmp_c;
uint32_t i, j;
volatile uint32_t dummy_dst __attribute__((unused));
 
union {
115,7 → 104,7
 
neorv32_mtime_set_time(0);
// set CMP of machine system timer MTIME to max to prevent an IRQ
uint64_t mtime_cmp_max = 0xFFFFFFFFFFFFFFFFL;
uint64_t mtime_cmp_max = 0xFFFFFFFFFFFFFFFFUL;
neorv32_mtime_set_timecmp(mtime_cmp_max);
 
// intro
176,84 → 165,13
// intro2
neorv32_uart_printf("\n\nStarting tests...\n\n");
 
 
// enable global interrupts
neorv32_cpu_eint();
 
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
 
// ----------------------------------------------------------
// Instruction memory test
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_uart_printf("[%i] Processor-internal IMEM test: ", cnt_test);
 
if ((UART_CT & (1 << UART_CT_SIM_MODE)) == 0) { // check if this is a simulation
cnt_test++;
 
register uint32_t dmem_probe_addr = SYSINFO_ISPACE_BASE;
uint32_t dmem_probe_cnt = 0;
 
while(1) {
asm volatile ("lb zero, 0(%[input_j])" : : [input_j] "r" (dmem_probe_addr));
if (exception_handler_answer == TRAP_CODE_L_ACCESS) {
break;
}
dmem_probe_addr++;
dmem_probe_cnt++;
}
neorv32_uart_printf("%u bytes (should be %u bytes) ", dmem_probe_cnt, SYSINFO_IMEM_SIZE);
neorv32_uart_printf("@ 0x%x ", SYSINFO_ISPACE_BASE);
if (dmem_probe_cnt == SYSINFO_IMEM_SIZE) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (disabled for simulation)\n");
}
 
 
// ----------------------------------------------------------
// Data memory test
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_uart_printf("[%i] Processor-internal DMEM test: ", cnt_test);
 
if ((UART_CT & (1 << UART_CT_SIM_MODE)) == 0) { // check if this is a simulation
cnt_test++;
 
register uint32_t imem_probe_addr = SYSINFO_DSPACE_BASE;
uint32_t imem_probe_cnt = 0;
 
while(1) {
asm volatile ("lb zero, 0(%[input_j])" : : [input_j] "r" (imem_probe_addr));
if (exception_handler_answer == TRAP_CODE_L_ACCESS) {
break;
}
imem_probe_addr++;
imem_probe_cnt++;
}
neorv32_uart_printf("%u bytes (should be %u bytes) ", imem_probe_cnt, SYSINFO_DMEM_SIZE);
neorv32_uart_printf("@ 0x%x ", SYSINFO_DSPACE_BASE);
if (imem_probe_cnt == SYSINFO_DMEM_SIZE) {
test_ok();
}
else {
test_fail();
}
}
else {
neorv32_uart_printf("skipped (disabled for simulation)\n");
}
 
 
// ----------------------------------------------------------
// List all accessible CSRs
// ----------------------------------------------------------
neorv32_uart_printf("[%i] List all accessible CSRs: ", cnt_test);
279,7 → 197,7
 
// iterate through full 12-bit CSR address space
for (csr_addr_cnt=0x000; csr_addr_cnt<=0xfff; csr_addr_cnt++) {
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
// construct and store new CSR access instruction
// 0x00006073 = csrrsi, 0x000, 0
292,8 → 210,8
asm volatile ("jalr ra, %[input_i]" : : [input_i] "r" (tmp_a));
 
// check for access exception
if (exception_handler_answer == 0xFFFFFFFF) { // no exception -> access ok -> CSR exists
neorv32_uart_printf(" + 0x%x\n", csr_addr_cnt);
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) { // no exception -> access ok -> CSR exists
neorv32_uart_printf(" + 0x%x\n", csr_addr_cnt);
i++;
}
}
312,7 → 230,7
// ----------------------------------------------------------
// CFU0 test (default HW)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Default CFU0 access test: ", cnt_test);
 
// cfu0 implemented?
327,7 → 245,7
 
if ((CFU0_REG_0 == 0x01234567) && (CFU0_REG_1 == 0x76543210) &&
(CFU0_REG_2 == 0xABCDABCD) && (CFU0_REG_3 == 0xFFAAFFAA) && // correct read-back
(exception_handler_answer == 0xFFFFFFFF)) { // no exception
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception
test_ok();
}
else {
335,7 → 253,7
}
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
neorv32_uart_printf("skipped (CFU0 not implemented)\n");
}
 
 
342,7 → 260,7
// ----------------------------------------------------------
// CFU1 test (default HW)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Default CFU1 access test: ", cnt_test);
 
// cfu0 implemented?
357,7 → 275,7
 
if ((CFU1_REG_0 == 0x22334455) && (CFU1_REG_1 == 0x44782931) &&
(CFU1_REG_2 == 0xDDAABBFF) && (CFU1_REG_3 == 0xA0B0D0C0) && // correct read-back
(exception_handler_answer == 0xFFFFFFFF)) { // no exception
(neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) { // no exception
test_ok();
}
else {
365,7 → 283,7
}
}
else {
neorv32_uart_printf("skipped (not implemented)\n");
neorv32_uart_printf("skipped (CFU1 not implemented)\n");
}
 
 
372,7 → 290,7
// ----------------------------------------------------------
// Bus timeout latency estimation
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Estimate bus time-out latency: ", cnt_test);
 
// start timing
380,11 → 298,11
 
// this will timeout
MMR_UNREACHABLE = 0;
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE) - tmp_a;
 
// wait for timeout
while (exception_handler_answer == 0xFFFFFFFF);
while (neorv32_cpu_csr_read(CSR_MCAUSE) == 0);
 
tmp_a = neorv32_cpu_csr_read(CSR_CYCLE) - tmp_a;
tmp_a = tmp_a / 4; // divide by average CPI
neorv32_uart_printf("~%u cycles\n", tmp_a);
 
392,42 → 310,49
// ----------------------------------------------------------
// External memory interface test
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_uart_printf("[%i] External memory access test: ", cnt_test);
#if (EXT_MEM_TEST == 1)
cnt_test++;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] External memory access (@ 0x%x) test: ", cnt_test, (uint32_t)EXT_MEM_BASE);
 
// create test program in RAM
static const uint32_t dummy_ext_program[2] __attribute__((aligned(8))) = {
0x3407D073, // csrwi mscratch, 15
0x00008067 // ret (32-bit)
};
if (UART_CT & (1 << UART_CT_SIM_MODE)) { // check if this is a simulation
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT)) {
cnt_test++;
 
// copy to external memory
if (memcpy((void*)EXT_MEM_BASE, (void*)&dummy_ext_program, (size_t)sizeof(dummy_ext_program)) == NULL) {
test_fail();
}
else {
// create test program in RAM
static const uint32_t dummy_ext_program[2] __attribute__((aligned(8))) = {
0x3407D073, // csrwi mscratch, 15
0x00008067 // ret (32-bit)
};
 
// execute program
tmp_a = (uint32_t)EXT_MEM_BASE; // call the dummy sub program
asm volatile ("jalr ra, %[input_i]" : : [input_i] "r" (tmp_a));
if (exception_handler_answer == 0xFFFFFFFF) { // make sure there was no exception
if (neorv32_cpu_csr_read(CSR_MSCRATCH) == 15) { // make sure the program was executed in the right way
test_ok();
// copy to external memory
if (memcpy((void*)EXT_MEM_BASE, (void*)&dummy_ext_program, (size_t)sizeof(dummy_ext_program)) == NULL) {
test_fail();
}
else {
test_fail();
 
// execute program
tmp_a = (uint32_t)EXT_MEM_BASE; // call the dummy sub program
asm volatile ("jalr ra, %[input_i]" : : [input_i] "r" (tmp_a));
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) { // make sure there was no exception
if (neorv32_cpu_csr_read(CSR_MSCRATCH) == 15) { // make sure the program was executed in the right way
test_ok();
}
else {
test_fail();
}
}
else {
test_fail();
}
}
}
else {
test_fail();
neorv32_uart_printf("skipped (external memory interface not implemented)\n");
}
}
#else
neorv32_uart_printf("skipped (disabled)\n");
#endif
else {
neorv32_uart_printf("skipped (on real hardware)\n");
}
 
 
// ----------------------------------------------------------
453,12 → 378,12
// ----------------------------------------------------------
// Test fence instructions - make sure CPU does not crash here and throws no exception
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FENCE instruction test: ", cnt_test);
cnt_test++;
asm volatile ("fence");
 
if (exception_handler_answer != 0xFFFFFFFF) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != 0) {
test_fail();
}
else {
470,18 → 395,18
// Test fencei instructions - make sure CPU does not crash here and throws no exception
// a more complex test is provided by the RISC-V compliance test
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FENCE.I instruction test: ", cnt_test);
asm volatile ("fence.i");
 
if (exception_handler_answer == TRAP_CODE_I_ILLEGAL) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
neorv32_uart_printf("skipped (not implemented)\n");
}
else {
cnt_test++;
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
asm volatile ("fence.i");
if (exception_handler_answer == 0xFFFFFFFF) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
test_ok();
}
else {
493,7 → 418,7
// ----------------------------------------------------------
// Illegal CSR access (CSR not implemented)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Illegal CSR (0xfff) access test: ", cnt_test);
 
cnt_test++;
500,7 → 425,7
 
neorv32_cpu_csr_read(0xfff); // CSR 0xfff not implemented
 
if (exception_handler_answer == TRAP_CODE_I_ILLEGAL) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
511,7 → 436,7
// ----------------------------------------------------------
// Write-access to read-only CSR
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Read-only CSR (time) write access test: ", cnt_test);
 
cnt_test++;
518,7 → 443,7
 
neorv32_cpu_csr_write(CSR_TIME, 0); // time CSR is read-only
 
if (exception_handler_answer == TRAP_CODE_I_ILLEGAL) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
529,7 → 454,7
// ----------------------------------------------------------
// No "real" CSR write access (because rs1 = r0)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Read-only CSR (time) no-write (rs1=0) access test: ", cnt_test);
 
cnt_test++;
538,7 → 463,7
// -> should cause no exception
asm volatile("csrrs zero, time, zero");
 
if (exception_handler_answer == 0xFFFFFFFF) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
test_ok();
}
else {
549,7 → 474,7
// ----------------------------------------------------------
// Unaligned instruction address
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] I_ALIGN (instruction alignment) exception test: ", cnt_test);
 
// skip if C-mode is implemented
560,7 → 485,7
// call unaligned address
((void (*)(void))ADDR_UNALIGNED)();
 
if (exception_handler_answer == TRAP_CODE_I_MISALIGNED) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_MISALIGNED) {
neorv32_uart_printf("ok\n");
cnt_ok++;
}
577,7 → 502,7
// ----------------------------------------------------------
// Instruction access fault
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] I_ACC (instruction bus access) exception test: ", cnt_test);
cnt_test++;
 
584,7 → 509,7
// call unreachable aligned address
((void (*)(void))ADDR_UNREACHABLE)();
 
if (exception_handler_answer == TRAP_CODE_I_ACCESS) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ACCESS) {
test_ok();
}
else {
595,7 → 520,7
// ----------------------------------------------------------
// Illegal instruction
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] I_ILLEG (illegal instruction) exception test: ", cnt_test);
 
cnt_test++;
603,7 → 528,7
asm volatile ("csrrw zero, 0xfff, zero"); // = 0xfff01073 : CSR 0xfff not implemented -> illegal instruction
 
// make sure this has cause an illegal exception
if (exception_handler_answer == TRAP_CODE_I_ILLEGAL) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
// make sure this is really the instruction that caused the exception
// for illegal instructions mtval contains the actual instruction word
if (neorv32_cpu_csr_read(CSR_MTVAL) == 0xfff01073) {
621,7 → 546,7
// ----------------------------------------------------------
// Illegal compressed instruction
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] CI_ILLEG (illegal compressed instruction) exception test: ", cnt_test);
 
// skip if C-mode is not implemented
638,7 → 563,7
tmp_a = (uint32_t)&dummy_sub_program_ci; // call the dummy sub program
asm volatile ("jalr ra, %[input_i]" : : [input_i] "r" (tmp_a));
 
if (exception_handler_answer == TRAP_CODE_I_ILLEGAL) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
653,13 → 578,13
// ----------------------------------------------------------
// Breakpoint instruction
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] BREAK (break instruction) exception test: ", cnt_test);
cnt_test++;
 
asm volatile("EBREAK");
 
if (exception_handler_answer == TRAP_CODE_BREAKPOINT) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_BREAKPOINT) {
test_ok();
}
else {
670,7 → 595,7
// ----------------------------------------------------------
// Unaligned load address
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] L_ALIGN (load address alignment) exception test: ", cnt_test);
cnt_test++;
 
677,7 → 602,7
// load from unaligned address
asm volatile ("lw zero, %[input_i](zero)" : : [input_i] "i" (ADDR_UNALIGNED));
 
if (exception_handler_answer == TRAP_CODE_L_MISALIGNED) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_MISALIGNED) {
test_ok();
}
else {
688,7 → 613,7
// ----------------------------------------------------------
// Load access fault
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] L_ACC (load bus access) exception test: ", cnt_test);
cnt_test++;
 
695,7 → 620,7
// load from unreachable aligned address
dummy_dst = MMR_UNREACHABLE;
 
if (exception_handler_answer == TRAP_CODE_L_ACCESS) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_L_ACCESS) {
test_ok();
}
else {
706,7 → 631,7
// ----------------------------------------------------------
// Unaligned store address
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] S_ALIGN (store address alignment) exception test: ", cnt_test);
cnt_test++;
 
713,7 → 638,7
// store to unaligned address
asm volatile ("sw zero, %[input_i](zero)" : : [input_i] "i" (ADDR_UNALIGNED));
 
if (exception_handler_answer == TRAP_CODE_S_MISALIGNED) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_MISALIGNED) {
test_ok();
}
else {
724,7 → 649,7
// ----------------------------------------------------------
// Store access fault
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] S_ACC (store bus access) exception test: ", cnt_test);
cnt_test++;
 
731,7 → 656,7
// store to unreachable aligned address
MMR_UNREACHABLE = 0;
 
if (exception_handler_answer == TRAP_CODE_S_ACCESS) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
test_ok();
}
else {
742,13 → 667,13
// ----------------------------------------------------------
// Environment call
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] ENVCALL (ecall instruction) exception test: ", cnt_test);
cnt_test++;
 
asm volatile("ECALL");
 
if (exception_handler_answer == TRAP_CODE_MENV_CALL) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MENV_CALL) {
test_ok();
}
else {
759,7 → 684,7
// ----------------------------------------------------------
// Machine timer interrupt (MTIME)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] MTI (machine timer) interrupt test: ", cnt_test);
 
if (neorv32_mtime_available()) {
776,7 → 701,7
asm volatile("nop");
asm volatile("nop");
 
if (exception_handler_answer == TRAP_CODE_MTI) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_MTI) {
test_ok();
}
else {
794,7 → 719,7
// ----------------------------------------------------------
// Fast interrupt channel 0 (WDT)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ0 (fast IRQ0) interrupt test (via WDT): ", cnt_test);
 
if (neorv32_wdt_available()) {
813,7 → 738,7
asm volatile("nop");
asm volatile("nop");
 
if (exception_handler_answer == TRAP_CODE_FIRQ_0) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_0) {
test_ok();
}
else {
831,53 → 756,57
// ----------------------------------------------------------
// Fast interrupt channel 1 (GPIO)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ1 (fast IRQ1) interrupt test (via GPIO): ", cnt_test);
 
if (neorv32_gpio_available()) {
cnt_test++;
if (UART_CT & (1 << UART_CT_SIM_MODE)) { // check if this is a simulation
if (neorv32_gpio_available()) {
cnt_test++;
 
// clear output port
neorv32_gpio_port_set(0);
// clear output port
neorv32_gpio_port_set(0);
 
// configure GPIO.in(31) for pin-change IRQ
neorv32_gpio_pin_change_config(0x80000000);
// configure GPIO.in(31) for pin-change IRQ
neorv32_gpio_pin_change_config(0x80000000);
 
// trigger pin-change IRQ by setting GPIO.out(31)
// the testbench connects GPIO.out => GPIO.in
neorv32_gpio_pin_set(31);
// trigger pin-change IRQ by setting GPIO.out(31)
// the testbench connects GPIO.out => GPIO.in
neorv32_gpio_pin_set(31);
 
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
// wait some time for the IRQ to arrive the CPU
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
 
if (exception_handler_answer == TRAP_CODE_FIRQ_1) {
test_ok();
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_1) {
test_ok();
}
else {
test_fail();
}
 
// disable GPIO pin-change IRQ
neorv32_gpio_pin_change_config(0);
 
// clear output port
neorv32_gpio_port_set(0);
}
else {
test_fail();
neorv32_uart_printf("skipped (GPIO not implemented)\n");
}
 
// disable GPIO pin-change IRQ
neorv32_gpio_pin_change_config(0);
 
// clear output port
neorv32_gpio_port_set(0);
}
else {
neorv32_uart_printf("skipped (GPIO not implemented)\n");
neorv32_uart_printf("skipped (on real hardware)\n");
}
 
 
 
// ----------------------------------------------------------
// Fast interrupt channel 2 (UART)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ2 (fast IRQ2) interrupt test (via UART): ", cnt_test);
 
if (neorv32_uart_available()) {
915,7 → 844,7
// re-enable UART sim_mode if it was enabled and disable UART TX done IRQ
UART_CT = uart_ct_backup;
 
if (exception_handler_answer == TRAP_CODE_FIRQ_2) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_2) {
test_ok();
}
else {
931,7 → 860,7
// ----------------------------------------------------------
// Fast interrupt channel 3 (SPI)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ3 (fast IRQ3) interrupt test (via SPI): ", cnt_test);
 
if (neorv32_spi_available()) {
952,7 → 881,7
asm volatile("nop");
asm volatile("nop");
 
if (exception_handler_answer == TRAP_CODE_FIRQ_3) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_3) {
test_ok();
}
else {
970,16 → 899,17
// ----------------------------------------------------------
// Fast interrupt channel 3 (TWI)
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] FIRQ3 (fast IRQ3) interrupt test (via TWI): ", cnt_test);
 
if (neorv32_twi_available()) {
cnt_test++;
 
// configure TWI, fastest clock, transfer-done IRQ enable
neorv32_twi_setup(CLK_PRSC_2, 1);
// configure TWI, fastest clock, transfer-done IRQ enable, disable peripheral clock stretching
neorv32_twi_setup(CLK_PRSC_2, 1, 0);
 
// trigger TWI IRQ
neorv32_twi_generate_start();
neorv32_twi_trans(0);
neorv32_twi_generate_stop();
 
991,7 → 921,7
asm volatile("nop");
asm volatile("nop");
 
if (exception_handler_answer == TRAP_CODE_FIRQ_3) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_FIRQ_3) {
test_ok();
}
else {
1009,7 → 939,7
// ----------------------------------------------------------
// Test WFI ("sleep") instructions, wakeup via MTIME
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] WFI (wait for interrupt / sleep instruction) test (wake-up via MTIME): ", cnt_test);
 
if (neorv32_mtime_available()) {
1021,7 → 951,7
// put CPU into sleep mode
asm volatile ("wfi");
 
if (exception_handler_answer != TRAP_CODE_MTI) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != TRAP_CODE_MTI) {
test_fail();
}
else {
1039,7 → 969,7
// ----------------------------------------------------------
// Test invalid CSR access in user mode
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] Invalid CSR access (mstatus) from user mode test: ", cnt_test);
 
// skip if U-mode is not implemented
1054,7 → 984,7
neorv32_cpu_csr_read(CSR_MSTATUS);
}
 
if (exception_handler_answer == TRAP_CODE_I_ILLEGAL) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_I_ILLEGAL) {
test_ok();
}
else {
1070,7 → 1000,7
// ----------------------------------------------------------
// Test RTE debug handler
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
neorv32_uart_printf("[%i] RTE (runtime environment) debug trap handler test: ", cnt_test);
 
cnt_test++;
1082,12 → 1012,12
neorv32_cpu_csr_read(0xfff); // CSR not available
 
neorv32_uart_printf(" ");
if (exception_handler_answer == 0xFFFFFFFF) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) != 0) {
test_ok();
}
else {
test_fail();
neorv32_uart_printf("answer: 0x%x", exception_handler_answer);
neorv32_uart_printf("answer: 0x%x", neorv32_cpu_csr_read(CSR_MCAUSE));
}
 
// restore original handler
1097,7 → 1027,6
// ----------------------------------------------------------
// Test physical memory protection
// ----------------------------------------------------------
exception_handler_answer = 0xFFFFFFFF;
neorv32_uart_printf("[%i] Physical memory protection (PMP): ", cnt_test);
 
// check if PMP is implemented
1105,13 → 1034,37
 
// Test access to protected region
// ---------------------------------------------
neorv32_uart_printf("Creating protected page (NAPOT, 64kB) @ 0xFFFFA000, [!x, !w, r]... ");
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
cnt_test++;
 
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffdfff); // 64k area @ 0xFFFFA000
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b00011001); // NAPOT, read permission, NO write and NO execute permissions
// check min granulartiy
neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
tmp_a = neorv32_cpu_csr_read(0x3b0);
 
if ((neorv32_cpu_csr_read(CSR_PMPADDR0) == 0xffffdfff) && (neorv32_cpu_csr_read(CSR_PMPCFG0) == 0b00011001)) {
// find least-significat set bit
for (i=31; i!=0; i--) {
if (((tmp_a >> i) & 1) == 0) {
break;
}
}
 
tmp_a = SYSINFO_DSPACE_BASE; // base address of protected region
 
tmp_b = 0;
for (j=i; j!=0; j--) {
tmp_b = tmp_b << 1;
tmp_b = tmp_b | 1;
}
tmp_c = tmp_a & (~tmp_b); // clear LSBs in base address
tmp_c = tmp_c | tmp_b; // set region size config
 
neorv32_uart_printf("Creating protected page (NAPOT, [!X,!W,R], %u bytes) @ 0x%x (PMPADDR = 0x%x): ", (uint32_t)(1 << (i+1+2)), tmp_a, tmp_c);
 
neorv32_cpu_csr_write(CSR_PMPADDR0, tmp_c); // 64k area @ 0xFFFFA000
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b00011001); // NAPOT, read permission, NO write and NO execute permissions
 
if ((neorv32_cpu_csr_read(CSR_PMPADDR0) == tmp_c) && (neorv32_cpu_csr_read(CSR_PMPCFG0) == 0b00011001) && (neorv32_cpu_csr_read(CSR_MCAUSE) == 0)) {
test_ok();
}
else {
1119,18 → 1072,43
}
 
 
// ------ EXECUTE: should fail ------
neorv32_uart_printf("[%i] - PMP: U-mode [!X,!W,R] execute test: ", cnt_test);
cnt_test++;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile ("jalr ra, %[input_i]" : : [input_i] "r" (tmp_a)); // call address to execute -> should fail
}
 
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
test_fail();
}
else {
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
test_ok();
}
 
 
// ------ LOAD: should work ------
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] load test: ", cnt_test);
neorv32_uart_printf("[%i] - PMP: U-mode [!X,!W,R] read test: ", cnt_test);
cnt_test++;
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile ("lw zero, 0xFFFFFF90(zero)"); // MTIME load access, should work
asm volatile ("lw zero, 0(%[input_i])" : : [input_i] "r" (tmp_a)); // load access -> should work
}
 
if (exception_handler_answer == 0xFFFFFFFF) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
1145,17 → 1123,17
 
 
// ------ STORE: should fail ------
neorv32_uart_printf("[%i] PMP: U-mode [!X,!W,R] store test: ", cnt_test);
neorv32_uart_printf("[%i] - PMP: U-mode [!X,!W,R] write test: ", cnt_test);
cnt_test++;
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
// switch to user mode (hart will be back in MACHINE mode when trap handler returns)
neorv32_cpu_goto_user_mode();
{
asm volatile ("sw zero, 0xFFFFFF90(zero)"); // MTIME store access, should fail
asm volatile ("sw zero, 0(%[input_i])" : : [input_i] "r" (tmp_a)); // store access -> should fail
}
 
if (exception_handler_answer == TRAP_CODE_S_ACCESS) {
if (neorv32_cpu_csr_read(CSR_MCAUSE) == TRAP_CODE_S_ACCESS) {
// switch back to machine mode (if not allready)
asm volatile ("ecall");
 
1169,18 → 1147,18
}
 
 
// ------ Lock test ------
neorv32_uart_printf("[%i] PMP: Locking pmpcfg0 [mode=off]: ", cnt_test);
// ------ Lock test - pmpcfg0.0 ------
neorv32_uart_printf("[%i] - PMP: pmpcfg0.0 [mode=off] lock test: ", cnt_test);
cnt_test++;
exception_handler_answer = 0xFFFFFFFF;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b10000001); // locked but entry is deactivated (mode = off)
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b10000001); // locked, but entry is deactivated (mode = off)
 
// make sure a locked cfg cannot be written
tmp_a = neorv32_cpu_csr_read(CSR_PMPCFG0);
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b00011001); // try to re-write CFG content
 
if ((tmp_a != neorv32_cpu_csr_read(CSR_PMPCFG0)) || (exception_handler_answer != 0xFFFFFFFF)) {
if ((tmp_a != neorv32_cpu_csr_read(CSR_PMPCFG0)) || (neorv32_cpu_csr_read(CSR_MCAUSE) != 0)) {
test_fail();
}
else {
1187,6 → 1165,25
test_ok();
}
 
 
// ------ Lock test - pmpaddr0 ------
neorv32_uart_printf("[%i] - PMP: pmpaddr0 [mode=off] lock test: ", cnt_test);
cnt_test++;
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
neorv32_cpu_csr_write(CSR_PMPCFG0, 0b10000001); // locked, but entry is deactivated (mode = off)
 
// make sure a locked cfg cannot be written
tmp_a = neorv32_cpu_csr_read(CSR_PMPADDR0);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xABABCDCD); // try to re-write ADDR content
 
if ((tmp_a != neorv32_cpu_csr_read(CSR_PMPADDR0)) || (neorv32_cpu_csr_read(CSR_MCAUSE) != 0)) {
test_fail();
}
else {
test_ok();
}
 
}
else {
neorv32_uart_printf("not implemented\n");
1196,17 → 1193,17
// ----------------------------------------------------------
// Final test reports
// ----------------------------------------------------------
neorv32_uart_printf("\n\nExecuted instructions: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET));
neorv32_uart_printf( "Required clock cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE));
neorv32_uart_printf("\nExecuted instructions: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_INSTRET));
neorv32_uart_printf( "Required clock cycles: %u\n", (uint32_t)neorv32_cpu_csr_read(CSR_CYCLE));
 
neorv32_uart_printf("\nTest results:\nOK: %i/%i\nFAILED: %i/%i\n\n", cnt_ok, cnt_test, cnt_fail, cnt_test);
 
// final result
if (cnt_fail == 0) {
neorv32_uart_printf("%c[1mTEST OK!%c[0m\n", 27, 27);
neorv32_uart_printf("%c[1m[TEST OK!]%c[0m\n", 27, 27);
}
else {
neorv32_uart_printf("%c[1mTEST FAILED!%c[0m\n", 27, 27);
neorv32_uart_printf("%c[1m[TEST FAILED!]%c[0m\n", 27, 27);
}
 
return 0;
1218,8 → 1215,6
**************************************************************************/
void global_trap_handler(void) {
 
exception_handler_answer = neorv32_cpu_csr_read(CSR_MCAUSE);
 
// hack: always come back in MACHINE MODE
register uint32_t mask = (1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L);
asm volatile ("csrrs zero, mstatus, %[input_j]" : : [input_j] "r" (mask));
/neorv32/trunk/sw/example/demo_twi/main.c
60,9 → 60,9
 
 
/**********************************************************************//**
* This program generates a simple dimming sequence for PWM channel 0,1,2.
* This program provides an interactive console to communicate with TWI devices.
*
* @note This program requires the UART and the TWI to be synthesized.
* @note This program requires the UART and the PWM to be synthesized.
*
* @return Irrelevant.
**************************************************************************/
101,8 → 101,8
neorv32_uart_printf("This program allows to create TWI transfers by hand.\n"
"Type 'help' to see the help menu.\n\n");
 
// configure TWI, second slowest clock, no IRQ
neorv32_twi_setup(CLK_PRSC_2048, 0);
// configure TWI, second slowest clock, no IRQ, no clock-stretching
neorv32_twi_setup(CLK_PRSC_2048, 0, 0);
 
// no active bus session yet
bus_claimed = 0;
/neorv32/trunk/sw/example/hex_viewer/main.c
0,0 → 1,271
// #################################################################################################
// # << NEORV32 - Hex Viewer - Memory Inspector >> #
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2020, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
// # #
// # 1. Redistributions of source code must retain the above copyright notice, this list of #
// # conditions and the following disclaimer. #
// # #
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
// # conditions and the following disclaimer in the documentation and/or other materials #
// # provided with the distribution. #
// # #
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
// # endorse or promote products derived from this software without specific prior written #
// # permission. #
// # #
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
// # OF THE POSSIBILITY OF SUCH DAMAGE. #
// # ********************************************************************************************* #
// # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
// #################################################################################################
 
 
/**********************************************************************//**
* @file hex_viewer/main.c
* @author Stephan Nolting
* @brief Interactive memory inspector.
**************************************************************************/
 
#include <neorv32.h>
#include <string.h>
 
 
/**********************************************************************//**
* @name User configuration
**************************************************************************/
/**@{*/
/** UART BAUD rate */
#define BAUD_RATE 19200
/**@}*/
 
 
// Prototypes
void read_memory(void);
void write_memory(void);
void dump_memory(void);
uint32_t hexstr_to_uint(char *buffer, uint8_t length);
 
 
/**********************************************************************//**
* This program provides an interactive console to read/write memory.
*
* @note This program requires the UART to be synthesized.
*
* @return Irrelevant.
**************************************************************************/
int main() {
 
char buffer[8];
int length = 0;
 
// check if UART unit is implemented at all
if (neorv32_uart_available() == 0) {
return 0;
}
 
 
// capture all exceptions and give debug info via UART
neorv32_rte_setup();
 
 
// init UART at default baud rate, no rx interrupt, no tx interrupt
neorv32_uart_setup(BAUD_RATE, 0, 0);
 
// intro
neorv32_uart_printf("\n--- Hex Viewer ---\n\n");
 
// info
neorv32_uart_printf("This program allows to read/write/dump memory locations by hand.\n"
"Type 'help' to see the help menu.\n\n");
 
// Main menu
for (;;) {
neorv32_uart_printf("HEX_VIEWER:> ");
length = neorv32_uart_scan(buffer, 8, 1);
neorv32_uart_printf("\n");
 
if (!length) // nothing to be done
continue;
 
// decode input and execute command
if (!strcmp(buffer, "help")) {
neorv32_uart_printf("Available commands:\n"
" help - show this text\n"
" read - read single word from address\n"
" write - write single word to address\n"
" dump - dumpe several words from base address\n\n");
}
 
else if (!strcmp(buffer, "read")) {
read_memory();
}
 
else if (!strcmp(buffer, "write")) {
write_memory();
}
 
else if (!strcmp(buffer, "dump")) {
dump_memory();
}
 
else {
neorv32_uart_printf("Invalid command. Type 'help' to see all commands.\n");
}
}
 
return 0;
}
 
 
/**********************************************************************//**
* Read word from memory address
**************************************************************************/
void read_memory(void) {
 
char terminal_buffer[16];
 
// enter address
neorv32_uart_printf("Enter address (8 hex chars): ");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
// perform read access
neorv32_uart_printf("\n[0x%x] = ", mem_address);
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
register uint32_t mem_data = 0;
 
asm volatile ("lw %[rdata], 0(%[raddr])" : [rdata] "=r" (mem_data) : [raddr] "r" (mem_address));
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
neorv32_uart_printf("0x%x", mem_data);
}
 
neorv32_uart_printf("\n");
}
 
 
/**********************************************************************//**
* Write word tp memory address
**************************************************************************/
void write_memory(void) {
 
char terminal_buffer[16];
 
// enter address
neorv32_uart_printf("Enter address (8 hex chars): ");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
// enter data
neorv32_uart_printf("\nEnter data (8 hex chars): ");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_data = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
 
// perform write access
neorv32_uart_printf("\n[0x%x] = ", mem_address);
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
asm volatile ("sw %[wdata], 0(%[waddr])" : : [wdata] "r" (mem_data), [waddr] "r" (mem_address));
asm volatile ("nop");
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
neorv32_uart_printf("0x%x", mem_data);
}
 
neorv32_uart_printf("\n");
}
 
 
/**********************************************************************//**
* Read several words from memory base address
**************************************************************************/
void dump_memory(void) {
 
char terminal_buffer[16];
 
// enter base address
neorv32_uart_printf("Enter base address (8 hex chars): ");
neorv32_uart_scan(terminal_buffer, 8+1, 1); // 8 hex chars for address plus '\0'
register uint32_t mem_address = (uint32_t)hexstr_to_uint(terminal_buffer, strlen(terminal_buffer));
mem_address = mem_address & 0xFFFFFFFCUL; // align to 32-bit boundary
 
neorv32_uart_printf("\nPress key to start dumping. Press any key to abort.\n");
 
neorv32_uart_getc(); // wait for key
 
// perform read accesses
register uint32_t mem_data = 0;
while(neorv32_uart_char_received() == 0) {
 
neorv32_uart_printf("[0x%x] = ", mem_address);
 
neorv32_cpu_csr_write(CSR_MCAUSE, 0);
 
asm volatile ("lw %[rdata], 0(%[raddr])" : [rdata] "=r" (mem_data) : [raddr] "r" (mem_address));
asm volatile ("nop");
 
// show memory content if there was no exception
if (neorv32_cpu_csr_read(CSR_MCAUSE) == 0) {
neorv32_uart_printf("0x%x\n", mem_data);
}
else {
break;
}
 
mem_address = mem_address + 4;
 
}
neorv32_uart_char_received_get(); // clear UART rx buffer
neorv32_uart_printf("\n");
}
 
 
/**********************************************************************//**
* Helper function to convert N hex chars string into uint32_T
*
* @param[in,out] buffer Pointer to array of chars to convert into number.
* @param[in,out] length Length of the conversion string.
* @return Converted number.
**************************************************************************/
uint32_t hexstr_to_uint(char *buffer, uint8_t length) {
 
uint32_t res = 0, d = 0;
char c = 0;
 
while (length--) {
c = *buffer++;
 
if ((c >= '0') && (c <= '9'))
d = (uint32_t)(c - '0');
else if ((c >= 'a') && (c <= 'f'))
d = (uint32_t)((c - 'a') + 10);
else if ((c >= 'A') && (c <= 'F'))
d = (uint32_t)((c - 'A') + 10);
else
d = 0;
 
res = res + (d << (length*4));
}
 
return res;
}
/neorv32/trunk/sw/example/hex_viewer/makefile
0,0 → 1,338
#################################################################################################
# << NEORV32 - Application Makefile >> #
# ********************************************************************************************* #
# Make sure to add the riscv GCC compiler's bin folder to your PATH environment variable. #
# ********************************************************************************************* #
# BSD 3-Clause License #
# #
# Copyright (c) 2020, Stephan Nolting. All rights reserved. #
# #
# Redistribution and use in source and binary forms, with or without modification, are #
# permitted provided that the following conditions are met: #
# #
# 1. Redistributions of source code must retain the above copyright notice, this list of #
# conditions and the following disclaimer. #
# #
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of #
# conditions and the following disclaimer in the documentation and/or other materials #
# provided with the distribution. #
# #
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to #
# endorse or promote products derived from this software without specific prior written #
# permission. #
# #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS #
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF #
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE #
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, #
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED #
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING #
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED #
# OF THE POSSIBILITY OF SUCH DAMAGE. #
# ********************************************************************************************* #
# The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting #
#################################################################################################
 
 
# *****************************************************************************
# USER CONFIGURATION
# *****************************************************************************
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
 
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
 
# Optimization
EFFORT ?= -Os
 
# Compiler toolchain
RISCV_TOOLCHAIN ?= riscv32-unknown-elf
 
# CPU architecture and ABI
MARCH ?= -march=rv32i
MABI ?= -mabi=ilp32
 
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
 
# Serial port for executable upload via bootloer
COM_PORT ?= /dev/ttyUSB0
 
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# *****************************************************************************
 
 
 
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 core rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl/core
# Marker file to check for NEORV32 home folder
NEORV32_HOME_MARKER = $(NEORV32_INC_PATH)/neorv32.h
 
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
 
# Linker script
LD_SCRIPT = $(NEORV32_COM_PATH)/neorv32.ld
 
# Main output files
APP_EXE = neorv32_exe.bin
APP_ASM = main.asm
APP_IMG = neorv32_application_image.vhd
BOOT_IMG = neorv32_bootloader_image.vhd
 
 
# -----------------------------------------------------------------------------
# Sources and objects
# -----------------------------------------------------------------------------
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
 
# Define all object files
OBJ = $(SRC:%=%.o)
 
 
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_TOOLCHAIN)-gcc
OBJDUMP = $(RISCV_TOOLCHAIN)-objdump
OBJCOPY = $(RISCV_TOOLCHAIN)-objcopy
SIZE = $(RISCV_TOOLCHAIN)-size
 
# Host native compiler
CC_X86 = gcc -Wall -O -g
 
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
 
# Compiler & linker flags
CC_OPTS = $(MARCH) $(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles
CC_OPTS += -Wl,--gc-sections -lm -lc -lgcc -lc
# This accelerates instruction fetch after branches when C extension is enabled (irrelevant when C extension is disabled)
CC_OPTS += -falign-functions=4 -falign-labels=4 -falign-loops=4 -falign-jumps=4
CC_OPTS += $(USER_FLAGS)
 
 
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all bootloader
.DEFAULT_GOAL := help
 
# 'compile' is still here for compatibility
exe: $(APP_ASM) $(APP_EXE)
compile: $(APP_ASM) $(APP_EXE)
install: $(APP_ASM) $(APP_IMG)
all: $(APP_ASM) $(APP_EXE) $(APP_IMG)
 
# Check if making bootloader
# Use different base address and legth for instruction memory/"rom" (BOOTMEM instead of IMEM)
# Also define "make_bootloader" for crt0.S
target bootloader: CC_OPTS += -Wl,--defsym=make_bootloader=1 -Dmake_bootloader
 
 
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# install/compile tools
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.cpp
@echo Compiling $(IMAGE_GEN)
@$(CC_X86) $< -o $(IMAGE_GEN)
 
 
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Compile app *.s sources (assembly)
%.s.o: %.s
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.S sources (assembly + C pre-processor)
%.S.o: %.S
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
 
# Compile app *.c sources
%.c.o: %.c
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Compile app *.cpp sources
%.cpp.o: %.cpp
@$(CC) -c $(CC_OPTS) -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
 
# Link object files and show memory utilization
main.elf: $(OBJ)
@$(CC) $(CC_OPTS) -T $(LD_SCRIPT) $(OBJ) -o $@
@echo "Memory utilization:"
@$(SIZE) main.elf
 
# Assembly listing file (for debugging)
$(APP_ASM): main.elf
@$(OBJDUMP) -D -S -z $< > $@
 
# Generate final executable from .text + .rodata + .data (in THIS order!)
main.bin: main.elf $(APP_ASM)
@$(OBJCOPY) -I elf32-little $< -j .text -O binary text.bin
@$(OBJCOPY) -I elf32-little $< -j .rodata -O binary rodata.bin
@$(OBJCOPY) -I elf32-little $< -j .data -O binary data.bin
@cat text.bin rodata.bin data.bin > $@
@rm -f text.bin rodata.bin data.bin
 
 
# -----------------------------------------------------------------------------
# Application targets: Generate binary executable, install (as VHDL file)
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
@echo "Executable ($(APP_EXE)) size in bytes:"
@wc -c < $(APP_EXE)
 
# Generate NEORV32 executable VHDL boot image
$(APP_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -app_img $< $@ $(shell basename $(CURDIR))
@echo "Installing application image to $(NEORV32_RTL_PATH)/$(APP_IMG)"
@cp $(APP_IMG) $(NEORV32_RTL_PATH)/.
 
 
# -----------------------------------------------------------------------------
# Bootloader targets
# -----------------------------------------------------------------------------
# Create and install bootloader VHDL init image
$(BOOT_IMG): main.bin $(IMAGE_GEN)
@set -e
@$(IMAGE_GEN) -bld_img $< $(BOOT_IMG) $(shell basename $(CURDIR))
@echo "Installing bootloader image to $(NEORV32_RTL_PATH)/$(BOOT_IMG)"
@cp $(BOOT_IMG) $(NEORV32_RTL_PATH)/.
 
# Just an alias that
bootloader: $(BOOT_IMG)
 
 
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
@echo "---------------- Check: NEORV32_HOME folder ----------------"
ifneq ($(shell [ -e $(NEORV32_HOME_MARKER) ] && echo 1 || echo 0 ), 1)
$(error NEORV32_HOME folder not found!)
endif
@echo "NEORV32_HOME: $(NEORV32_HOME)"
@echo "---------------- Check: $(CC) ----------------"
@$(CC) -v
@echo "---------------- Check: $(OBJDUMP) ----------------"
@$(OBJDUMP) -V
@echo "---------------- Check: $(OBJCOPY) ----------------"
@$(OBJCOPY) -V
@echo "---------------- Check: $(SIZE) ----------------"
@$(SIZE) -V
@echo "---------------- Check: NEORV32 image_gen ----------------"
@$(IMAGE_GEN) -help
@echo "---------------- Check: Native GCC ----------------"
@$(CC_X86) -v
@echo
@echo "Toolchain check OK"
 
 
# -----------------------------------------------------------------------------
# Upload executable via serial port to bootloader
# -----------------------------------------------------------------------------
upload: $(APP_EXE)
@sh $(NEORV32_EXG_PATH)/uart_upload.sh $(COM_PORT) $(APP_EXE)
 
 
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
@echo "---------------- Info: Project ----------------"
@echo "Project folder: $(shell basename $(CURDIR))"
@echo "Source files: $(APP_SRC)"
@echo "Include folder(s): $(APP_INC)"
@echo "ASM include folder(s): $(ASM_INC)"
@echo "---------------- Info: NEORV32 ----------------"
@echo "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
@echo "IMAGE_GEN: $(IMAGE_GEN)"
@echo "Core source files:"
@echo "$(CORE_SRC)"
@echo "Core include folder:"
@echo "$(NEORV32_INC_PATH)"
@echo "---------------- Info: Objects ----------------"
@echo "Project object files:"
@echo "$(OBJ)"
@echo "---------------- Info: RISC-V CPU ----------------"
@echo "MARCH: $(MARCH)"
@echo "MABI: $(MABI)"
@echo "---------------- Info: Toolchain ----------------"
@echo "Toolchain: $(RISCV_TOLLCHAIN)"
@echo "CC: $(CC)"
@echo "OBJDUMP: $(OBJDUMP)"
@echo "OBJCOPY: $(OBJCOPY)"
@echo "SIZE: $(SIZE)"
@echo "---------------- Info: Compiler Libraries ----------------"
@echo "LIBGCC:"
@$(CC) -print-libgcc-file-name
@echo "SEARCH-DIRS:"
@$(CC) -print-search-dirs
@echo "---------------- Info: Flags ----------------"
@echo "USER_FLAGS: $(USER_FLAGS)"
@echo "CC_OPTS: $(CC_OPTS)"
@echo "---------------- Info: Host Native GCC Flags ----------------"
@echo "CC_X86: $(CC_X86)"
 
 
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: main.elf
@$(OBJDUMP) -x main.elf
 
 
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
@echo "<<< NEORV32 Application Makefile >>>"
@echo "Make sure to add the bin folder of RISC-V GCC to your PATH variable."
@echo "Targets:"
@echo " help - show this text"
@echo " check - check toolchain"
@echo " info - show makefile/toolchain configuration"
@echo " exe - compile and generate <neorv32_exe.bin> executable for upload via bootloader"
@echo " install - compile, generate and install VHDL IMEM boot image (for application)"
@echo " all - compile and generate <neorv32_exe.bin> executable for upload via bootloader and generate and install VHDL IMEM boot image (for application)"
@echo " clean - clean up project"
@echo " clean_all - clean up project, core libraries and image generator"
@echo " bootloader - compile, generate and install VHDL BOOTROM boot image (for bootloader only!)"
@echo " upload - upload <neorv32_exe.bin> executable via serial port <COM_PORT> to bootloader"
 
 
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
clean:
@rm -f *.elf *.o *.bin *.out *.asm *.vhd
 
clean_all: clean
@rm -f $(OBJ) $(IMAGE_GEN)
/neorv32/trunk/sw/lib/include/neorv32.h
423,6 → 423,7
TWI_CT_PRSC1 = 5, /**< TWI control register(5) (r/w): Clock prescaler select bit 1 */
TWI_CT_PRSC2 = 6, /**< TWI control register(6) (r/w): Clock prescaler select bit 2 */
TWI_CT_MACK = 7, /**< TWI control register(7) (r/w): Generate controller ACK for each transmission */
TWI_CT_CKSTEN = 8, /**< TWI control register(8) (r/w): Enable clock stretching (by peripheral) */
 
TWI_CT_ACK = 30, /**< TWI control register(30) (r/-): ACK received when set */
TWI_CT_BUSY = 31 /**< TWI control register(31) (r/-): Transfer in progress, busy flag */
/neorv32/trunk/sw/lib/include/neorv32_twi.h
46,7 → 46,7
 
// prototypes
int neorv32_twi_available(void);
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en);
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en, uint8_t ckst_en);
void neorv32_twi_disable(void);
void neorv32_twi_mack_enable(void);
int neorv32_twi_busy(void);
/neorv32/trunk/sw/lib/source/neorv32_cpu.c
246,11 → 246,11
**************************************************************************/
void __attribute__((naked)) neorv32_cpu_goto_user_mode(void) {
 
register uint32_t mask = (1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L);
asm volatile ("csrrc zero, mstatus, %[input_j]" : : [input_j] "r" (mask));
// make sure to use NO registers in here! -> naked
 
// return switching to user mode
asm volatile ("csrw mepc, ra");
asm volatile ("mret");
asm volatile ("csrw mepc, ra \n\t" // move return address to mepc so we can return using "mret". also, we can use ra as general purpose register in here
"li ra, %[input_imm] \n\t" // bit mask to clear the two MPP bits
"csrrc zero, mstatus, ra \n\t" // clear MPP bits -> MPP=u-mode
"mret \n\t" // return and switch to user mode
: : [input_imm] "i" ((1<<CPU_MSTATUS_MPP_H) | (1<<CPU_MSTATUS_MPP_L)));
}
 
/neorv32/trunk/sw/lib/source/neorv32_pwm.c
105,6 → 105,10
duty_mask = duty_mask << (channel * 8);
duty_new = duty_new << (channel * 8);
 
PWM_DUTY &= ~duty_mask; // clear previous duty cycle
PWM_DUTY |= duty_new; // set new duty cycle
uint32_t duty_cycle = PWM_DUTY;
 
duty_cycle &= ~duty_mask; // clear previous duty cycle
duty_cycle |= duty_new; // set new duty cycle
 
PWM_DUTY = duty_cycle;
}
/neorv32/trunk/sw/lib/source/neorv32_rte.c
227,7 → 227,7
}
 
// instruction address
neorv32_uart_print(" @ ");
neorv32_uart_print(" @ PC=");
__neorv32_rte_print_hex_word(neorv32_cpu_csr_read(CSR_MSCRATCH)); // rte core stores actual mepc to mscratch
 
// additional info
326,7 → 326,7
 
neorv32_uart_printf("\n- Min granularity: ");
if (i < 29) {
neorv32_uart_printf("%u bytes per region (0x%x)\n", (uint32_t)(1 << (i+1+2)), pmp_test_g);
neorv32_uart_printf("%u bytes per region\n", (uint32_t)(1 << (i+1+2)));
}
else {
neorv32_uart_printf("2^%u bytes per region\n", i+1+2);
485,8 → 485,8
 
// serial division
cnt = 0;
while (tmp >= 10) {
tmp = tmp - 10;
while (tmp >= 16) {
tmp = tmp - 16;
cnt++;
}
 
/neorv32/trunk/sw/lib/source/neorv32_twi.c
66,8 → 66,9
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] irq_en Enable transfer-done interrupt when 1.
* @param[in] ckst_en Enable clock-stretching by peripherals when 1.
**************************************************************************/
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en) {
void neorv32_twi_setup(uint8_t prsc, uint8_t irq_en, uint8_t ckst_en) {
 
TWI_CT = 0; // reset
 
80,7 → 81,10
uint32_t ct_irq = (uint32_t)(irq_en & 0x01);
ct_irq = ct_irq << TWI_CT_IRQ_EN;
 
TWI_CT = ct_enable | ct_prsc | ct_irq;
uint32_t ct_cksten = (uint32_t)(ckst_en & 0x01);
ct_cksten = ct_cksten << TWI_CT_CKSTEN;
 
TWI_CT = ct_enable | ct_prsc | ct_irq | ct_cksten;
}
 
 
/neorv32/trunk/sw/lib/source/neorv32_uart.c
118,7 → 118,7
/* Enable the UART for SIM mode. */
/* Only use this for simulation! */
#ifdef UART_SIM_MODE
#warning UART_SIM_MODE enabled! Sending all UART.TX to text.io simulation output instead of real UART transmitter. Use this for simulations only!
#warning UART_SIM_MODE enabled! Sending all UART.TX data to text.io simulation output instead of real UART transmitter. Use this for simulations only!
uint32_t sim_mode = 1 << UART_CT_SIM_MODE;
#else
uint32_t sim_mode = 0;
/neorv32/trunk/sw/README.md
2,26 → 2,26
 
This folder provides the core of the NEORV32 software framework. This is a short description of the main folders.
 
### `bootloader`
### [`bootloader`](https://github.com/stnolting/neorv32/tree/master/sw/bootloader)
 
Source(s) of the default NEORV32 bootloader. A pre-built image is already installed into the rtl design via the
`rtl/core/neorv32_bootloader_image.vhd` file.
 
### `common`
### [`common`](https://github.com/stnolting/neorv32/tree/master/sw/common)
 
NEORV32-specific common files for all bootloader and application programs: linker script for executable generation and
processor start-up code.
 
### `example`
### [`example`](https://github.com/stnolting/neorv32/tree/master/sw/example)
 
Several example programs for testing and for getting started.
 
### `image_gen`
### [`image_gen`](https://github.com/stnolting/neorv32/tree/master/sw/image_gen)
 
This folder contains a simple program that is used to create NEORV32 executables (for upload via bootloader) and VHDL memory
initializiation files (for memory-persistent applications and for the bootloader). This program is automatically compiled using
the native GCC when invoking one of the application compilation makefiles.
 
### `lib`
### [`lib`](https://github.com/stnolting/neorv32/tree/master/sw/lib)
 
Core libraries (sources and header files) and helper functions for using the processor peripherals and the CPU itself.
/neorv32/trunk/CHANGELOG.md
6,8 → 6,8
A list of all releases can be found [here](https://github.com/stnolting/neorv32/releases). The most recent version of the *NEORV32 data sheet*
can be found [here](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf) (pdf).
 
The processor can determine its version from the `mimpid` CSR (at CSR address 0xf13). A 2x4-bit decimal-coded representation is used.
Example: `CSR(mimpid) = 0x01040312 -> 01.04.03.12 -> Version 1.4.3.12 = v1.4.3.12`
The processor can determine its version from the `mimpid` CSR (at CSR address 0xf13). A 2x4-bit decimal-coded representation is used. Leading
zeros are optional. Example: `CSR(mimpid) = 0x01040312 -> 01.04.03.12 -> Version 1.4.3.12 = v1.4.3.12 = v01.04.03.12`
 
For the HDL sources the version number is globally defined by the `hw_version_c` constant in the main VHDL package file
[`rtl/core/neorv32_package.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_package.vhd).
14,7 → 14,10
 
| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 20.10.2020 | 1.4.5.9 | Fixed bug in CPU "sleep" instruction (`WFI` - wait for interrupt) |
| 24.10.2020 | [**:rocket:1.4.6.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.6.0) | Completely reworked external memory interface (WISHBONE), removed now-obsolete processor generic `MEM_EXT_REG_STAGES`; added processor wrapper with **AXI4-Lite master interface** |
| 22.10.2020 | 1.4.5.11 | TWI: Added new control register flag to enable/disable SCL clock stretching by peripheral devices |
| 22.10.2020 | 1.4.5.10 | Added `i_bus_priv_o` and `d_bus_priv_o` signals to CPU_top and `priv_o` to Processor_top to show privilege level of bus access (from `mstatus` MPP); :warning: Fixed bug in external memory interface [WISHBONE] (non-standard Wishbone components were able to corrupt processor-internal ACK/ERR signal logic) |
| 20.10.2020 | 1.4.5.9 | :warning: Fixed bug in CPU "sleep" instruction (`WFI` - wait for interrupt) |
| 20.10.2020 | 1.4.5.8 | *Machine timer interrupt* is available as processor input pin (`mtime_irq_i`) if internal `MTIME` is not implemented (`IO_MTIME_USE` = false) |
| 18.10.2020 | 1.4.5.7 | Added new IO peripheral/Device: Second CFU (CFU1); renamed old CFU to CFU0; CFU VHDL files: `neorv32_cfu0.vhd` & `neorv32_cfu1.vhd`; removed CFU interrupt |
| 17.10.2020 | 1.4.5.5 | New makefile target `upload` allows to directly upload an executable to the bootloader from the console |
28,16 → 31,16
| 08.10.2020 | 1.4.4.5 | Removed CPU's `BUS_TIMEOUT` and processor's `MEM_EXT_TIMEOUT` generics; instead, a global configuration `bus_timeout_c` in the VHDL package file is used now |
| 08.10.2020 | 1.4.4.4 | Removed `DEVNULL` device; all simulation output options from this device are now available as `SIM_MODE` in the `UART`; `mcause` CSR can now also be written; FIXED: trying to write a read-only CSR will cause an illegal instruction exception; for compatibility reasons any write access to the misa CSR will be ignored and will NOT cause an exception |
| 07.10.2020 | 1.4.4.2 | Simplified ALU's set of core operations; removed co-processor data mux right after ALU -> shorter critical path; CPU control VHDL code clean-up and CSR write logic optimization; optimized IMEM/DMEM access logic; added note regarding alignment of IMEM/DMEM |
| 05.10.2020 | [**:rocket:1.4.4.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.4.0) | Fixed bug in external memory interface: Executing code from external memory was causing an instruction fetch stall |
| 05.10.2020 | [**:rocket:1.4.4.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.4.0) | :warning: Fixed bug in external memory interface: Executing code from external memory was causing an instruction fetch stall |
| 02.10.2020 | 1.4.3.9 | `[m]cycleh` and `[m]instreth` CSRs are now 32-bit wide (-> fully RISC-V-compliant) |
| 01.10.2020 | 1.4.3.8 | Added CPU top entity wrapper with resolved port signals `rtl/top_templetes/neorv32_cpu_stdlogic.vhd`; optimized ALU core functions – shorter critical path, less control overhead, reduced HW footprint |
| 27.09.2020 | 1.4.3.3 | Further improved ALU and control logic; CSR access instruction require one additional cycle now (to let side effects kick in); updated synthesis results; added CFU hardware driver dummy |
| 26.09.2020 | 1.4.3.2 | Fixed bug in `CSRRWI` instruction (introduced with version 1.4.3.1); further ALU operand logic optimizations; updated CPU data path figure |
| 26.09.2020 | 1.4.3.2 | :warning: Fixed bug in `CSRRWI` instruction (introduced with version 1.4.3.1); further ALU operand logic optimizations; updated CPU data path figure |
| 25.09.2020 | 1.4.3.1 | Register file's `x0` is now a physical register; this register is initialized by the hardware and locked afterwards; removed "set to zero" stage -> smaller hardware footprint and shorter critical path; added processor top entity wrapper with resolved signals `rtl/top_templetes/neorv32_top_stdlogic.vhd` |
| 16.09.2020 | [**:rocket:1.4.3.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.3.0) | Simplified memory configuration: removed processor top's memory space configuration generics (`MEM_ISPACE_BASE`, `MEM_ISPACE_SIZE`, `MEM_DSPACE_BASE`, `MEM_DSPACE_SIZE`); data/instruction space sizes are irrelevant for hardware; instruction/data space base addresses are fixed (but can be modified in NEORV32 VHDL package file); modified SYSINFO registers; adapted bootloader, crt0 start-up code and linker script; stack configuration is now done via linker script; reworked chapter "address space"; added CFU interrupt -> fast interrupt channel 1 (shared with GPIO) |
| 14.09.2020 | 1.4.2.0 | Removed option to disable CSR counters (via `CSR_COUNTERS_USE` generic) since these counters are mandatory according to the RISC-V specs; added new IO/peripheral device: custom functions unit (`CFU`) for tightly-coupled custom co-processors; improved timing of processor-internal clock generator; fixed wrong labels in address space figure and removed dedicated exception vectors box; added mask register to GPIO unit to specify which input pins can trigger a pin-change interrupt |
| 11.09.2020 | 1.4.0.4 | Reworked `TRNG` architecture and interface; added text regarding fast interrupt channels usage for the NEORV32 processor |
| 02.09.2020 | 1.4.0.2 | Fixed bugs in external memory interface; added option to define latency of simulated external memory in testbench; hardware configuration sanity checks will now only appear once in console; added more details to data sheet section 3.3. Address Space; fixed typos in MEM_*_BASE and MEM_*_SIZE generic names |
| 02.09.2020 | 1.4.0.2 | :warning: Fixed bugs in external memory interface; added option to define latency of simulated external memory in testbench; hardware configuration sanity checks will now only appear once in console; added more details to data sheet section 3.3. Address Space; fixed typos in MEM_*_BASE and MEM_*_SIZE generic names |
| 01.09.2020 | 1.4.0.1 | Using registers above `x15` when the `E` extensions is enabled will now correctly cause an illegal instruction exception |
| 29.08.2020 | [**:rocket:1.4.0.0**](https://github.com/stnolting/neorv32/releases/tag/v1.4.0.0) | Rearranged and reworked this document; added FreeRTOS port, demo & short referencing chapter; removed booloader-specific linker scripts – main linker script is used for both, applications and bootloader; bootloader can now have `.data` and `.bss` sections; improved IMEM and BOOTROM memory initialization – faster synthesis; image generator now constrains init array size to actual executable size; peripheral/IO devices can only be written in full word mode (= 32-bit); GPIO ports are now 32-bit wide |
| 23.08.2020 | 1.3.7.3 | Added custom `mzext` CSR to check for available Z* CPU extensions; multiplier's FAST_MUL mode is one cycle faster now; updated performance data |
46,8 → 49,8
| 06.08.2020 | 1.3.6.5 | Added `FAST_MUL_EN` generic to enable mapping of the multiplier core to DSP blocks; ALU.shifter is no more triggered when executing MULDIV operations; added benchmark results for DSP-based multiplier configurations; updated implementation and performance results; simplified makefiles – using implicit libc definition; crt0 only initializes lowest 16 registers |
| 03.08.2020 | [**:rocket:1.3.6.0**](https://github.com/stnolting/neorv32/releases/tag/v1.3.6.0) | Relocated `DEVNULL` (changed base address); minor edits, optimization and clean-ups |
| 30.07.2020 | 1.3.5.2 | Added register stage to PMP mask generation to shorten critical path; removed automatic IRQ enable/disable from RTE install/uninstall functions |
| 30.07.2020 | 1.3.5.1 | Fixed bug(s) in PMP mask generation; `misa.Z` flag is not yet defined by the RISC-V specs., hence it is read-only and read as zero |
| 29.07.2020 | 1.3.5.0 | Added user privilege level, enabled via new `CPU_EXTENSION_RISCV_U` generic; fixed error in `mstatus(mpie)` logic; implemented RISC-V spec.-compliant Physical Memory Protection (PMP); allows up to 8 regions but only NAPOT mode is supported yet |
| 30.07.2020 | 1.3.5.1 | :warning: Fixed bug(s) in PMP mask generation; `misa.Z` flag is not yet defined by the RISC-V specs., hence it is read-only and read as zero |
| 29.07.2020 | 1.3.5.0 | Added user privilege level, enabled via new `CPU_EXTENSION_RISCV_U` generic; :warning: fixed error in `mstatus(mpie)` logic; implemented RISC-V spec.-compliant Physical Memory Protection (PMP); allows up to 8 regions but only NAPOT mode is supported yet |
| 25.07.2020 | 1.3.0.0 | `mcause` CSR is read-only now!; removed `CLIC`, added 4 fast IRQ channels to CPU with according flags in `mie` and `mip` and trap IDs; updated core libraries; updated NEORV32 RTE; highly reworked data sheet; updated synthesis and performance results |
| 21.07.2020 | 1.2.0.6 | Added doc section regarding the CPU's data and instruction interfaces; optimized CPU fetch engine; updated iCE40 synthesis results |
| 20.07.2020 | 1.2.0.5 | Less penalty for taken branches and jumps (2 cycles faster) |
56,6 → 59,6
| 10.07.2020 | 1.0.6.0 | Non-taken branches are now 1 cycle faster; the `time[h]` CSR now correctly reflects the system time from the MTIME unit; fixed WFI instruction permanently stalling the CPU; `[m]cycle[h]` counters now stop counting when CPU is in sleep mode; `minstret[h]` and `mcycle[h]` now also allow write-access |
| 09.07.2020 | 1.0.5.0 | `X` flag of `misa` CSR is zero now; the default SPI flash boot address of the bootloader is now `0x0080000`; new exemplary FPGA utilization results for Intel, Lattice and Xilinx; `misa` CSR is read-only again, switching compressed extension on/off is pretty bad for the fetch engine; `mtval` and `mcause` CSRs now allow write accesses and are finally RISC-V-compliant; time low and high registers of `MTIME` peripheral can now also be written by user; `MTIME` registers only allow full-word write accesses |
| 06.07.2020 | 1.0.1.0 | Added missing `fence` instruction; added new generic to enable optional Zifencei CPU extension for instruction stream synchronization |
| 05.07.2020 | 1.0.0.0 | New CPU architecture: Fetch and execute engines; increased CPI; timer and counter CSRs are now all 64-bit wide; fixed CSR access errors; fixed `C.LW` decompression logic; `misa` flags `C` and `M` are now r/w – compressed mode and multiplier/divider support can be switched on/off during runtime; PC(0) is now always zero; fixed bug in multiplier/divider co-processor; renamed SPI signals; added RISC-V compliance check information – processor now passes the official RISC-V compliance tests |
| 05.07.2020 | 1.0.0.0 | New CPU architecture: Fetch and execute engines; increased CPI; timer and counter CSRs are now all 64-bit wide; :warning: fixed CSR access errors; fixed `C.LW` decompression logic; `misa` flags `C` and `M` are now r/w – compressed mode and multiplier/divider support can be switched on/off during runtime; PC(0) is now always zero; :warning: fixed bug in multiplier/divider co-processor; renamed SPI signals; added RISC-V compliance check information – processor now passes the official RISC-V compliance tests |
| 25.06.2020 | 0.0.2.5 | Added `DEVNULL` device; added chapter regarding processor simulation; fixed/added links; fixed typos; added FPGA implementation results for iCE40 UP |
| 23.06.2020 | [**:rocket:0.0.2.3**](https://github.com/stnolting/neorv32/releases/tag/v1.2.0.5) | Publication |
/neorv32/trunk/README.md
4,9 → 4,6
[![license](https://img.shields.io/github/license/stnolting/neorv32)](https://github.com/stnolting/neorv32/blob/master/LICENSE)
[![release](https://img.shields.io/github/v/release/stnolting/neorv32)](https://github.com/stnolting/neorv32/releases)
 
 
## Table of Content
 
* [Overview](#Overview)
* [Project Status](#Status)
* [Features](#Features)
75,6 → 72,7
* Fully synchronous design, no latches, no gated clocks
* Small hardware footprint and high operating frequency
* Highly configurable CPU and processor setup
* [AXI4-Lite connectivity](#AXI4-Connectivity) - compatible with Xilinx Vivado IP Packer
* [FreeRTOS port](https://github.com/stnolting/neorv32/blob/master/sw/example/demo_freeRTOS) available
 
 
102,13 → 100,13
| [RISC-V compliance test](https://github.com/stnolting/neorv32_riscv_compliance) | [![Build Status](https://travis-ci.com/stnolting/neorv32_riscv_compliance.svg?branch=master)](https://travis-ci.com/stnolting/neorv32_riscv_compliance) | |
 
 
### To-Do / Wish List
### To-Do / Wish List / [Help Wanted](#Contribute)
 
* Add a cache for the external memory interface
* Use LaTeX for data sheet
* Further size and performance optimization
* Add AXI(-Lite) bridges
* Synthesis results (+ wrappers?) for more platforms
* Maybe port additional RTOSs (like [Zephyr](https://github.com/zephyrproject-rtos/zephyr) or [RIOT](https://www.riot-os.org))
* Use LaTeX for data sheet
* Implement further CPU extensions:
* Atomic operations (`A`)
* Bitmanipulation operations (`B`), when they are "official"
121,7 → 119,7
The full-blown data sheet of the NEORV32 Processor and CPU is available as pdf file:
[![NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/PDF_32.png) NEORV32 data sheet](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/NEORV32.pdf).
 
### Processor Features
### NEORV32 Processor (SoC)
 
![neorv32 Overview](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_processor.png)
 
133,9 → 131,10
* Optional machine system timer (**MTIME**), RISC-V-compliant
* Optional universal asynchronous receiver and transmitter (**UART**) with simulation output option via text.io
* Optional 8/16/24/32-bit serial peripheral interface controller (**SPI**) with 8 dedicated chip select lines
* Optional two wire serial interface controller (**TWI**), compatible to the I²C standard
* Optional two wire serial interface controller (**TWI**), with optional clock-stretching, compatible to the I²C standard
* Optional general purpose parallel IO port (**GPIO**), 32xOut & 32xIn, with pin-change interrupt
* Optional 32-bit external bus interface, Wishbone b4 compliant (**WISHBONE**), *standard* or *pipelined* handshake/transactions mode
* Optional wrapper for **AXI4-Lite Master Interface** (see [AXI Connectivity](#AXI4-Connectivity)), compatibility verified with Xilinx Vivado Block Desginer
* Optional watchdog timer (**WDT**)
* Optional PWM controller with 4 channels and 8-bit duty cycle resolution (**PWM**)
* Optional GARO-based true random number generator (**TRNG**)
142,7 → 141,7
* Optional custom functions units (**CFU0** and **CFU1**) for tightly-coupled custom co-processors
* System configuration information memory to check hardware configuration by software (**SYSINFO**)
 
### CPU Features
### NEORV32 CPU
 
![neorv32 Overview](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_cpu.png)
 
272,7 → 271,7
| TWI | Two-wire interface | 74 | 44 | 0 | 0 |
| UART | Universal asynchronous receiver/transmitter | 175 | 132 | 0 | 0 |
| WDT | Watchdog timer | 58 | 45 | 0 | 0 |
| WISHBONE | External memory interface (`MEM_EXT_REG_STAGES` = 2) | 106 | 104 | 0 | 0 |
| WISHBONE | External memory interface | 106 | 104 | 0 | 0 |
 
 
### NEORV32 Processor - Exemplary FPGA Setups
421,6 → 420,7
i_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
i_bus_err_i : in std_ulogic := '0'; -- bus transfer error
i_bus_fence_o : out std_ulogic; -- executed FENCEI operation
i_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- data bus interface --
d_bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
d_bus_rdata_i : in std_ulogic_vector(data_width_c-1 downto 0) := (others => '0'); -- bus read data
432,6 → 432,7
d_bus_ack_i : in std_ulogic := '0'; -- bus transfer acknowledge
d_bus_err_i : in std_ulogic := '0'; -- bus transfer error
d_bus_fence_o : out std_ulogic; -- executed FENCE operation
d_bus_priv_o : out std_ulogic_vector(1 downto 0); -- privilege level
-- system time input from MTIME --
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time
-- interrupts (risc-v compliant) --
444,7 → 445,6
end neorv32_cpu;
```
 
 
### NEORV32 Processor
 
```vhdl
477,7 → 477,6
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes
-- External memory interface --
MEM_EXT_USE : boolean := false; -- implement external memory bus interface?
MEM_EXT_REG_STAGES : natural := 2; -- number of interface register stages (0,1,2)
-- Processor peripherals --
IO_GPIO_USE : boolean := true; -- implement general purpose input/output port unit (GPIO)?
IO_MTIME_USE : boolean := true; -- implement machine system timer (MTIME)?
505,6 → 504,7
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge
wb_err_i : in std_ulogic := '0'; -- transfer error
-- Advanced memory control signals (available if MEM_EXT_USE = true) --
priv_o : out std_ulogic_vector(1 downto 0); -- current CPU privilege level
fence_o : out std_ulogic; -- indicates an executed FENCE operation
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation
-- GPIO (available if IO_GPIO_USE = true) --
519,8 → 519,8
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- TWI (available if IO_TWI_USE = true) --
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
twi_scl_io : inout std_logic := 'H'; -- twi serial clock line
twi_sda_io : inout std_logic; -- twi serial data line
twi_scl_io : inout std_logic; -- twi serial clock line
-- PWM (available if IO_PWM_USE = true) --
pwm_o : out std_ulogic_vector(03 downto 0); -- pwm channels
-- Interrupts --
531,8 → 531,27
end neorv32_top;
```
 
### AXI4 Connectivity
 
Via the [`rtl/top_templates/neorv32_top_axi4lite.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/top_templates/neorv32_top_axi4lite.vhd)
wrapper the NEORV32 provides an **AXI4-Lite** compatible master interface. This wrapper instantiates the default
[NEORV32 processor top entitiy](https://github.com/stnolting/neorv32/blob/master/rtl/core/neorv32_top.vhd) and implements a Wishbone to AXI4-Lite bridge.
 
The AXI4-Lite interface has been tested using Xilinx Vivado 19.2 block designer:
 
![AXI-SoC](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/neorv32_axi_soc.png)
 
The processor was packed as custom IP using `neorv32_top_axi4lite.vhd` as top entity. The AXI interface is automatically detected by the packager.
All remaining IO interfaces are available as custom signals. The configuration generics are available via the "customize IP" dialog.
In the figure above the resulting IP block is named "neorv32_top_axi4lite_v1_0".
*(Note: Use Syntheiss option "global" when generating the block design to maintain the internal TWI tri-state drivers.)*
 
The setup uses an AXI interconnect to attach two block RAMs to the processor. Since the processor in this example is configured *without* IMEM and DMEM,
the attached block RAMs are used for storing instructions and data: the first RAM is used as instruction memory
and is mapped to address `0x00000000 - 0x00003fff` (16kB), the second RAM is used as data memory and is mapped to address `0x80000000 - 0x80001fff` (8kB).
 
 
 
## Getting Started
 
This overview is just a short excerpt from the *Let's Get It Started* section of the NEORV32 documentary:
737,16 → 756,14
 
"Artix" and "Vivado" are trademarks of Xilinx Inc.
 
"Cyclone", "Quartus Prime", "Quartus Prime Lite" and "Avalon Bus" are trademarks of Intel Corporation.
"Cyclone", "Quartus Prime Lite" and "Avalon Bus" are trademarks of Intel Corporation.
 
"Artix" and "Vivado" are trademarks of Xilinx, Inc.
"iCE40", "UltraPlus" and "Radiant" are trademarks of Lattice Semiconductor Corporation.
 
"iCE40", "UltraPlus" and "Lattice Radiant" are trademarks of Lattice Semiconductor Corporation.
"AXI", "AXI4" and "AXI4-Lite" are trademarks of Arm Holdings plc.
 
"AXI" and "AXI-Lite" are trademarks of Arm Holdings plc.
 
 
 
## Acknowledgements
 
[![RISC-V](https://raw.githubusercontent.com/stnolting/neorv32/master/docs/figures/riscv_logo.png)](https://riscv.org/)

powered by: WebSVN 2.1.0

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