URL
https://opencores.org/ocsvn/neorv32/neorv32/trunk
Subversion Repositories neorv32
Compare Revisions
- This comparison shows the changes necessary to convert path
/neorv32/trunk/rtl/core
- from Rev 56 to Rev 57
- ↔ Reverse comparison
Rev 56 → Rev 57
/neorv32_bootloader_image.vhd
6,7 → 6,7
|
package neorv32_bootloader_image is |
|
type bootloader_init_image_t is array (0 to 1014) of std_ulogic_vector(31 downto 0); |
type bootloader_init_image_t is array (0 to 1021) of std_ulogic_vector(31 downto 0); |
constant bootloader_init_image : bootloader_init_image_t := ( |
00000000 => x"00000093", |
00000001 => x"00000113", |
52,7 → 52,7
00000041 => x"00158593", |
00000042 => x"ff5ff06f", |
00000043 => x"00001597", |
00000044 => x"f2c58593", |
00000044 => x"f4858593", |
00000045 => x"80010617", |
00000046 => x"f4c60613", |
00000047 => x"80010697", |
111,20 → 111,20
00000100 => x"00200513", |
00000101 => x"0087f463", |
00000102 => x"00400513", |
00000103 => x"36d000ef", |
00000103 => x"389000ef", |
00000104 => x"00100513", |
00000105 => x"40d000ef", |
00000105 => x"429000ef", |
00000106 => x"00005537", |
00000107 => x"00000613", |
00000108 => x"00000593", |
00000109 => x"b0050513", |
00000110 => x"2a9000ef", |
00000111 => x"1c5000ef", |
00000110 => x"2b5000ef", |
00000111 => x"1d1000ef", |
00000112 => x"00245793", |
00000113 => x"00a78533", |
00000114 => x"00f537b3", |
00000115 => x"00b785b3", |
00000116 => x"1dd000ef", |
00000116 => x"1e9000ef", |
00000117 => x"ffff07b7", |
00000118 => x"4d478793", |
00000119 => x"30579073", |
134,78 → 134,78
00000123 => x"00000013", |
00000124 => x"00000013", |
00000125 => x"ffff1537", |
00000126 => x"eec50513", |
00000127 => x"309000ef", |
00000126 => x"f0850513", |
00000127 => x"315000ef", |
00000128 => x"f1302573", |
00000129 => x"260000ef", |
00000130 => x"ffff1537", |
00000131 => x"f2450513", |
00000132 => x"2f5000ef", |
00000131 => x"f4050513", |
00000132 => x"301000ef", |
00000133 => x"fe002503", |
00000134 => x"24c000ef", |
00000135 => x"ffff1537", |
00000136 => x"f2c50513", |
00000137 => x"2e1000ef", |
00000136 => x"f4850513", |
00000137 => x"2ed000ef", |
00000138 => x"fe402503", |
00000139 => x"238000ef", |
00000140 => x"ffff1537", |
00000141 => x"f3450513", |
00000142 => x"2cd000ef", |
00000141 => x"f5050513", |
00000142 => x"2d9000ef", |
00000143 => x"30102573", |
00000144 => x"224000ef", |
00000145 => x"ffff1537", |
00000146 => x"f3c50513", |
00000147 => x"2b9000ef", |
00000146 => x"f5850513", |
00000147 => x"2c5000ef", |
00000148 => x"fc002573", |
00000149 => x"210000ef", |
00000150 => x"ffff1537", |
00000151 => x"f4450513", |
00000152 => x"2a5000ef", |
00000151 => x"f6050513", |
00000152 => x"2b1000ef", |
00000153 => x"fe802503", |
00000154 => x"ffff14b7", |
00000155 => x"00341413", |
00000156 => x"1f4000ef", |
00000157 => x"ffff1537", |
00000158 => x"f4c50513", |
00000159 => x"289000ef", |
00000158 => x"f6850513", |
00000159 => x"295000ef", |
00000160 => x"ff802503", |
00000161 => x"1e0000ef", |
00000162 => x"f5448513", |
00000163 => x"279000ef", |
00000162 => x"f7048513", |
00000163 => x"285000ef", |
00000164 => x"ff002503", |
00000165 => x"1d0000ef", |
00000166 => x"ffff1537", |
00000167 => x"f6050513", |
00000168 => x"265000ef", |
00000167 => x"f7c50513", |
00000168 => x"271000ef", |
00000169 => x"ffc02503", |
00000170 => x"1bc000ef", |
00000171 => x"f5448513", |
00000172 => x"255000ef", |
00000171 => x"f7048513", |
00000172 => x"261000ef", |
00000173 => x"ff402503", |
00000174 => x"1ac000ef", |
00000175 => x"ffff1537", |
00000176 => x"f6850513", |
00000177 => x"241000ef", |
00000178 => x"0b9000ef", |
00000176 => x"f8450513", |
00000177 => x"24d000ef", |
00000178 => x"0c5000ef", |
00000179 => x"00a404b3", |
00000180 => x"0084b433", |
00000181 => x"00b40433", |
00000182 => x"1d1000ef", |
00000182 => x"1dd000ef", |
00000183 => x"02050263", |
00000184 => x"ffff1537", |
00000185 => x"f9450513", |
00000186 => x"21d000ef", |
00000187 => x"0d9000ef", |
00000185 => x"fb050513", |
00000186 => x"229000ef", |
00000187 => x"0e5000ef", |
00000188 => x"02300793", |
00000189 => x"02f51263", |
00000190 => x"00000513", |
00000191 => x"0180006f", |
00000192 => x"081000ef", |
00000192 => x"08d000ef", |
00000193 => x"fc85eae3", |
00000194 => x"00b41463", |
00000195 => x"fc9566e3", |
00000196 => x"00100513", |
00000197 => x"5dc000ef", |
00000197 => x"5e8000ef", |
00000198 => x"0b4000ef", |
00000199 => x"ffff1937", |
00000200 => x"ffff19b7", |
215,13 → 215,13
00000204 => x"07500b93", |
00000205 => x"ffff14b7", |
00000206 => x"ffff1c37", |
00000207 => x"fa090513", |
00000208 => x"1c5000ef", |
00000209 => x"155000ef", |
00000207 => x"fbc90513", |
00000208 => x"1d1000ef", |
00000209 => x"161000ef", |
00000210 => x"00050413", |
00000211 => x"129000ef", |
00000212 => x"ea498513", |
00000213 => x"1b1000ef", |
00000211 => x"135000ef", |
00000212 => x"ec098513", |
00000213 => x"1bd000ef", |
00000214 => x"fb4400e3", |
00000215 => x"01541863", |
00000216 => x"ffff02b7", |
234,7 → 234,7
00000223 => x"03740063", |
00000224 => x"07300793", |
00000225 => x"00f41663", |
00000226 => x"67c000ef", |
00000226 => x"688000ef", |
00000227 => x"fb1ff06f", |
00000228 => x"06c00793", |
00000229 => x"00f41863", |
246,20 → 246,20
00000235 => x"02c000ef", |
00000236 => x"f8dff06f", |
00000237 => x"03f00793", |
00000238 => x"fa8c0513", |
00000238 => x"fc4c0513", |
00000239 => x"00f40463", |
00000240 => x"fbc48513", |
00000241 => x"141000ef", |
00000240 => x"fd848513", |
00000241 => x"14d000ef", |
00000242 => x"f75ff06f", |
00000243 => x"ffff1537", |
00000244 => x"db850513", |
00000245 => x"1310006f", |
00000244 => x"dd450513", |
00000245 => x"13d0006f", |
00000246 => x"800007b7", |
00000247 => x"0007a783", |
00000248 => x"00079863", |
00000249 => x"ffff1537", |
00000250 => x"e1c50513", |
00000251 => x"1190006f", |
00000250 => x"e3850513", |
00000251 => x"1250006f", |
00000252 => x"ff010113", |
00000253 => x"00112623", |
00000254 => x"30047073", |
266,9 → 266,9
00000255 => x"00000013", |
00000256 => x"00000013", |
00000257 => x"ffff1537", |
00000258 => x"e3850513", |
00000259 => x"0f9000ef", |
00000260 => x"075000ef", |
00000258 => x"e5450513", |
00000259 => x"105000ef", |
00000260 => x"081000ef", |
00000261 => x"fe051ee3", |
00000262 => x"ff002783", |
00000263 => x"00078067", |
277,17 → 277,17
00000266 => x"00812423", |
00000267 => x"00050413", |
00000268 => x"ffff1537", |
00000269 => x"e4850513", |
00000269 => x"e6450513", |
00000270 => x"00112623", |
00000271 => x"0c9000ef", |
00000271 => x"0d5000ef", |
00000272 => x"03040513", |
00000273 => x"0ff57513", |
00000274 => x"02d000ef", |
00000274 => x"039000ef", |
00000275 => x"30047073", |
00000276 => x"00000013", |
00000277 => x"00000013", |
00000278 => x"00100513", |
00000279 => x"155000ef", |
00000279 => x"171000ef", |
00000280 => x"0000006f", |
00000281 => x"fe010113", |
00000282 => x"01212823", |
294,14 → 294,14
00000283 => x"00050913", |
00000284 => x"ffff1537", |
00000285 => x"00912a23", |
00000286 => x"e5450513", |
00000286 => x"e7050513", |
00000287 => x"ffff14b7", |
00000288 => x"00812c23", |
00000289 => x"01312623", |
00000290 => x"00112e23", |
00000291 => x"01c00413", |
00000292 => x"075000ef", |
00000293 => x"fc848493", |
00000292 => x"081000ef", |
00000293 => x"fe448493", |
00000294 => x"ffc00993", |
00000295 => x"008957b3", |
00000296 => x"00f7f793", |
308,7 → 308,7
00000297 => x"00f487b3", |
00000298 => x"0007c503", |
00000299 => x"ffc40413", |
00000300 => x"7c4000ef", |
00000300 => x"7d0000ef", |
00000301 => x"ff3414e3", |
00000302 => x"01c12083", |
00000303 => x"01812403", |
340,14 → 340,14
00000329 => x"00778793", |
00000330 => x"06f41a63", |
00000331 => x"00000513", |
00000332 => x"065000ef", |
00000333 => x"64c000ef", |
00000332 => x"081000ef", |
00000333 => x"658000ef", |
00000334 => x"fe002783", |
00000335 => x"0027d793", |
00000336 => x"00a78533", |
00000337 => x"00f537b3", |
00000338 => x"00b785b3", |
00000339 => x"660000ef", |
00000339 => x"66c000ef", |
00000340 => x"03c12403", |
00000341 => x"04c12083", |
00000342 => x"04812283", |
373,13 → 373,13
00000362 => x"00100513", |
00000363 => x"02079863", |
00000364 => x"ffff1537", |
00000365 => x"e5850513", |
00000366 => x"74c000ef", |
00000365 => x"e7450513", |
00000366 => x"758000ef", |
00000367 => x"00040513", |
00000368 => x"ea5ff0ef", |
00000369 => x"ffff1537", |
00000370 => x"e6c50513", |
00000371 => x"738000ef", |
00000370 => x"e8850513", |
00000371 => x"744000ef", |
00000372 => x"34102573", |
00000373 => x"e91ff0ef", |
00000374 => x"00500513", |
388,14 → 388,14
00000377 => x"00000513", |
00000378 => x"00112623", |
00000379 => x"00812423", |
00000380 => x"74c000ef", |
00000380 => x"768000ef", |
00000381 => x"09e00513", |
00000382 => x"788000ef", |
00000382 => x"7a4000ef", |
00000383 => x"00000513", |
00000384 => x"780000ef", |
00000384 => x"79c000ef", |
00000385 => x"00050413", |
00000386 => x"00000513", |
00000387 => x"750000ef", |
00000387 => x"76c000ef", |
00000388 => x"00c12083", |
00000389 => x"0ff47513", |
00000390 => x"00812403", |
405,15 → 405,15
00000394 => x"00112623", |
00000395 => x"00812423", |
00000396 => x"00000513", |
00000397 => x"708000ef", |
00000397 => x"724000ef", |
00000398 => x"00500513", |
00000399 => x"744000ef", |
00000399 => x"760000ef", |
00000400 => x"00000513", |
00000401 => x"73c000ef", |
00000401 => x"758000ef", |
00000402 => x"00050413", |
00000403 => x"00147413", |
00000404 => x"00000513", |
00000405 => x"708000ef", |
00000405 => x"724000ef", |
00000406 => x"fc041ce3", |
00000407 => x"00c12083", |
00000408 => x"00812403", |
422,13 → 422,13
00000411 => x"ff010113", |
00000412 => x"00000513", |
00000413 => x"00112623", |
00000414 => x"6c4000ef", |
00000414 => x"6e0000ef", |
00000415 => x"00600513", |
00000416 => x"700000ef", |
00000416 => x"71c000ef", |
00000417 => x"00c12083", |
00000418 => x"00000513", |
00000419 => x"01010113", |
00000420 => x"6cc0006f", |
00000420 => x"6e80006f", |
00000421 => x"ff010113", |
00000422 => x"00812423", |
00000423 => x"00050413", |
435,30 → 435,30
00000424 => x"01055513", |
00000425 => x"0ff57513", |
00000426 => x"00112623", |
00000427 => x"6d4000ef", |
00000427 => x"6f0000ef", |
00000428 => x"00845513", |
00000429 => x"0ff57513", |
00000430 => x"6c8000ef", |
00000430 => x"6e4000ef", |
00000431 => x"0ff47513", |
00000432 => x"00812403", |
00000433 => x"00c12083", |
00000434 => x"01010113", |
00000435 => x"6b40006f", |
00000435 => x"6d00006f", |
00000436 => x"ff010113", |
00000437 => x"00812423", |
00000438 => x"00050413", |
00000439 => x"00000513", |
00000440 => x"00112623", |
00000441 => x"658000ef", |
00000441 => x"674000ef", |
00000442 => x"00300513", |
00000443 => x"694000ef", |
00000443 => x"6b0000ef", |
00000444 => x"00040513", |
00000445 => x"fa1ff0ef", |
00000446 => x"00000513", |
00000447 => x"684000ef", |
00000447 => x"6a0000ef", |
00000448 => x"00050413", |
00000449 => x"00000513", |
00000450 => x"654000ef", |
00000450 => x"670000ef", |
00000451 => x"00c12083", |
00000452 => x"0ff47513", |
00000453 => x"00812403", |
477,7 → 477,7
00000466 => x"00000413", |
00000467 => x"00400a13", |
00000468 => x"02091e63", |
00000469 => x"544000ef", |
00000469 => x"550000ef", |
00000470 => x"00a481a3", |
00000471 => x"00140413", |
00000472 => x"fff48493", |
519,509 → 519,516
00000508 => x"04079663", |
00000509 => x"02041863", |
00000510 => x"ffff1537", |
00000511 => x"e7450513", |
00000512 => x"504000ef", |
00000511 => x"e9050513", |
00000512 => x"510000ef", |
00000513 => x"008005b7", |
00000514 => x"00040513", |
00000515 => x"f15ff0ef", |
00000516 => x"4788d7b7", |
00000517 => x"afe78793", |
00000518 => x"02f50463", |
00000518 => x"02f50a63", |
00000519 => x"00000513", |
00000520 => x"01c0006f", |
00000521 => x"ffff1537", |
00000522 => x"e9450513", |
00000523 => x"4d8000ef", |
00000524 => x"db1ff0ef", |
00000525 => x"fc0518e3", |
00000522 => x"eb050513", |
00000523 => x"4e4000ef", |
00000524 => x"4e4000ef", |
00000525 => x"00051663", |
00000526 => x"00300513", |
00000527 => x"be9ff0ef", |
00000528 => x"008009b7", |
00000529 => x"00498593", |
00000530 => x"00040513", |
00000531 => x"ed5ff0ef", |
00000532 => x"00050a93", |
00000533 => x"00898593", |
00000534 => x"00040513", |
00000535 => x"ec5ff0ef", |
00000536 => x"ff002c03", |
00000537 => x"00050b13", |
00000538 => x"ffcafb93", |
00000539 => x"00000913", |
00000540 => x"00000493", |
00000541 => x"00c98993", |
00000542 => x"013905b3", |
00000543 => x"052b9c63", |
00000544 => x"016484b3", |
00000545 => x"00200513", |
00000546 => x"fa049ae3", |
00000547 => x"ffff1537", |
00000548 => x"ea050513", |
00000549 => x"470000ef", |
00000550 => x"02c12083", |
00000551 => x"02812403", |
00000552 => x"800007b7", |
00000553 => x"0157a023", |
00000554 => x"000a2023", |
00000555 => x"02412483", |
00000556 => x"02012903", |
00000557 => x"01c12983", |
00000558 => x"01812a03", |
00000559 => x"01412a83", |
00000560 => x"01012b03", |
00000561 => x"00c12b83", |
00000562 => x"00812c03", |
00000563 => x"03010113", |
00000564 => x"00008067", |
00000565 => x"00040513", |
00000566 => x"e49ff0ef", |
00000567 => x"012c07b3", |
00000568 => x"00a484b3", |
00000569 => x"00a7a023", |
00000570 => x"00490913", |
00000571 => x"f8dff06f", |
00000572 => x"ff010113", |
00000573 => x"00112623", |
00000574 => x"ea1ff0ef", |
00000575 => x"ffff1537", |
00000576 => x"ea450513", |
00000577 => x"400000ef", |
00000578 => x"ad1ff0ef", |
00000579 => x"0000006f", |
00000580 => x"ff010113", |
00000581 => x"00112623", |
00000582 => x"00812423", |
00000583 => x"00912223", |
00000584 => x"00058413", |
00000585 => x"00050493", |
00000586 => x"d45ff0ef", |
00000587 => x"00000513", |
00000588 => x"40c000ef", |
00000589 => x"00200513", |
00000590 => x"448000ef", |
00000591 => x"00048513", |
00000592 => x"d55ff0ef", |
00000593 => x"00040513", |
00000594 => x"438000ef", |
00000595 => x"00000513", |
00000596 => x"40c000ef", |
00000597 => x"00812403", |
00000598 => x"00c12083", |
00000599 => x"00412483", |
00000600 => x"01010113", |
00000601 => x"cc1ff06f", |
00000602 => x"fe010113", |
00000603 => x"00812c23", |
00000604 => x"00912a23", |
00000605 => x"01212823", |
00000606 => x"00112e23", |
00000607 => x"00b12623", |
00000608 => x"00300413", |
00000609 => x"00350493", |
00000610 => x"fff00913", |
00000611 => x"00c10793", |
00000612 => x"008787b3", |
00000613 => x"0007c583", |
00000614 => x"40848533", |
00000615 => x"fff40413", |
00000616 => x"f71ff0ef", |
00000617 => x"ff2414e3", |
00000618 => x"01c12083", |
00000619 => x"01812403", |
00000620 => x"01412483", |
00000621 => x"01012903", |
00000622 => x"02010113", |
00000623 => x"00008067", |
00000624 => x"ff010113", |
00000625 => x"00112623", |
00000626 => x"00812423", |
00000627 => x"00050413", |
00000628 => x"c9dff0ef", |
00000629 => x"00000513", |
00000630 => x"364000ef", |
00000631 => x"0d800513", |
00000632 => x"3a0000ef", |
00000633 => x"00040513", |
00000634 => x"cadff0ef", |
00000635 => x"00000513", |
00000636 => x"36c000ef", |
00000637 => x"00812403", |
00000638 => x"00c12083", |
00000639 => x"01010113", |
00000640 => x"c25ff06f", |
00000641 => x"fe010113", |
00000642 => x"800007b7", |
00000643 => x"00812c23", |
00000644 => x"0007a403", |
00000645 => x"00112e23", |
00000646 => x"00912a23", |
00000647 => x"01212823", |
00000648 => x"01312623", |
00000649 => x"01412423", |
00000650 => x"01512223", |
00000651 => x"02041863", |
00000652 => x"ffff1537", |
00000653 => x"e1c50513", |
00000654 => x"01812403", |
00000655 => x"01c12083", |
00000656 => x"01412483", |
00000657 => x"01012903", |
00000658 => x"00c12983", |
00000659 => x"00812a03", |
00000660 => x"00412a83", |
00000661 => x"02010113", |
00000662 => x"2ac0006f", |
00000663 => x"ffff1537", |
00000664 => x"ea850513", |
00000665 => x"2a0000ef", |
00000666 => x"00040513", |
00000667 => x"9f9ff0ef", |
00000668 => x"ffff1537", |
00000669 => x"eb450513", |
00000670 => x"28c000ef", |
00000671 => x"00800537", |
00000672 => x"9e5ff0ef", |
00000673 => x"ffff1537", |
00000674 => x"ed050513", |
00000675 => x"278000ef", |
00000676 => x"208000ef", |
00000677 => x"00050493", |
00000678 => x"1dc000ef", |
00000679 => x"07900793", |
00000680 => x"0af49e63", |
00000681 => x"b3dff0ef", |
00000682 => x"00051663", |
00000683 => x"00300513", |
00000684 => x"975ff0ef", |
00000685 => x"ffff1537", |
00000686 => x"edc50513", |
00000687 => x"01045493", |
00000688 => x"244000ef", |
00000689 => x"00148493", |
00000690 => x"00800937", |
00000691 => x"fff00993", |
00000692 => x"00010a37", |
00000693 => x"fff48493", |
00000694 => x"07349063", |
00000695 => x"4788d5b7", |
00000696 => x"afe58593", |
00000697 => x"00800537", |
00000698 => x"e81ff0ef", |
00000699 => x"00800537", |
00000700 => x"00040593", |
00000701 => x"00450513", |
00000702 => x"e71ff0ef", |
00000703 => x"ff002a03", |
00000704 => x"008009b7", |
00000705 => x"ffc47413", |
00000706 => x"00000493", |
00000707 => x"00000913", |
00000708 => x"00c98a93", |
00000709 => x"01548533", |
00000710 => x"009a07b3", |
00000711 => x"02849663", |
00000712 => x"00898513", |
00000713 => x"412005b3", |
00000714 => x"e41ff0ef", |
00000715 => x"ffff1537", |
00000716 => x"ea050513", |
00000717 => x"f05ff06f", |
00000718 => x"00090513", |
00000719 => x"e85ff0ef", |
00000720 => x"01490933", |
00000721 => x"f91ff06f", |
00000722 => x"0007a583", |
00000723 => x"00448493", |
00000724 => x"00b90933", |
00000725 => x"e15ff0ef", |
00000726 => x"fbdff06f", |
00000727 => x"01c12083", |
00000728 => x"01812403", |
00000729 => x"01412483", |
00000730 => x"01012903", |
00000731 => x"00c12983", |
00000732 => x"00812a03", |
00000733 => x"00412a83", |
00000734 => x"02010113", |
00000735 => x"00008067", |
00000736 => x"ff010113", |
00000737 => x"f9402783", |
00000738 => x"f9002703", |
00000739 => x"f9402683", |
00000740 => x"fed79ae3", |
00000741 => x"00e12023", |
00000742 => x"00f12223", |
00000743 => x"00012503", |
00000744 => x"00412583", |
00000745 => x"01010113", |
00000746 => x"00008067", |
00000747 => x"f9800693", |
00000748 => x"fff00613", |
00000749 => x"00c6a023", |
00000750 => x"00a6a023", |
00000751 => x"00b6a223", |
00000752 => x"00008067", |
00000753 => x"fa402503", |
00000754 => x"0ff57513", |
00000528 => x"da1ff0ef", |
00000529 => x"fc0510e3", |
00000530 => x"ff1ff06f", |
00000531 => x"008009b7", |
00000532 => x"00498593", |
00000533 => x"00040513", |
00000534 => x"ec9ff0ef", |
00000535 => x"00050a93", |
00000536 => x"00898593", |
00000537 => x"00040513", |
00000538 => x"eb9ff0ef", |
00000539 => x"ff002c03", |
00000540 => x"00050b13", |
00000541 => x"ffcafb93", |
00000542 => x"00000913", |
00000543 => x"00000493", |
00000544 => x"00c98993", |
00000545 => x"013905b3", |
00000546 => x"052b9c63", |
00000547 => x"016484b3", |
00000548 => x"00200513", |
00000549 => x"fa0494e3", |
00000550 => x"ffff1537", |
00000551 => x"ebc50513", |
00000552 => x"470000ef", |
00000553 => x"02c12083", |
00000554 => x"02812403", |
00000555 => x"800007b7", |
00000556 => x"0157a023", |
00000557 => x"000a2023", |
00000558 => x"02412483", |
00000559 => x"02012903", |
00000560 => x"01c12983", |
00000561 => x"01812a03", |
00000562 => x"01412a83", |
00000563 => x"01012b03", |
00000564 => x"00c12b83", |
00000565 => x"00812c03", |
00000566 => x"03010113", |
00000567 => x"00008067", |
00000568 => x"00040513", |
00000569 => x"e3dff0ef", |
00000570 => x"012c07b3", |
00000571 => x"00a484b3", |
00000572 => x"00a7a023", |
00000573 => x"00490913", |
00000574 => x"f8dff06f", |
00000575 => x"ff010113", |
00000576 => x"00112623", |
00000577 => x"e95ff0ef", |
00000578 => x"ffff1537", |
00000579 => x"ec050513", |
00000580 => x"400000ef", |
00000581 => x"ac5ff0ef", |
00000582 => x"0000006f", |
00000583 => x"ff010113", |
00000584 => x"00112623", |
00000585 => x"00812423", |
00000586 => x"00912223", |
00000587 => x"00058413", |
00000588 => x"00050493", |
00000589 => x"d39ff0ef", |
00000590 => x"00000513", |
00000591 => x"41c000ef", |
00000592 => x"00200513", |
00000593 => x"458000ef", |
00000594 => x"00048513", |
00000595 => x"d49ff0ef", |
00000596 => x"00040513", |
00000597 => x"448000ef", |
00000598 => x"00000513", |
00000599 => x"41c000ef", |
00000600 => x"00812403", |
00000601 => x"00c12083", |
00000602 => x"00412483", |
00000603 => x"01010113", |
00000604 => x"cb5ff06f", |
00000605 => x"fe010113", |
00000606 => x"00812c23", |
00000607 => x"00912a23", |
00000608 => x"01212823", |
00000609 => x"00112e23", |
00000610 => x"00b12623", |
00000611 => x"00300413", |
00000612 => x"00350493", |
00000613 => x"fff00913", |
00000614 => x"00c10793", |
00000615 => x"008787b3", |
00000616 => x"0007c583", |
00000617 => x"40848533", |
00000618 => x"fff40413", |
00000619 => x"f71ff0ef", |
00000620 => x"ff2414e3", |
00000621 => x"01c12083", |
00000622 => x"01812403", |
00000623 => x"01412483", |
00000624 => x"01012903", |
00000625 => x"02010113", |
00000626 => x"00008067", |
00000627 => x"ff010113", |
00000628 => x"00112623", |
00000629 => x"00812423", |
00000630 => x"00050413", |
00000631 => x"c91ff0ef", |
00000632 => x"00000513", |
00000633 => x"374000ef", |
00000634 => x"0d800513", |
00000635 => x"3b0000ef", |
00000636 => x"00040513", |
00000637 => x"ca1ff0ef", |
00000638 => x"00000513", |
00000639 => x"37c000ef", |
00000640 => x"00812403", |
00000641 => x"00c12083", |
00000642 => x"01010113", |
00000643 => x"c19ff06f", |
00000644 => x"fe010113", |
00000645 => x"800007b7", |
00000646 => x"00812c23", |
00000647 => x"0007a403", |
00000648 => x"00112e23", |
00000649 => x"00912a23", |
00000650 => x"01212823", |
00000651 => x"01312623", |
00000652 => x"01412423", |
00000653 => x"01512223", |
00000654 => x"02041863", |
00000655 => x"ffff1537", |
00000656 => x"e3850513", |
00000657 => x"01812403", |
00000658 => x"01c12083", |
00000659 => x"01412483", |
00000660 => x"01012903", |
00000661 => x"00c12983", |
00000662 => x"00812a03", |
00000663 => x"00412a83", |
00000664 => x"02010113", |
00000665 => x"2ac0006f", |
00000666 => x"ffff1537", |
00000667 => x"ec450513", |
00000668 => x"2a0000ef", |
00000669 => x"00040513", |
00000670 => x"9edff0ef", |
00000671 => x"ffff1537", |
00000672 => x"ed050513", |
00000673 => x"28c000ef", |
00000674 => x"00800537", |
00000675 => x"9d9ff0ef", |
00000676 => x"ffff1537", |
00000677 => x"eec50513", |
00000678 => x"278000ef", |
00000679 => x"208000ef", |
00000680 => x"00050493", |
00000681 => x"1dc000ef", |
00000682 => x"07900793", |
00000683 => x"0af49e63", |
00000684 => x"b31ff0ef", |
00000685 => x"00051663", |
00000686 => x"00300513", |
00000687 => x"969ff0ef", |
00000688 => x"ffff1537", |
00000689 => x"ef850513", |
00000690 => x"01045493", |
00000691 => x"244000ef", |
00000692 => x"00148493", |
00000693 => x"00800937", |
00000694 => x"fff00993", |
00000695 => x"00010a37", |
00000696 => x"fff48493", |
00000697 => x"07349063", |
00000698 => x"4788d5b7", |
00000699 => x"afe58593", |
00000700 => x"00800537", |
00000701 => x"e81ff0ef", |
00000702 => x"00800537", |
00000703 => x"00040593", |
00000704 => x"00450513", |
00000705 => x"e71ff0ef", |
00000706 => x"ff002a03", |
00000707 => x"008009b7", |
00000708 => x"ffc47413", |
00000709 => x"00000493", |
00000710 => x"00000913", |
00000711 => x"00c98a93", |
00000712 => x"01548533", |
00000713 => x"009a07b3", |
00000714 => x"02849663", |
00000715 => x"00898513", |
00000716 => x"412005b3", |
00000717 => x"e41ff0ef", |
00000718 => x"ffff1537", |
00000719 => x"ebc50513", |
00000720 => x"f05ff06f", |
00000721 => x"00090513", |
00000722 => x"e85ff0ef", |
00000723 => x"01490933", |
00000724 => x"f91ff06f", |
00000725 => x"0007a583", |
00000726 => x"00448493", |
00000727 => x"00b90933", |
00000728 => x"e15ff0ef", |
00000729 => x"fbdff06f", |
00000730 => x"01c12083", |
00000731 => x"01812403", |
00000732 => x"01412483", |
00000733 => x"01012903", |
00000734 => x"00c12983", |
00000735 => x"00812a03", |
00000736 => x"00412a83", |
00000737 => x"02010113", |
00000738 => x"00008067", |
00000739 => x"ff010113", |
00000740 => x"f9402783", |
00000741 => x"f9002703", |
00000742 => x"f9402683", |
00000743 => x"fed79ae3", |
00000744 => x"00e12023", |
00000745 => x"00f12223", |
00000746 => x"00012503", |
00000747 => x"00412583", |
00000748 => x"01010113", |
00000749 => x"00008067", |
00000750 => x"f9800693", |
00000751 => x"fff00613", |
00000752 => x"00c6a023", |
00000753 => x"00a6a023", |
00000754 => x"00b6a223", |
00000755 => x"00008067", |
00000756 => x"fa002023", |
00000757 => x"fe002703", |
00000758 => x"00151513", |
00000759 => x"00000793", |
00000760 => x"04a77463", |
00000761 => x"000016b7", |
00000762 => x"00000713", |
00000763 => x"ffe68693", |
00000764 => x"04f6e663", |
00000765 => x"00367613", |
00000766 => x"0035f593", |
00000767 => x"fff78793", |
00000768 => x"01461613", |
00000769 => x"00c7e7b3", |
00000770 => x"01659593", |
00000771 => x"01871713", |
00000772 => x"00b7e7b3", |
00000773 => x"00e7e7b3", |
00000774 => x"10000737", |
00000775 => x"00e7e7b3", |
00000776 => x"faf02023", |
00000777 => x"00008067", |
00000778 => x"00178793", |
00000779 => x"01079793", |
00000780 => x"40a70733", |
00000781 => x"0107d793", |
00000782 => x"fa9ff06f", |
00000783 => x"ffe70513", |
00000784 => x"0fd57513", |
00000785 => x"00051a63", |
00000786 => x"0037d793", |
00000787 => x"00170713", |
00000788 => x"0ff77713", |
00000789 => x"f9dff06f", |
00000790 => x"0017d793", |
00000791 => x"ff1ff06f", |
00000792 => x"f71ff06f", |
00000793 => x"fa002783", |
00000794 => x"fe07cee3", |
00000795 => x"faa02223", |
00000796 => x"00008067", |
00000797 => x"ff1ff06f", |
00000798 => x"fa002503", |
00000799 => x"01f55513", |
00000800 => x"00008067", |
00000801 => x"ff5ff06f", |
00000802 => x"fa402503", |
00000803 => x"fe055ee3", |
00000804 => x"0ff57513", |
00000805 => x"00008067", |
00000806 => x"ff1ff06f", |
00000807 => x"fa402503", |
00000808 => x"01f55513", |
00000809 => x"00008067", |
00000810 => x"ff5ff06f", |
00000811 => x"ff010113", |
00000812 => x"00812423", |
00000813 => x"01212023", |
00000814 => x"00112623", |
00000815 => x"00912223", |
00000816 => x"00050413", |
00000817 => x"00a00913", |
00000818 => x"00044483", |
00000819 => x"00140413", |
00000820 => x"00049e63", |
00000821 => x"00c12083", |
00000822 => x"00812403", |
00000823 => x"00412483", |
00000824 => x"00012903", |
00000825 => x"01010113", |
00000826 => x"00008067", |
00000827 => x"01249663", |
00000828 => x"00d00513", |
00000829 => x"f71ff0ef", |
00000830 => x"00048513", |
00000831 => x"f69ff0ef", |
00000832 => x"fc9ff06f", |
00000833 => x"fa9ff06f", |
00000834 => x"00757513", |
00000835 => x"00367613", |
00000836 => x"0015f593", |
00000837 => x"00a51513", |
00000838 => x"00d61613", |
00000839 => x"00c56533", |
00000840 => x"00959593", |
00000841 => x"fa800793", |
00000842 => x"00b56533", |
00000843 => x"0007a023", |
00000844 => x"10056513", |
00000845 => x"00a7a023", |
00000846 => x"00008067", |
00000847 => x"fa800713", |
00000848 => x"00072683", |
00000849 => x"00757793", |
00000850 => x"00100513", |
00000851 => x"00f51533", |
00000852 => x"00d56533", |
00000853 => x"00a72023", |
00000854 => x"00008067", |
00000855 => x"fa800713", |
00000856 => x"00072683", |
00000857 => x"00757513", |
00000858 => x"00100793", |
00000859 => x"00a797b3", |
00000860 => x"fff7c793", |
00000861 => x"00d7f7b3", |
00000862 => x"00f72023", |
00000863 => x"00008067", |
00000864 => x"faa02623", |
00000865 => x"fa802783", |
00000866 => x"fe07cee3", |
00000867 => x"fac02503", |
00000868 => x"00008067", |
00000869 => x"f8400713", |
00000870 => x"00072683", |
00000871 => x"00100793", |
00000872 => x"00a797b3", |
00000873 => x"00d7c7b3", |
00000874 => x"00f72023", |
00000756 => x"fa402503", |
00000757 => x"0ff57513", |
00000758 => x"00008067", |
00000759 => x"fa002023", |
00000760 => x"fe002703", |
00000761 => x"00151513", |
00000762 => x"00000793", |
00000763 => x"04a77463", |
00000764 => x"000016b7", |
00000765 => x"00000713", |
00000766 => x"ffe68693", |
00000767 => x"04f6e663", |
00000768 => x"00367613", |
00000769 => x"0035f593", |
00000770 => x"fff78793", |
00000771 => x"01461613", |
00000772 => x"00c7e7b3", |
00000773 => x"01659593", |
00000774 => x"01871713", |
00000775 => x"00b7e7b3", |
00000776 => x"00e7e7b3", |
00000777 => x"10000737", |
00000778 => x"00e7e7b3", |
00000779 => x"faf02023", |
00000780 => x"00008067", |
00000781 => x"00178793", |
00000782 => x"01079793", |
00000783 => x"40a70733", |
00000784 => x"0107d793", |
00000785 => x"fa9ff06f", |
00000786 => x"ffe70513", |
00000787 => x"0fd57513", |
00000788 => x"00051a63", |
00000789 => x"0037d793", |
00000790 => x"00170713", |
00000791 => x"0ff77713", |
00000792 => x"f9dff06f", |
00000793 => x"0017d793", |
00000794 => x"ff1ff06f", |
00000795 => x"f71ff06f", |
00000796 => x"fa002783", |
00000797 => x"fe07cee3", |
00000798 => x"faa02223", |
00000799 => x"00008067", |
00000800 => x"ff1ff06f", |
00000801 => x"fa002503", |
00000802 => x"01f55513", |
00000803 => x"00008067", |
00000804 => x"ff5ff06f", |
00000805 => x"fa402503", |
00000806 => x"fe055ee3", |
00000807 => x"0ff57513", |
00000808 => x"00008067", |
00000809 => x"ff1ff06f", |
00000810 => x"fa402503", |
00000811 => x"01f55513", |
00000812 => x"00008067", |
00000813 => x"ff5ff06f", |
00000814 => x"ff010113", |
00000815 => x"00812423", |
00000816 => x"01212023", |
00000817 => x"00112623", |
00000818 => x"00912223", |
00000819 => x"00050413", |
00000820 => x"00a00913", |
00000821 => x"00044483", |
00000822 => x"00140413", |
00000823 => x"00049e63", |
00000824 => x"00c12083", |
00000825 => x"00812403", |
00000826 => x"00412483", |
00000827 => x"00012903", |
00000828 => x"01010113", |
00000829 => x"00008067", |
00000830 => x"01249663", |
00000831 => x"00d00513", |
00000832 => x"f71ff0ef", |
00000833 => x"00048513", |
00000834 => x"f69ff0ef", |
00000835 => x"fc9ff06f", |
00000836 => x"fa9ff06f", |
00000837 => x"fe802503", |
00000838 => x"01355513", |
00000839 => x"00157513", |
00000840 => x"00008067", |
00000841 => x"00757513", |
00000842 => x"00367613", |
00000843 => x"0015f593", |
00000844 => x"00a51513", |
00000845 => x"00d61613", |
00000846 => x"00c56533", |
00000847 => x"00959593", |
00000848 => x"fa800793", |
00000849 => x"00b56533", |
00000850 => x"0007a023", |
00000851 => x"10056513", |
00000852 => x"00a7a023", |
00000853 => x"00008067", |
00000854 => x"fa800713", |
00000855 => x"00072683", |
00000856 => x"00757793", |
00000857 => x"00100513", |
00000858 => x"00f51533", |
00000859 => x"00d56533", |
00000860 => x"00a72023", |
00000861 => x"00008067", |
00000862 => x"fa800713", |
00000863 => x"00072683", |
00000864 => x"00757513", |
00000865 => x"00100793", |
00000866 => x"00a797b3", |
00000867 => x"fff7c793", |
00000868 => x"00d7f7b3", |
00000869 => x"00f72023", |
00000870 => x"00008067", |
00000871 => x"faa02623", |
00000872 => x"fa802783", |
00000873 => x"fe07cee3", |
00000874 => x"fac02503", |
00000875 => x"00008067", |
00000876 => x"f8a02223", |
00000877 => x"00008067", |
00000878 => x"69617641", |
00000879 => x"6c62616c", |
00000880 => x"4d432065", |
00000881 => x"0a3a7344", |
00000882 => x"203a6820", |
00000883 => x"706c6548", |
00000884 => x"3a72200a", |
00000885 => x"73655220", |
00000886 => x"74726174", |
00000887 => x"3a75200a", |
00000888 => x"6c705520", |
00000889 => x"0a64616f", |
00000890 => x"203a7320", |
00000891 => x"726f7453", |
00000892 => x"6f742065", |
00000893 => x"616c6620", |
00000894 => x"200a6873", |
00000895 => x"4c203a6c", |
00000896 => x"2064616f", |
00000897 => x"6d6f7266", |
00000898 => x"616c6620", |
00000899 => x"200a6873", |
00000900 => x"45203a65", |
00000901 => x"75636578", |
00000902 => x"00006574", |
00000903 => x"65206f4e", |
00000904 => x"75636578", |
00000905 => x"6c626174", |
00000906 => x"76612065", |
00000907 => x"616c6961", |
00000908 => x"2e656c62", |
00000909 => x"00000000", |
00000910 => x"746f6f42", |
00000911 => x"2e676e69", |
00000912 => x"0a0a2e2e", |
00000913 => x"00000000", |
00000914 => x"52450a07", |
00000915 => x"5f524f52", |
00000876 => x"f8400713", |
00000877 => x"00072683", |
00000878 => x"00100793", |
00000879 => x"00a797b3", |
00000880 => x"00d7c7b3", |
00000881 => x"00f72023", |
00000882 => x"00008067", |
00000883 => x"f8a02223", |
00000884 => x"00008067", |
00000885 => x"69617641", |
00000886 => x"6c62616c", |
00000887 => x"4d432065", |
00000888 => x"0a3a7344", |
00000889 => x"203a6820", |
00000890 => x"706c6548", |
00000891 => x"3a72200a", |
00000892 => x"73655220", |
00000893 => x"74726174", |
00000894 => x"3a75200a", |
00000895 => x"6c705520", |
00000896 => x"0a64616f", |
00000897 => x"203a7320", |
00000898 => x"726f7453", |
00000899 => x"6f742065", |
00000900 => x"616c6620", |
00000901 => x"200a6873", |
00000902 => x"4c203a6c", |
00000903 => x"2064616f", |
00000904 => x"6d6f7266", |
00000905 => x"616c6620", |
00000906 => x"200a6873", |
00000907 => x"45203a65", |
00000908 => x"75636578", |
00000909 => x"00006574", |
00000910 => x"65206f4e", |
00000911 => x"75636578", |
00000912 => x"6c626174", |
00000913 => x"76612065", |
00000914 => x"616c6961", |
00000915 => x"2e656c62", |
00000916 => x"00000000", |
00000917 => x"00007830", |
00000918 => x"58450a0a", |
00000919 => x"54504543", |
00000920 => x"204e4f49", |
00000921 => x"7561636d", |
00000922 => x"003d6573", |
00000923 => x"70204020", |
00000924 => x"00003d63", |
00000925 => x"69617741", |
00000926 => x"676e6974", |
00000927 => x"6f656e20", |
00000928 => x"32337672", |
00000929 => x"6578655f", |
00000930 => x"6e69622e", |
00000931 => x"202e2e2e", |
00000932 => x"00000000", |
00000933 => x"64616f4c", |
00000934 => x"2e676e69", |
00000935 => x"00202e2e", |
00000936 => x"00004b4f", |
00000937 => x"0000000a", |
00000938 => x"74697257", |
00000939 => x"78302065", |
00000940 => x"00000000", |
00000941 => x"74796220", |
00000942 => x"74207365", |
00000943 => x"5053206f", |
00000944 => x"6c662049", |
00000945 => x"20687361", |
00000946 => x"78302040", |
00000917 => x"746f6f42", |
00000918 => x"2e676e69", |
00000919 => x"0a0a2e2e", |
00000920 => x"00000000", |
00000921 => x"52450a07", |
00000922 => x"5f524f52", |
00000923 => x"00000000", |
00000924 => x"00007830", |
00000925 => x"58450a0a", |
00000926 => x"54504543", |
00000927 => x"204e4f49", |
00000928 => x"7561636d", |
00000929 => x"003d6573", |
00000930 => x"70204020", |
00000931 => x"00003d63", |
00000932 => x"69617741", |
00000933 => x"676e6974", |
00000934 => x"6f656e20", |
00000935 => x"32337672", |
00000936 => x"6578655f", |
00000937 => x"6e69622e", |
00000938 => x"202e2e2e", |
00000939 => x"00000000", |
00000940 => x"64616f4c", |
00000941 => x"2e676e69", |
00000942 => x"00202e2e", |
00000943 => x"00004b4f", |
00000944 => x"0000000a", |
00000945 => x"74697257", |
00000946 => x"78302065", |
00000947 => x"00000000", |
00000948 => x"7928203f", |
00000949 => x"20296e2f", |
00000950 => x"00000000", |
00000951 => x"616c460a", |
00000952 => x"6e696873", |
00000953 => x"2e2e2e67", |
00000954 => x"00000020", |
00000955 => x"0a0a0a0a", |
00000956 => x"4e203c3c", |
00000957 => x"56524f45", |
00000958 => x"42203233", |
00000959 => x"6c746f6f", |
00000960 => x"6564616f", |
00000961 => x"3e3e2072", |
00000962 => x"4c420a0a", |
00000963 => x"203a5644", |
00000964 => x"20727041", |
00000965 => x"32203331", |
00000966 => x"0a313230", |
00000967 => x"3a565748", |
00000968 => x"00002020", |
00000969 => x"4b4c430a", |
00000970 => x"0020203a", |
00000971 => x"4553550a", |
00000972 => x"00203a52", |
00000973 => x"53494d0a", |
00000974 => x"00203a41", |
00000975 => x"58455a0a", |
00000976 => x"00203a54", |
00000977 => x"4f52500a", |
00000978 => x"00203a43", |
00000979 => x"454d490a", |
00000980 => x"00203a4d", |
00000981 => x"74796220", |
00000982 => x"40207365", |
00000983 => x"00000020", |
00000984 => x"454d440a", |
00000985 => x"00203a4d", |
00000986 => x"75410a0a", |
00000987 => x"6f626f74", |
00000988 => x"6920746f", |
00000989 => x"3828206e", |
00000990 => x"202e7329", |
00000991 => x"73657250", |
00000992 => x"656b2073", |
00000993 => x"6f742079", |
00000994 => x"6f626120", |
00000995 => x"0a2e7472", |
00000996 => x"00000000", |
00000997 => x"726f6241", |
00000998 => x"2e646574", |
00000999 => x"00000a0a", |
00001000 => x"444d430a", |
00001001 => x"00203e3a", |
00001002 => x"53207962", |
00001003 => x"68706574", |
00001004 => x"4e206e61", |
00001005 => x"69746c6f", |
00001006 => x"0000676e", |
00001007 => x"61766e49", |
00001008 => x"2064696c", |
00001009 => x"00444d43", |
00001010 => x"33323130", |
00001011 => x"37363534", |
00001012 => x"62613938", |
00001013 => x"66656463", |
00000948 => x"74796220", |
00000949 => x"74207365", |
00000950 => x"5053206f", |
00000951 => x"6c662049", |
00000952 => x"20687361", |
00000953 => x"78302040", |
00000954 => x"00000000", |
00000955 => x"7928203f", |
00000956 => x"20296e2f", |
00000957 => x"00000000", |
00000958 => x"616c460a", |
00000959 => x"6e696873", |
00000960 => x"2e2e2e67", |
00000961 => x"00000020", |
00000962 => x"0a0a0a0a", |
00000963 => x"4e203c3c", |
00000964 => x"56524f45", |
00000965 => x"42203233", |
00000966 => x"6c746f6f", |
00000967 => x"6564616f", |
00000968 => x"3e3e2072", |
00000969 => x"4c420a0a", |
00000970 => x"203a5644", |
00000971 => x"20727041", |
00000972 => x"32203132", |
00000973 => x"0a313230", |
00000974 => x"3a565748", |
00000975 => x"00002020", |
00000976 => x"4b4c430a", |
00000977 => x"0020203a", |
00000978 => x"4553550a", |
00000979 => x"00203a52", |
00000980 => x"53494d0a", |
00000981 => x"00203a41", |
00000982 => x"58455a0a", |
00000983 => x"00203a54", |
00000984 => x"4f52500a", |
00000985 => x"00203a43", |
00000986 => x"454d490a", |
00000987 => x"00203a4d", |
00000988 => x"74796220", |
00000989 => x"40207365", |
00000990 => x"00000020", |
00000991 => x"454d440a", |
00000992 => x"00203a4d", |
00000993 => x"75410a0a", |
00000994 => x"6f626f74", |
00000995 => x"6920746f", |
00000996 => x"3828206e", |
00000997 => x"202e7329", |
00000998 => x"73657250", |
00000999 => x"656b2073", |
00001000 => x"6f742079", |
00001001 => x"6f626120", |
00001002 => x"0a2e7472", |
00001003 => x"00000000", |
00001004 => x"726f6241", |
00001005 => x"2e646574", |
00001006 => x"00000a0a", |
00001007 => x"444d430a", |
00001008 => x"00203e3a", |
00001009 => x"53207962", |
00001010 => x"68706574", |
00001011 => x"4e206e61", |
00001012 => x"69746c6f", |
00001013 => x"0000676e", |
00001014 => x"61766e49", |
00001015 => x"2064696c", |
00001016 => x"00444d43", |
00001017 => x"33323130", |
00001018 => x"37363534", |
00001019 => x"62613938", |
00001020 => x"66656463", |
others => x"00000000" |
); |
|
/neorv32_bus_keeper.vhd
0,0 → 1,144
-- ################################################################################################# |
-- # << NEORV32 - Bus Keeper (BUSKEEPER) >> # |
-- # ********************************************************************************************* # |
-- # This unit monitors the processor-internal bus. If the accesses INTERNAL (IMEM if enabled, # |
-- # DMEM if enabled, BOOTROM + IO region) module does not respond within the defined number of # |
-- # cycles (VHDL package: max_proc_int_response_time_c) it asserts the error signal to inform the # |
-- # CPU / bus driver. This timeout does not track accesses via the processor-external bus # |
-- # interface! # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, 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_bus_keeper is |
generic ( |
-- Internal instruction memory -- |
MEM_INT_IMEM_EN : 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_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes |
); |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
rstn_i : in std_ulogic; -- global reset line, low-active |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
ack_i : in std_ulogic; -- transfer acknowledge from bus system |
err_i : in std_ulogic; -- transfer error from bus system |
err_o : out std_ulogic -- bus error |
); |
end neorv32_bus_keeper; |
|
architecture neorv32_bus_keeper_rtl of neorv32_bus_keeper is |
|
-- access check -- |
type access_check_t is record |
int_imem : std_ulogic; |
int_dmem : std_ulogic; |
int_bootrom_io : std_ulogic; |
valid : std_ulogic; |
end record; |
signal access_check : access_check_t; |
|
-- controller -- |
type control_t is record |
pending : std_ulogic; |
timeout : std_ulogic_vector(index_size_f(max_proc_int_response_time_c)-1 downto 0); |
bus_err : std_ulogic; |
end record; |
signal control : control_t; |
|
begin |
|
-- Sanity Check -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert not (max_proc_int_response_time_c < 2) report "NEORV32 PROCESSOR CONFIG ERROR! Processor-internal bus timeout <max_proc_int_response_time_c> has to >= 2." severity error; |
|
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- access to processor-internal IMEM or DMEM? -- |
access_check.int_imem <= '1' when (addr_i(31 downto index_size_f(MEM_INT_IMEM_SIZE)) = imem_base_c(31 downto index_size_f(MEM_INT_IMEM_SIZE))) and (MEM_INT_IMEM_EN = true) else '0'; |
access_check.int_dmem <= '1' when (addr_i(31 downto index_size_f(MEM_INT_DMEM_SIZE)) = dmem_base_c(31 downto index_size_f(MEM_INT_DMEM_SIZE))) and (MEM_INT_DMEM_EN = true) else '0'; |
-- access to processor-internal BOOTROM or IO devices? -- |
access_check.int_bootrom_io <= '1' when (addr_i(31 downto 16) = boot_rom_base_c(31 downto 16)) else '0'; -- hacky! |
-- actual internal bus access? -- |
access_check.valid <= access_check.int_imem or access_check.int_dmem or access_check.int_bootrom_io; |
|
|
-- Keeper --------------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
keeper_control: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
control.pending <= '0'; |
control.bus_err <= '0'; |
control.timeout <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
|
-- pending access? -- |
control.bus_err <= '0'; |
if (control.pending = '0') then -- idle |
if ((rden_i or wren_i) = '1') and (access_check.valid = '1') then |
control.pending <= '1'; |
end if; |
else -- pending |
if (ack_i = '1') or (err_i = '1') then -- termination by bus system |
control.pending <= '0'; |
elsif (or_all_f(control.timeout) = '0') then -- timeout! terminate bus transfer |
control.pending <= '0'; |
control.bus_err <= '1'; |
end if; |
end if; |
|
-- timeout counter -- |
if (control.pending = '0') then |
control.timeout <= std_ulogic_vector(to_unsigned(max_proc_int_response_time_c, index_size_f(max_proc_int_response_time_c))); |
else |
control.timeout <= std_ulogic_vector(unsigned(control.timeout) - 1); -- countdown timer |
end if; |
end if; |
end process keeper_control; |
|
err_o <= control.bus_err; |
|
|
end neorv32_bus_keeper_rtl; |
/neorv32_busswitch.vhd
58,8 → 58,7
ca_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable |
ca_bus_we_i : in std_ulogic; -- write enable |
ca_bus_re_i : in std_ulogic; -- read enable |
ca_bus_cancel_i : in std_ulogic; -- cancel current bus transaction |
ca_bus_excl_i : in std_ulogic; -- exclusive access |
ca_bus_lock_i : in std_ulogic; -- exclusive access request |
ca_bus_ack_o : out std_ulogic; -- bus transfer acknowledge |
ca_bus_err_o : out std_ulogic; -- bus transfer error |
-- controller interface b -- |
69,8 → 68,7
cb_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable |
cb_bus_we_i : in std_ulogic; -- write enable |
cb_bus_re_i : in std_ulogic; -- read enable |
cb_bus_cancel_i : in std_ulogic; -- cancel current bus transaction |
cb_bus_excl_i : in std_ulogic; -- exclusive access |
cb_bus_lock_i : in std_ulogic; -- exclusive access request |
cb_bus_ack_o : out std_ulogic; -- bus transfer acknowledge |
cb_bus_err_o : out std_ulogic; -- bus transfer error |
-- peripheral bus -- |
81,8 → 79,7
p_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
p_bus_we_o : out std_ulogic; -- write enable |
p_bus_re_o : out std_ulogic; -- read enable |
p_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
p_bus_excl_o : out std_ulogic; -- exclusive access |
p_bus_lock_o : out std_ulogic; -- exclusive access request |
p_bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
p_bus_err_i : in std_ulogic -- bus transfer error |
); |
129,8 → 126,7
if (ca_rd_req_buf = '0') and (ca_wr_req_buf = '0') then -- idle |
ca_rd_req_buf <= ca_bus_re_i; |
ca_wr_req_buf <= ca_bus_we_i; |
elsif (ca_bus_cancel_i = '1') or -- controller cancels access |
(ca_bus_err = '1') or -- peripheral cancels access |
elsif (ca_bus_err = '1') or -- error termination |
(ca_bus_ack = '1') then -- normal termination |
ca_rd_req_buf <= '0'; |
ca_wr_req_buf <= '0'; |
140,8 → 136,7
if (cb_rd_req_buf = '0') and (cb_wr_req_buf = '0') then |
cb_rd_req_buf <= cb_bus_re_i; |
cb_wr_req_buf <= cb_bus_we_i; |
elsif (cb_bus_cancel_i = '1') or -- controller cancels access |
(cb_bus_err = '1') or -- peripheral cancels access |
elsif (cb_bus_err = '1') or -- error termination |
(cb_bus_ack = '1') then -- normal termination |
cb_rd_req_buf <= '0'; |
cb_wr_req_buf <= '0'; |
175,8 → 170,7
-- Peripheral Bus Arbiter ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
arbiter_comb: process(arbiter, ca_req_current, cb_req_current, ca_req_buffered, cb_req_buffered, |
ca_rd_req_buf, ca_wr_req_buf, cb_rd_req_buf, cb_wr_req_buf, |
ca_bus_cancel_i, cb_bus_cancel_i, p_bus_ack_i, p_bus_err_i) |
ca_rd_req_buf, ca_wr_req_buf, cb_rd_req_buf, cb_wr_req_buf, p_bus_ack_i, p_bus_err_i) |
begin |
-- arbiter defaults -- |
arbiter.state_nxt <= arbiter.state; |
210,8 → 204,7
-- ------------------------------------------------------------ |
p_bus_src_o <= '0'; -- access from port A |
arbiter.bus_sel <= '0'; |
if (ca_bus_cancel_i = '1') or -- controller cancels access |
(p_bus_err_i = '1') or -- peripheral cancels access |
if (p_bus_err_i = '1') or -- error termination |
(p_bus_ack_i = '1') then -- normal termination |
arbiter.state_nxt <= IDLE; |
end if; |
230,8 → 223,7
-- ------------------------------------------------------------ |
p_bus_src_o <= '1'; -- access from port B |
arbiter.bus_sel <= '1'; |
if (cb_bus_cancel_i = '1') or -- controller cancels access |
(p_bus_err_i = '1') or -- peripheral cancels access |
if (p_bus_err_i = '1') or -- error termination |
(p_bus_ack_i = '1') then -- normal termination |
if (ca_req_buffered = '1') or (ca_req_current = '1') then -- any request from A? |
arbiter.state_nxt <= RETIRE; |
263,10 → 255,9
ca_bus_ben_i when (arbiter.bus_sel = '0') else cb_bus_ben_i; |
p_bus_we <= ca_bus_we_i when (arbiter.bus_sel = '0') else cb_bus_we_i; |
p_bus_re <= ca_bus_re_i when (arbiter.bus_sel = '0') else cb_bus_re_i; |
p_bus_cancel_o <= ca_bus_cancel_i when (arbiter.bus_sel = '0') else cb_bus_cancel_i; |
p_bus_we_o <= (p_bus_we or arbiter.we_trig); |
p_bus_re_o <= (p_bus_re or arbiter.re_trig); |
p_bus_excl_o <= ca_bus_excl_i or cb_bus_excl_i; |
p_bus_lock_o <= ca_bus_lock_i or cb_bus_lock_i; |
|
ca_bus_rdata_o <= p_bus_rdata_i; |
cb_bus_rdata_o <= p_bus_rdata_i; |
/neorv32_cpu.vhd
58,7 → 58,6
-- General -- |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0):= x"00000000"; -- cpu boot address |
BUS_TIMEOUT : natural := 63; -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit manipulation extensions? |
93,7 → 92,7
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
i_bus_we_o : out std_ulogic; -- write enable |
i_bus_re_o : out std_ulogic; -- read enable |
i_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
i_bus_lock_o : out std_ulogic; -- exclusive access request |
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 |
105,13 → 104,11
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
d_bus_we_o : out std_ulogic; -- write enable |
d_bus_re_o : out std_ulogic; -- read enable |
d_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
d_bus_lock_o : out std_ulogic; -- exclusive access request |
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 |
d_bus_excl_o : out std_ulogic; -- exclusive access request |
d_bus_excl_i : in std_ulogic; -- state of exclusiv access (set if success) |
-- system time input from MTIME -- |
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time |
-- interrupts (risc-v compliant) -- |
143,7 → 140,7
signal ma_instr : std_ulogic; -- misaligned instruction address |
signal ma_load : std_ulogic; -- misaligned load data address |
signal ma_store : std_ulogic; -- misaligned store data address |
signal bus_excl_ok : std_ulogic; -- atomic memory access successful |
signal excl_state : std_ulogic; -- atomic/exclusive access lock status |
signal be_instr : std_ulogic; -- bus error on instruction access |
signal be_load : std_ulogic; -- bus error on load data access |
signal be_store : std_ulogic; -- bus error on store data access |
161,11 → 158,6
signal pmp_addr : pmp_addr_if_t; |
signal pmp_ctrl : pmp_ctrl_if_t; |
|
-- atomic memory access - success? -- |
signal atomic_sc_res : std_ulogic; |
signal atomic_sc_res_ff : std_ulogic; |
signal atomic_sc_val : std_ulogic; |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
185,9 → 177,6
-- U-extension requires Zicsr extension -- |
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (CPU_EXTENSION_RISCV_U = true)) report "NEORV32 CPU CONFIG ERROR! User mode requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error; |
|
-- Bus timeout -- |
assert not (BUS_TIMEOUT < 2) report "NEORV32 CPU CONFIG ERROR! Invalid bus access timeout value <BUS_TIMEOUT>. Has to be >= 2." severity error; |
|
-- Instruction prefetch buffer size -- |
assert not (is_power_of_two_f(ipb_entries_c) = false) report "NEORV32 CPU CONFIG ERROR! Number of entries in instruction prefetch buffer <ipb_entries_c> has to be a power of two." severity error; |
-- A extension - only lr.w and sc.w are supported yet -- |
252,6 → 241,7
alu_wait_i => alu_wait, -- wait for ALU |
bus_i_wait_i => bus_i_wait, -- wait for bus |
bus_d_wait_i => bus_d_wait, -- wait for bus |
excl_state_i => excl_state, -- atomic/exclusive access lock status |
-- data input -- |
instr_i => instr, -- instruction |
cmp_i => comparator, -- comparator status |
341,8 → 331,16
); |
|
|
-- Co-Processor 0: Integer Multiplication/Division ('M' Extension) ------------------------ |
-- Co-Processor 0: CSR (Read) Access ('Zicsr' Extension) ---------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- "pseudo" co-processor for CSR *read* access operations |
-- required to get CSR read data into the data path |
cp_result(0) <= csr_rdata when (CPU_EXTENSION_RISCV_Zicsr = true) else (others => '0'); |
cp_valid(0) <= cp_start(0); -- always assigned even if Zicsr extension is disabled to make sure CPU does not get stalled if there is an accidental access |
|
|
-- Co-Processor 1: Integer Multiplication/Division ('M' Extension) ------------------------ |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_muldiv_inst_true: |
if (CPU_EXTENSION_RISCV_M = true) generate |
neorv32_cpu_cp_muldiv_inst: neorv32_cpu_cp_muldiv |
354,50 → 352,23
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
ctrl_i => ctrl, -- main control bus |
start_i => cp_start(0), -- trigger operation |
start_i => cp_start(1), -- trigger operation |
-- data input -- |
rs1_i => rs1, -- rf source 1 |
rs2_i => rs2, -- rf source 2 |
-- result and status -- |
res_o => cp_result(0), -- operation result |
valid_o => cp_valid(0) -- data output valid |
res_o => cp_result(1), -- operation result |
valid_o => cp_valid(1) -- data output valid |
); |
end generate; |
|
neorv32_cpu_cp_muldiv_inst_false: |
if (CPU_EXTENSION_RISCV_M = false) generate |
cp_result(0) <= (others => '0'); |
cp_valid(0) <= cp_start(0); -- to make sure CPU does not get stalled if there is an accidental access |
cp_result(1) <= (others => '0'); |
cp_valid(1) <= cp_start(1); -- to make sure CPU does not get stalled if there is an accidental access |
end generate; |
|
|
-- Co-Processor 1: Atomic Memory Access ('A' Extension) ----------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- "pseudo" co-processor for atomic operations |
-- required to get the result of a store-conditional operation into the data path |
atomic_op_cp: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
atomic_sc_val <= def_rst_val_c; |
atomic_sc_res <= def_rst_val_c; |
atomic_sc_res_ff <= def_rst_val_c; |
elsif rising_edge(clk_i) then |
atomic_sc_val <= cp_start(1); |
atomic_sc_res <= bus_excl_ok; |
if (atomic_sc_val = '1') then |
atomic_sc_res_ff <= not atomic_sc_res; |
else |
atomic_sc_res_ff <= '0'; |
end if; |
end if; |
end process atomic_op_cp; |
|
-- CP result -- |
cp_result(1)(data_width_c-1 downto 1) <= (others => '0'); |
cp_result(1)(0) <= atomic_sc_res_ff when (CPU_EXTENSION_RISCV_A = true) else '0'; |
cp_valid(1) <= atomic_sc_val when (CPU_EXTENSION_RISCV_A = true) else cp_start(1); -- assigned even if A extension is disabled so CPU does not get stalled on accidental access |
|
|
-- Co-Processor 2: Bit Manipulation ('B' Extension) --------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_bitmanip_inst_true: |
426,16 → 397,8
end generate; |
|
|
-- Co-Processor 3: CSR (Read) Access ('Zicsr' Extension) ---------------------------------- |
-- Co-Processor 3: Single-Precision Floating-Point Unit ('Zfinx' Extension) --------------- |
-- ------------------------------------------------------------------------------------------- |
-- "pseudo" co-processor for CSR *read* access operations |
-- required to get CSR read data into the data path |
cp_result(3) <= csr_rdata when (CPU_EXTENSION_RISCV_Zicsr = true) else (others => '0'); |
cp_valid(3) <= cp_start(3); -- always assigned even if Zicsr extension is disabled to make sure CPU does not get stalled if there is an accidental access |
|
|
-- Co-Processor 4: Single-Precision Floating-Point Unit ('Zfinx' Extension) --------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_fpu_inst_true: |
if (CPU_EXTENSION_RISCV_Zfinx = true) generate |
neorv32_cpu_cp_fpu_inst: neorv32_cpu_cp_fpu |
444,7 → 407,7
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
ctrl_i => ctrl, -- main control bus |
start_i => cp_start(4), -- trigger operation |
start_i => cp_start(3), -- trigger operation |
-- data input -- |
frm_i => fpu_rm, -- rounding mode |
cmp_i => comparator, -- comparator status |
451,22 → 414,25
rs1_i => rs1, -- rf source 1 |
rs2_i => rs2, -- rf source 2 |
-- result and status -- |
res_o => cp_result(4), -- operation result |
res_o => cp_result(3), -- operation result |
fflags_o => fpu_flags, -- exception flags |
valid_o => cp_valid(4) -- data output valid |
valid_o => cp_valid(3) -- data output valid |
); |
end generate; |
|
neorv32_cpu_cp_fpu_inst_false: |
if (CPU_EXTENSION_RISCV_Zfinx = false) generate |
cp_result(4) <= (others => '0'); |
cp_result(3) <= (others => '0'); |
fpu_flags <= (others => '0'); |
cp_valid(4) <= cp_start(4); -- to make sure CPU does not get stalled if there is an accidental access |
cp_valid(3) <= cp_start(3); -- to make sure CPU does not get stalled if there is an accidental access |
end generate; |
|
|
-- Co-Processor 5,6,7: Not Implemented Yet ------------------------------------------------ |
-- Co-Processor 4,5,6,7: Not Implemented -------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
cp_result(4) <= (others => '0'); |
cp_valid(4) <= '0'; |
-- |
cp_result(5) <= (others => '0'); |
cp_valid(5) <= '0'; |
-- |
485,9 → 451,7
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
-- Physical memory protection (PMP) -- |
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64) |
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Bus Timeout -- |
BUS_TIMEOUT => BUS_TIMEOUT -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
) |
port map ( |
-- global control -- |
508,7 → 472,7
mar_o => mar, -- current memory address register |
d_wait_o => bus_d_wait, -- wait for access to complete |
-- |
bus_excl_ok_o => bus_excl_ok, -- bus exclusive access successful |
excl_state_o => excl_state, -- atomic/exclusive access status |
ma_load_o => ma_load, -- misaligned load data address |
ma_store_o => ma_store, -- misaligned store data address |
be_load_o => be_load, -- bus error on load data access |
523,7 → 487,7
i_bus_ben_o => i_bus_ben_o, -- byte enable |
i_bus_we_o => i_bus_we_o, -- write enable |
i_bus_re_o => i_bus_re_o, -- read enable |
i_bus_cancel_o => i_bus_cancel_o, -- cancel current bus transaction |
i_bus_lock_o => i_bus_lock_o, -- exclusive access request |
i_bus_ack_i => i_bus_ack_i, -- bus transfer acknowledge |
i_bus_err_i => i_bus_err_i, -- bus transfer error |
i_bus_fence_o => i_bus_fence_o, -- fence operation |
534,12 → 498,10
d_bus_ben_o => d_bus_ben_o, -- byte enable |
d_bus_we_o => d_bus_we_o, -- write enable |
d_bus_re_o => d_bus_re_o, -- read enable |
d_bus_cancel_o => d_bus_cancel_o, -- cancel current bus transaction |
d_bus_lock_o => d_bus_lock_o, -- exclusive access request |
d_bus_ack_i => d_bus_ack_i, -- bus transfer acknowledge |
d_bus_err_i => d_bus_err_i, -- bus transfer error |
d_bus_fence_o => d_bus_fence_o, -- fence operation |
d_bus_excl_o => d_bus_excl_o, -- exclusive access request |
d_bus_excl_i => d_bus_excl_i -- state of exclusiv access (set if success) |
d_bus_fence_o => d_bus_fence_o -- fence operation |
); |
|
-- current privilege level -- |
/neorv32_cpu_bus.vhd
43,13 → 43,11
|
entity neorv32_cpu_bus is |
generic ( |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension? |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension? |
-- Physical memory protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Bus Timeout -- |
BUS_TIMEOUT : natural := 63 -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024 -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
); |
port ( |
-- global control -- |
70,7 → 68,7
mar_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current memory address register |
d_wait_o : out std_ulogic; -- wait for access to complete |
-- |
bus_excl_ok_o : out std_ulogic; -- bus exclusive access successful |
excl_state_o : out std_ulogic; -- atomic/exclusive access status |
ma_load_o : out std_ulogic; -- misaligned load data address |
ma_store_o : out std_ulogic; -- misaligned store data address |
be_load_o : out std_ulogic; -- bus error on load data access |
85,7 → 83,7
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
i_bus_we_o : out std_ulogic; -- write enable |
i_bus_re_o : out std_ulogic; -- read enable |
i_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
i_bus_lock_o : out std_ulogic; -- exclusive access request |
i_bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
i_bus_err_i : in std_ulogic; -- bus transfer error |
i_bus_fence_o : out std_ulogic; -- fence operation |
96,12 → 94,10
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
d_bus_we_o : out std_ulogic; -- write enable |
d_bus_re_o : out std_ulogic; -- read enable |
d_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
d_bus_lock_o : out std_ulogic; -- exclusive access request |
d_bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
d_bus_err_i : in std_ulogic; -- bus transfer error |
d_bus_fence_o : out std_ulogic; -- fence operation |
d_bus_excl_o : out std_ulogic; -- exclusive access request |
d_bus_excl_i : in std_ulogic -- state of exclusiv access (set if success) |
d_bus_fence_o : out std_ulogic -- fence operation |
); |
end neorv32_cpu_bus; |
|
130,6 → 126,7
-- data access -- |
signal d_bus_wdata : std_ulogic_vector(data_width_c-1 downto 0); -- write data |
signal d_bus_rdata : std_ulogic_vector(data_width_c-1 downto 0); -- read data |
signal rdata_align : std_ulogic_vector(data_width_c-1 downto 0); -- read-data alignment |
signal d_bus_ben : std_ulogic_vector(3 downto 0); -- write data byte enable |
|
-- misaligned access? -- |
141,10 → 138,13
wr_req : std_ulogic; -- write access in progress |
err_align : std_ulogic; -- alignment error |
err_bus : std_ulogic; -- bus access error |
timeout : std_ulogic_vector(index_size_f(BUS_TIMEOUT)-1 downto 0); |
end record; |
signal i_arbiter, d_arbiter : bus_arbiter_t; |
|
-- atomic/exclusive access - reservation controller -- |
signal exclusive_lock : std_ulogic; |
signal exclusive_lock_status : std_ulogic_vector(data_width_c-1 downto 0); -- read data |
|
-- physical memory protection -- |
type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0); |
type pmp_t is record |
258,7 → 258,7
|
-- Data Interface: Read Data -------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
mem_out_buf: process(rstn_i, clk_i) |
mem_di_reg: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
mdi <= (others => def_rst_val_c); |
267,7 → 267,7
mdi <= d_bus_rdata; -- memory data input register (MDI) |
end if; |
end if; |
end process mem_out_buf; |
end process mem_di_reg; |
|
-- input data alignment and sign extension -- |
read_align: process(mdi, mar, ctrl_i) |
284,17 → 284,20
-- actual data size -- |
case ctrl_i(ctrl_bus_size_msb_c downto ctrl_bus_size_lsb_c) is |
when "00" => -- byte |
rdata_o(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and byte_in_v(7))); -- sign extension |
rdata_o(07 downto 00) <= byte_in_v; |
rdata_align(31 downto 08) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and byte_in_v(7))); -- sign extension |
rdata_align(07 downto 00) <= byte_in_v; |
when "01" => -- half-word |
rdata_o(31 downto 16) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and hword_in_v(15))); -- sign extension |
rdata_o(15 downto 00) <= hword_in_v; -- high half-word |
rdata_align(31 downto 16) <= (others => ((not ctrl_i(ctrl_bus_unsigned_c)) and hword_in_v(15))); -- sign extension |
rdata_align(15 downto 00) <= hword_in_v; -- high half-word |
when others => -- word |
rdata_o <= mdi; -- full word |
rdata_align <= mdi; -- full word |
end case; |
end process read_align; |
|
-- insert exclusive lock status for SC operations only -- |
rdata_o <= exclusive_lock_status when (CPU_EXTENSION_RISCV_A = true) and (ctrl_i(ctrl_bus_ch_lock_c) = '1') else rdata_align; |
|
|
-- Data Access Arbiter -------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
data_access_arbiter: process(rstn_i, clk_i) |
304,7 → 307,6
d_arbiter.rd_req <= '0'; |
d_arbiter.err_align <= '0'; |
d_arbiter.err_bus <= '0'; |
d_arbiter.timeout <= (others => '0'); |
elsif rising_edge(clk_i) then |
-- data access request -- |
if (d_arbiter.wr_req = '0') and (d_arbiter.rd_req = '0') then -- idle |
312,12 → 314,10
d_arbiter.rd_req <= ctrl_i(ctrl_bus_rd_c); |
d_arbiter.err_align <= d_misaligned; |
d_arbiter.err_bus <= '0'; |
d_arbiter.timeout <= std_ulogic_vector(to_unsigned(BUS_TIMEOUT, index_size_f(BUS_TIMEOUT))); |
else -- in progress |
d_arbiter.timeout <= std_ulogic_vector(unsigned(d_arbiter.timeout) - 1); |
d_arbiter.err_align <= (d_arbiter.err_align or d_misaligned) and (not ctrl_i(ctrl_bus_derr_ack_c)); |
d_arbiter.err_bus <= (d_arbiter.err_bus or (not or_all_f(d_arbiter.timeout)) or d_bus_err_i or |
(st_pmp_fault and d_arbiter.wr_req) or (ld_pmp_fault and d_arbiter.rd_req)) and (not ctrl_i(ctrl_bus_derr_ack_c)); |
d_arbiter.err_bus <= (d_arbiter.err_bus or d_bus_err_i or (st_pmp_fault and d_arbiter.wr_req) or (ld_pmp_fault and d_arbiter.rd_req)) and |
(not ctrl_i(ctrl_bus_derr_ack_c)); |
if (d_bus_ack_i = '1') or (ctrl_i(ctrl_bus_derr_ack_c) = '1') then -- wait for normal termination / CPU abort |
d_arbiter.wr_req <= '0'; |
d_arbiter.rd_req <= '0'; |
326,9 → 326,6
end if; |
end process data_access_arbiter; |
|
-- cancel bus access -- |
d_bus_cancel_o <= (d_arbiter.wr_req or d_arbiter.rd_req) and ctrl_i(ctrl_bus_derr_ack_c); |
|
-- wait for bus transaction to finish -- |
d_wait_o <= (d_arbiter.wr_req or d_arbiter.rd_req) and (not d_bus_ack_i); |
|
348,7 → 345,6
d_bus_re_o <= d_bus_re_buf when (PMP_NUM_REGIONS > pmp_num_regions_critical_c) else d_bus_re; |
d_bus_fence_o <= ctrl_i(ctrl_bus_fence_c); |
d_bus_rdata <= d_bus_rdata_i; |
d_bus_excl_o <= ctrl_i(ctrl_bus_excl_c); |
|
-- additional register stage for control signals if using PMP_NUM_REGIONS > pmp_num_regions_critical_c -- |
pmp_dbus_buffer: process(rstn_i, clk_i) |
362,25 → 358,38
end if; |
end process pmp_dbus_buffer; |
|
-- Atomic memory access - status buffer -- |
atomic_access_status: process(rstn_i, clk_i) |
|
-- Reservation Controller (LR/SC [A extension]) ------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
exclusive_access_controller: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
bus_excl_ok_o <= '0'; |
exclusive_lock <= '0'; |
elsif rising_edge(clk_i) then |
if (CPU_EXTENSION_RISCV_A = true) then |
if (d_bus_ack_i = '1') then |
bus_excl_ok_o <= d_bus_excl_i; -- set if access was exclusive |
elsif (d_arbiter.rd_req = '0') and (d_arbiter.wr_req = '0') then -- bus access done |
bus_excl_ok_o <= '0'; |
if (ctrl_i(ctrl_trap_c) = '1') or (ctrl_i(ctrl_bus_de_lock_c) = '1') then -- remove lock if entering a trap or executing a non-load-reservate memory access |
exclusive_lock <= '0'; |
elsif (ctrl_i(ctrl_bus_lock_c) = '1') then -- set new lock |
exclusive_lock <= '1'; |
end if; |
else |
bus_excl_ok_o <= '0'; |
exclusive_lock <= '0'; |
end if; |
end if; |
end process atomic_access_status; |
end process exclusive_access_controller; |
|
-- lock status for SC operation -- |
exclusive_lock_status(data_width_c-1 downto 1) <= (others => '0'); |
exclusive_lock_status(0) <= not exclusive_lock; |
|
-- output reservation status to control unit (to check if SC should write at all) -- |
excl_state_o <= exclusive_lock; |
|
-- output to memory system -- |
i_bus_lock_o <= '0'; -- instruction fetches cannot be lockes |
d_bus_lock_o <= exclusive_lock; |
|
|
-- Instruction Fetch Arbiter -------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
ifetch_arbiter: process(rstn_i, clk_i) |
389,7 → 398,6
i_arbiter.rd_req <= '0'; |
i_arbiter.err_align <= '0'; |
i_arbiter.err_bus <= '0'; |
i_arbiter.timeout <= (others => '0'); |
elsif rising_edge(clk_i) then |
-- instruction fetch request -- |
if (i_arbiter.rd_req = '0') then -- idle |
396,11 → 404,9
i_arbiter.rd_req <= ctrl_i(ctrl_bus_if_c); |
i_arbiter.err_align <= i_misaligned; |
i_arbiter.err_bus <= '0'; |
i_arbiter.timeout <= std_ulogic_vector(to_unsigned(BUS_TIMEOUT, index_size_f(BUS_TIMEOUT))); |
else -- in progress |
i_arbiter.timeout <= std_ulogic_vector(unsigned(i_arbiter.timeout) - 1); |
i_arbiter.err_align <= (i_arbiter.err_align or i_misaligned) and (not ctrl_i(ctrl_bus_ierr_ack_c)); |
i_arbiter.err_bus <= (i_arbiter.err_bus or (not or_all_f(i_arbiter.timeout)) or i_bus_err_i or if_pmp_fault) and (not ctrl_i(ctrl_bus_ierr_ack_c)); |
else -- in progres |
i_arbiter.err_align <= (i_arbiter.err_align or i_misaligned) and (not ctrl_i(ctrl_bus_ierr_ack_c)); |
i_arbiter.err_bus <= (i_arbiter.err_bus or i_bus_err_i or if_pmp_fault) and (not ctrl_i(ctrl_bus_ierr_ack_c)); |
if (i_bus_ack_i = '1') or (ctrl_i(ctrl_bus_ierr_ack_c) = '1') then -- wait for normal termination / CPU abort |
i_arbiter.rd_req <= '0'; |
end if; |
410,9 → 416,6
|
i_arbiter.wr_req <= '0'; -- instruction fetch is read-only |
|
-- cancel bus access -- |
i_bus_cancel_o <= i_arbiter.rd_req and ctrl_i(ctrl_bus_ierr_ack_c); |
|
-- wait for bus transaction to finish -- |
i_wait_o <= i_arbiter.rd_req and (not i_bus_ack_i); |
|
/neorv32_cpu_control.vhd
78,6 → 78,7
alu_wait_i : in std_ulogic; -- wait for ALU |
bus_i_wait_i : in std_ulogic; -- wait for bus |
bus_d_wait_i : in std_ulogic; -- wait for bus |
excl_state_i : in std_ulogic; -- atomic/exclusive access lock status |
-- data input -- |
instr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- instruction |
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status |
124,12 → 125,14
constant hpm_cnt_lo_width_c : natural := natural(cond_sel_int_f(boolean(HPM_CNT_WIDTH < 32), HPM_CNT_WIDTH, 32)); |
constant hpm_cnt_hi_width_c : natural := natural(cond_sel_int_f(boolean(HPM_CNT_WIDTH > 32), HPM_CNT_WIDTH-32, 0)); |
|
-- instruction fetch enginge -- |
type fetch_engine_state_t is (IFETCH_RESET, IFETCH_REQUEST, IFETCH_ISSUE); |
-- instruction fetch engine -- |
type fetch_engine_state_t is (IFETCH_REQUEST, IFETCH_ISSUE); |
type fetch_engine_t is record |
state : fetch_engine_state_t; |
state_nxt : fetch_engine_state_t; |
state_prev : fetch_engine_state_t; |
restart : std_ulogic; |
restart_nxt : std_ulogic; |
pc : std_ulogic_vector(data_width_c-1 downto 0); |
pc_nxt : std_ulogic_vector(data_width_c-1 downto 0); |
reset : std_ulogic; |
137,7 → 140,7
end record; |
signal fetch_engine : fetch_engine_t; |
|
-- instrucion prefetch buffer (IPB, real FIFO) -- |
-- instruction prefetch buffer (IPB, real FIFO) -- |
type ipb_data_fifo_t is array (0 to ipb_entries_c-1) of std_ulogic_vector(2+31 downto 0); |
type ipb_t is record |
wdata : std_ulogic_vector(2+31 downto 0); -- write status (bus_error, align_error) + 32-bit instruction data |
164,7 → 167,7
signal ci_instr32 : std_ulogic_vector(31 downto 0); |
signal ci_illegal : std_ulogic; |
|
-- instruction issue enginge -- |
-- instruction issue engine -- |
type issue_engine_state_t is (ISSUE_ACTIVE, ISSUE_REALIGN); |
type issue_engine_t is record |
state : issue_engine_state_t; |
198,7 → 201,7
|
-- instruction execution engine -- |
type execute_engine_state_t is (SYS_WAIT, DISPATCH, TRAP_ENTER, TRAP_EXIT, TRAP_EXECUTE, EXECUTE, ALU_WAIT, BRANCH, |
FENCE_OP,LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, ATOMIC_SC_EVAL, SYS_ENV, CSR_ACCESS); |
FENCE_OP,LOADSTORE_0, LOADSTORE_1, LOADSTORE_2, SYS_ENV, CSR_ACCESS); |
type execute_engine_t is record |
state : execute_engine_state_t; |
state_nxt : execute_engine_state_t; |
213,7 → 216,7
is_cp_op : std_ulogic; -- current instruction is a co-processor operation |
is_cp_op_nxt : std_ulogic; |
-- |
branch_taken : std_ulogic; -- branch condition fullfilled |
branch_taken : std_ulogic; -- branch condition fulfilled |
pc : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction |
pc_mux_sel : std_ulogic; -- source select for PC update |
pc_we : std_ulogic; -- PC update enabled |
363,17 → 366,19
fetch_engine_fsm_sync: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
fetch_engine.state <= IFETCH_RESET; |
fetch_engine.state_prev <= IFETCH_RESET; |
fetch_engine.state <= IFETCH_REQUEST; |
fetch_engine.state_prev <= IFETCH_REQUEST; |
fetch_engine.restart <= '1'; |
fetch_engine.pc <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
if (fetch_engine.reset = '1') then |
fetch_engine.state <= IFETCH_RESET; |
fetch_engine.state <= fetch_engine.state_nxt; |
fetch_engine.state_prev <= fetch_engine.state; |
fetch_engine.restart <= fetch_engine.restart_nxt; |
if (fetch_engine.restart = '1') then |
fetch_engine.pc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC |
else |
fetch_engine.state <= fetch_engine.state_nxt; |
fetch_engine.pc <= fetch_engine.pc_nxt; |
end if; |
fetch_engine.state_prev <= fetch_engine.state; |
fetch_engine.pc <= fetch_engine.pc_nxt; |
end if; |
end process fetch_engine_fsm_sync; |
|
390,41 → 395,41
fetch_engine.state_nxt <= fetch_engine.state; |
fetch_engine.pc_nxt <= fetch_engine.pc; |
fetch_engine.bus_err_ack <= '0'; |
fetch_engine.restart_nxt <= fetch_engine.restart or fetch_engine.reset; |
|
-- instruction prefetch buffer interface -- |
ipb.we <= '0'; |
ipb.wdata <= be_instr_i & ma_instr_i & instr_i(31 downto 0); -- store exception info and instruction word |
ipb.clear <= '0'; |
ipb.clear <= fetch_engine.restart; |
|
-- state machine -- |
case fetch_engine.state is |
|
when IFETCH_RESET => -- reset engine and prefetch buffer, get application PC |
when IFETCH_REQUEST => -- request new 32-bit-aligned instruction word |
-- ------------------------------------------------------------ |
fetch_engine.bus_err_ack <= '1'; -- acknowledge any instruction bus errors, the execute engine has to take care of them / terminate current transfer |
fetch_engine.pc_nxt <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC |
ipb.clear <= '1'; -- clear prefetch buffer |
fetch_engine.state_nxt <= IFETCH_REQUEST; |
|
when IFETCH_REQUEST => -- output current PC to bus system and request 32-bit (aligned!) instruction data |
-- ------------------------------------------------------------ |
if (ipb.free = '1') then -- free entry in buffer? |
if (ipb.free = '1') and (fetch_engine.restart = '0') then -- free entry in buffer AND no reset request? |
bus_fast_ir <= '1'; -- fast instruction fetch request |
fetch_engine.state_nxt <= IFETCH_ISSUE; |
end if; |
if (fetch_engine.restart = '1') then -- reset request? |
fetch_engine.restart_nxt <= '0'; |
end if; |
|
when IFETCH_ISSUE => -- store instruction data to prefetch buffer |
-- ------------------------------------------------------------ |
fetch_engine.bus_err_ack <= be_instr_i or ma_instr_i; -- ACK bus/alignment errors |
if (bus_i_wait_i = '0') or (be_instr_i = '1') or (ma_instr_i = '1') then -- wait for bus response |
fetch_engine.pc_nxt <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4); |
ipb.we <= '1'; |
fetch_engine.pc_nxt <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4); |
ipb.we <= not fetch_engine.restart; -- write to IPB if not being reset |
if (fetch_engine.restart = '1') then -- reset request? |
fetch_engine.restart_nxt <= '0'; |
end if; |
fetch_engine.state_nxt <= IFETCH_REQUEST; |
end if; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
fetch_engine.state_nxt <= IFETCH_RESET; |
fetch_engine.state_nxt <= IFETCH_REQUEST; |
|
end case; |
end process fetch_engine_fsm_comb; |
687,7 → 692,7
execute_engine.state <= SYS_WAIT; |
execute_engine.sleep <= '0'; |
execute_engine.branched <= '1'; -- reset is a branch from "somewhere" |
-- no dedicated RESEt required -- |
-- no dedicated RESET required -- |
execute_engine.state_prev <= SYS_WAIT; |
execute_engine.i_reg <= (others => def_rst_val_c); |
execute_engine.is_ci <= def_rst_val_c; |
774,6 → 779,7
ctrl_o(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) <= execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c); |
-- cpu status -- |
ctrl_o(ctrl_sleep_c) <= execute_engine.sleep; -- cpu is in sleep mode |
ctrl_o(ctrl_trap_c) <= trap_ctrl.env_start_ack; -- cpu is starting a trap handler |
end process ctrl_output; |
|
|
871,7 → 877,7
-- Execute Engine FSM Comb ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
execute_engine_fsm_comb: process(execute_engine, decode_aux, fetch_engine, cmd_issue, trap_ctrl, csr, ctrl, csr_acc_valid, |
alu_wait_i, bus_d_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i) |
alu_wait_i, bus_d_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i, excl_state_i) |
variable opcode_v : std_ulogic_vector(6 downto 0); |
begin |
-- arbiter defaults -- |
915,8 → 921,12
else -- branches |
ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- unsigned branches? (BLTU, BGEU) |
end if; |
-- bus interface -- |
ctrl_nxt(ctrl_bus_excl_c) <= ctrl(ctrl_bus_excl_c); -- keep exclusive bus access request alive if set |
-- Atomic store-conditional instruction (evaluate lock status) -- |
if (CPU_EXTENSION_RISCV_A = true) then |
ctrl_nxt(ctrl_bus_ch_lock_c) <= decode_aux.is_atomic_sc; |
else |
ctrl_nxt(ctrl_bus_ch_lock_c) <= '0'; |
end if; |
|
|
-- state machine -- |
937,8 → 947,7
when DISPATCH => -- Get new command from instruction issue engine |
-- ------------------------------------------------------------ |
-- housekeeping -- |
execute_engine.is_cp_op_nxt <= '0'; -- init |
ctrl_nxt(ctrl_bus_excl_c) <= '0'; -- clear exclusive data bus access |
execute_engine.is_cp_op_nxt <= '0'; -- no compressed instruction yet |
-- PC update -- |
execute_engine.pc_mux_sel <= '0'; -- linear next PC |
-- IR update -- |
1070,9 → 1079,9
|
when opcode_load_c | opcode_store_c | opcode_atomic_c => -- load/store / atomic memory access |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_c) <= '0'; -- use RS1 as ALU.OPA |
ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB |
ctrl_nxt(ctrl_bus_mo_we_c) <= '1'; -- write to MAR and MDO (MDO only relevant for store) |
ctrl_nxt(ctrl_alu_opa_mux_c)<= '0'; -- use RS1 as ALU.OPA |
ctrl_nxt(ctrl_alu_opb_mux_c)<= '1'; -- use IMM as ALU.OPB |
ctrl_nxt(ctrl_bus_mo_we_c) <= '1'; -- write to MAR and MDO (MDO only relevant for store) |
-- |
if (CPU_EXTENSION_RISCV_A = false) or -- atomic extension disabled |
(execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "00") then -- normal integerload/store |
1221,11 → 1230,17
|
when LOADSTORE_0 => -- trigger memory request |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_excl_c) <= decode_aux.is_atomic_lr; -- atomic.LR: exclusive memory access request |
ctrl_nxt(ctrl_bus_lock_c) <= decode_aux.is_atomic_lr; -- atomic.LR: set lock |
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load or atomic load-reservate |
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request |
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request |
else -- store |
ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- write request |
if (CPU_EXTENSION_RISCV_A = true) and (decode_aux.is_atomic_sc = '1') then -- evaluate lock state |
if (excl_state_i = '1') then -- lock is still ok - perform write access |
ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- write request |
end if; |
else |
ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- (normal) write request |
end if; |
end if; |
execute_engine.state_nxt <= LOADSTORE_1; |
|
1233,23 → 1248,25
when LOADSTORE_1 => -- memory latency |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD) |
if (CPU_EXTENSION_RISCV_A = true) and (decode_aux.is_atomic_sc = '1') then -- execute and evaluate atomic store-conditional |
execute_engine.state_nxt <= ATOMIC_SC_EVAL; |
else -- normal load/store |
execute_engine.state_nxt <= LOADSTORE_2; |
end if; |
execute_engine.state_nxt <= LOADSTORE_2; |
|
|
when LOADSTORE_2 => -- wait for bus transaction to finish |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load operations) |
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load (and SC.W) operations) |
ctrl_nxt(ctrl_rf_in_mux_c) <= '1'; -- RF input = memory input (only relevant for LOADs) |
-- wait for memory response -- |
if ((ma_load_i or be_load_i or ma_store_i or be_store_i) = '1') then -- abort if exception |
execute_engine.state_nxt <= DISPATCH; |
elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction |
-- data write-back |
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load OR atomic load |
-- remove atomic lock if this is NOT the LR.W instruction used to SET the lock -- |
if (CPU_EXTENSION_RISCV_A = true) and (decode_aux.is_atomic_lr = '0') then -- execute and evaluate atomic store-conditional |
ctrl_nxt(ctrl_bus_de_lock_c) <= '1'; |
end if; |
-- data write-back -- |
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or -- normal load |
(decode_aux.is_atomic_lr = '1') or -- atomic load-reservate |
(decode_aux.is_atomic_sc = '1') then -- atomic store-conditional |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; |
end if; |
execute_engine.state_nxt <= DISPATCH; |
1256,27 → 1273,6
end if; |
|
|
when ATOMIC_SC_EVAL => -- wait for bus transaction to finish and evaluate if SC was successful |
-- ------------------------------------------------------------ |
if (CPU_EXTENSION_RISCV_A = true) then |
-- atomic.SC: result comes from "atomic co-processor" -- |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_atomic_c; |
execute_engine.is_cp_op_nxt <= '1'; -- this is a CP operation |
ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU.res |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- allow reg file write back |
-- wait for memory response -- |
if ((ma_load_i or be_load_i or ma_store_i or be_store_i) = '1') then -- abort if exception |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; -- trigger atomic-coprocessor operation for SC status evaluation |
execute_engine.state_nxt <= ALU_WAIT; |
elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; -- trigger atomic-coprocessor operation for SC status evaluation |
execute_engine.state_nxt <= ALU_WAIT; |
end if; |
else |
execute_engine.state_nxt <= SYS_WAIT; |
end if; |
|
|
when others => -- undefined |
-- ------------------------------------------------------------ |
execute_engine.state_nxt <= SYS_WAIT; |
/neorv32_icache.vhd
60,7 → 60,6
host_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable |
host_we_i : in std_ulogic; -- write enable |
host_re_i : in std_ulogic; -- read enable |
host_cancel_i : in std_ulogic; -- cancel current bus transaction |
host_ack_o : out std_ulogic; -- bus transfer acknowledge |
host_err_o : out std_ulogic; -- bus transfer error |
-- peripheral bus interface -- |
70,7 → 69,6
bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
bus_we_o : out std_ulogic; -- write enable |
bus_re_o : out std_ulogic; -- read enable |
bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
bus_err_i : in std_ulogic -- bus transfer error |
); |
132,17 → 130,15
|
-- control engine -- |
type ctrl_engine_state_t is (S_IDLE, S_CACHE_CLEAR, S_CACHE_CHECK, S_CACHE_MISS, S_BUS_DOWNLOAD_REQ, S_BUS_DOWNLOAD_GET, |
S_CACHE_RESYNC_0, S_CACHE_RESYNC_1, S_BUS_ERROR, S_ERROR, S_HOST_CANCEL); |
S_CACHE_RESYNC_0, S_CACHE_RESYNC_1, S_BUS_ERROR); |
type ctrl_t is record |
state : ctrl_engine_state_t; -- current state |
state_nxt : ctrl_engine_state_t; -- next state |
addr_reg : std_ulogic_vector(31 downto 0); -- address register for block download |
addr_reg_nxt : std_ulogic_vector(31 downto 0); |
state : ctrl_engine_state_t; -- current state |
state_nxt : ctrl_engine_state_t; -- next state |
addr_reg : std_ulogic_vector(31 downto 0); -- address register for block download |
addr_reg_nxt : std_ulogic_vector(31 downto 0); |
-- |
re_buf : std_ulogic; -- read request buffer |
re_buf_nxt : std_ulogic; |
cancel_buf : std_ulogic; -- cancel request buffer |
cancel_buf_nxt : std_ulogic; |
re_buf : std_ulogic; -- read request buffer |
re_buf_nxt : std_ulogic; |
end record; |
signal ctrl : ctrl_t; |
|
165,13 → 161,11
ctrl_engine_fsm_sync_rst: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
ctrl.state <= S_CACHE_CLEAR; |
ctrl.re_buf <= '0'; |
ctrl.cancel_buf <= '0'; |
ctrl.state <= S_CACHE_CLEAR; |
ctrl.re_buf <= '0'; |
elsif rising_edge(clk_i) then |
ctrl.state <= ctrl.state_nxt; |
ctrl.re_buf <= ctrl.re_buf_nxt; |
ctrl.cancel_buf <= ctrl.cancel_buf_nxt; |
ctrl.state <= ctrl.state_nxt; |
ctrl.re_buf <= ctrl.re_buf_nxt; |
end if; |
end process ctrl_engine_fsm_sync_rst; |
|
186,13 → 180,12
|
-- Control Engine FSM Comb ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
ctrl_engine_fsm_comb: process(ctrl, cache, clear_i, host_addr_i, host_re_i, host_cancel_i, bus_rdata_i, bus_ack_i, bus_err_i) |
ctrl_engine_fsm_comb: process(ctrl, cache, clear_i, host_addr_i, host_re_i, bus_rdata_i, bus_ack_i, bus_err_i) |
begin |
-- control defaults -- |
ctrl.state_nxt <= ctrl.state; |
ctrl.addr_reg_nxt <= ctrl.addr_reg; |
ctrl.re_buf_nxt <= (ctrl.re_buf or host_re_i) and (not host_cancel_i); |
ctrl.cancel_buf_nxt <= ctrl.cancel_buf or host_cancel_i; |
ctrl.re_buf_nxt <= ctrl.re_buf or host_re_i; |
|
-- cache defaults -- |
cache.clear <= '0'; |
216,7 → 209,6
bus_ben_o <= (others => '0'); -- cache is read-only |
bus_we_o <= '0'; -- cache is read-only |
bus_re_o <= '0'; |
bus_cancel_o <= '0'; |
|
-- fsm -- |
case ctrl.state is |
226,9 → 218,8
if (clear_i = '1') then -- cache control operation? |
ctrl.state_nxt <= S_CACHE_CLEAR; |
elsif (host_re_i = '1') or (ctrl.re_buf = '1') then -- cache access |
ctrl.re_buf_nxt <= '0'; |
ctrl.cancel_buf_nxt <= '0'; |
ctrl.state_nxt <= S_CACHE_CHECK; |
ctrl.re_buf_nxt <= '0'; |
ctrl.state_nxt <= S_CACHE_CHECK; |
end if; |
|
when S_CACHE_CLEAR => -- invalidate all cache entries |
239,7 → 230,7
when S_CACHE_CHECK => -- finalize host access if cache hit |
-- ------------------------------------------------------------ |
if (cache.hit = '1') then -- cache HIT |
host_ack_o <= not ctrl.cancel_buf; -- ACK if request has not been canceled |
host_ack_o <= '1'; |
ctrl.state_nxt <= S_IDLE; |
else -- cache MISS |
ctrl.state_nxt <= S_CACHE_MISS; |
252,14 → 243,11
ctrl.addr_reg_nxt((2+cache_offset_size_c)-1 downto 2) <= (others => '0'); -- block-aligned |
ctrl.addr_reg_nxt(1 downto 0) <= "00"; -- word-aligned |
-- |
if (host_cancel_i = '1') or (ctrl.cancel_buf = '1') then -- 'early' CPU cancel (abort before bus transaction has even started) |
ctrl.state_nxt <= S_IDLE; |
else |
ctrl.state_nxt <= S_BUS_DOWNLOAD_REQ; |
end if; |
ctrl.state_nxt <= S_BUS_DOWNLOAD_REQ; |
|
when S_BUS_DOWNLOAD_REQ => -- download new cache block: request new word |
-- ------------------------------------------------------------ |
cache.ctrl_en <= '1'; -- we are in cache control mode |
bus_re_o <= '1'; -- request new read transfer |
ctrl.state_nxt <= S_BUS_DOWNLOAD_GET; |
|
269,8 → 257,6
-- |
if (bus_err_i = '1') then -- bus error |
ctrl.state_nxt <= S_BUS_ERROR; |
elsif (ctrl.cancel_buf = '1') then -- 'late' CPU cancel (timeout?) |
ctrl.state_nxt <= S_HOST_CANCEL; |
elsif (bus_ack_i = '1') then -- ACK = write to cache and get next word |
cache.ctrl_we <= '1'; -- write to cache |
if (and_all_f(ctrl.addr_reg((2+cache_offset_size_c)-1 downto 2)) = '1') then -- block complete? |
289,28 → 275,14
|
when S_CACHE_RESYNC_1 => -- re-sync host/cache access: finalize CPU request |
-- ------------------------------------------------------------ |
host_ack_o <= not ctrl.cancel_buf; -- ACK if request has not been canceled |
host_ack_o <= '1'; |
ctrl.state_nxt <= S_IDLE; |
|
when S_BUS_ERROR => -- bus error during download |
-- ------------------------------------------------------------ |
host_err_o <= '1'; |
ctrl.state_nxt <= S_ERROR; |
ctrl.state_nxt <= S_IDLE; |
|
when S_ERROR => -- wait for CPU to cancel faulting transfer |
-- ------------------------------------------------------------ |
if (host_cancel_i = '1') then |
bus_cancel_o <= '1'; |
ctrl.state_nxt <= S_IDLE; |
end if; |
|
when S_HOST_CANCEL => -- host cancels transfer |
-- ------------------------------------------------------------ |
cache.ctrl_en <= '1'; -- we are in cache control mode |
cache.ctrl_invalid_we <= '1'; -- invalidate current cache block |
bus_cancel_o <= '1'; |
ctrl.state_nxt <= S_IDLE; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
ctrl.state_nxt <= S_IDLE; |
503,7 → 475,7
history.re_ff <= host_re_i; |
if (invalidate_i = '1') then -- invalidate whole cache |
history.last_used_set <= (others => '1'); |
elsif (history.re_ff = '1') and (or_all_f(hit) = '1') then -- store last accessed set that caused a hit |
elsif (history.re_ff = '1') and (or_all_f(hit) = '1') and (ctrl_en_i = '0') then -- store last accessed set that caused a hit |
history.last_used_set(to_integer(unsigned(cache_index))) <= not hit(0); |
end if; |
history.to_be_replaced <= history.last_used_set(to_integer(unsigned(cache_index))); |
/neorv32_mtime.vhd
2,7 → 2,7
-- # << NEORV32 - Machine System Timer (MTIME) >> # |
-- # ********************************************************************************************* # |
-- # Compatible to RISC-V spec's 64-bit MACHINE system timer including "mtime[h]" & "mtimecmp[h]". # |
-- # Note: The 64-bit counter and compare system is broken and de-coupled into two 32-bit systems. # |
-- # Note: The 64-bit counter and compare systems are de-coupled into two 32-bit systems. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
71,6 → 71,11
signal addr : std_ulogic_vector(31 downto 0); -- access address |
signal wren : std_ulogic; -- module access enable |
|
-- time write access buffer -- |
signal wdata_buf : std_ulogic_vector(31 downto 0); |
signal mtime_lo_we : std_ulogic; |
signal mtime_hi_we : std_ulogic; |
|
-- accessible regs -- |
signal mtimecmp_lo : std_ulogic_vector(31 downto 0); |
signal mtimecmp_hi : std_ulogic_vector(31 downto 0); |
77,6 → 82,7
signal mtime_lo : std_ulogic_vector(32 downto 0); |
signal mtime_lo_msb_ff : std_ulogic; |
signal mtime_hi : std_ulogic_vector(31 downto 0); |
signal inc_hi : std_ulogic_vector(31 downto 0); |
|
-- irq control -- |
signal cmp_lo : std_ulogic; |
98,20 → 104,25
wr_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- mtimecmp low -- |
if (wren = '1') and (addr = mtime_cmp_lo_addr_c) then |
mtimecmp_lo <= data_i; |
-- mtimecmp -- |
if (wren = '1') then |
if (addr = mtime_cmp_lo_addr_c) then |
mtimecmp_lo <= data_i; |
end if; |
if (addr = mtime_cmp_hi_addr_c) then |
mtimecmp_hi <= data_i; |
end if; |
end if; |
|
-- mtimecmp high -- |
if (wren = '1') and (addr = mtime_cmp_hi_addr_c) then |
mtimecmp_hi <= data_i; |
end if; |
-- mtime access buffer -- |
wdata_buf <= data_i; |
mtime_lo_we <= wren and bool_to_ulogic_f(boolean(addr = mtime_time_lo_addr_c)); |
mtime_hi_we <= wren and bool_to_ulogic_f(boolean(addr = mtime_time_hi_addr_c)); |
|
-- mtime low -- |
if (wren = '1') and (addr = mtime_time_lo_addr_c) then |
if (mtime_lo_we = '1') then -- write access |
mtime_lo_msb_ff <= '0'; |
mtime_lo <= '0' & data_i; |
mtime_lo <= '0' & wdata_buf; |
else -- auto increment |
mtime_lo_msb_ff <= mtime_lo(mtime_lo'left); |
mtime_lo <= std_ulogic_vector(unsigned(mtime_lo) + 1); |
118,15 → 129,19
end if; |
|
-- mtime high -- |
if (wren = '1') and (addr = mtime_time_hi_addr_c) then |
mtime_hi <= data_i; |
elsif ((mtime_lo_msb_ff xor mtime_lo(mtime_lo'left)) = '1') then -- auto increment: mtime_lo carry? |
mtime_hi <= std_ulogic_vector(unsigned(mtime_hi) + 1); |
if (mtime_hi_we = '1') then -- write access |
mtime_hi <= wdata_buf; |
else -- auto increment (if mtime.low overflows) |
mtime_hi <= std_ulogic_vector(unsigned(mtime_hi) + unsigned(inc_hi)); |
end if; |
end if; |
end process wr_access; |
|
-- mtime.time_HI increment (0 or 1) -- |
inc_hi(0) <= mtime_lo_msb_ff xor mtime_lo(mtime_lo'left); |
inc_hi(31 downto 1) <= (others => '0'); |
|
|
-- Read Access ---------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
rd_access: process(clk_i) |
/neorv32_package.vhd
45,12 → 45,11
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- default data memory address space base address |
|
-- (external) bus interface -- |
constant bus_timeout_c : natural := 127; -- cycles after which an *unacknowledged* bus access will timeout and trigger a bus fault exception (min 2) |
constant wb_pipe_mode_c : boolean := false; -- *external* bus protocol: false=classic/standard wishbone mode (default), true=pipelined wishbone mode |
constant xbus_big_endian_c : boolean := true; -- external memory access byte order: true=big endian (default); false=little endian |
|
-- CPU core -- |
constant ipb_entries_c : natural := 2; -- entries in CPU instruction prefetch buffer, has to be a power of 2, default=2 |
constant ipb_entries_c : natural := 4; -- entries in CPU instruction prefetch buffer, has to be a power of 2, default=2 |
constant cp_timeout_en_c : boolean := false; -- auto-terminate pending co-processor operations after 256 cycles (for debugging only), default = false |
constant dedicated_reset_c : boolean := false; -- use dedicated hardware reset value for UNCRITICAL registers (FALSE=reset value is irrelevant (might simplify HW), default; TRUE=defined LOW reset value) |
|
59,6 → 58,9
-- increasing instruction fetch & data access latency by +1 cycle but also reducing critical path length |
constant pmp_num_regions_critical_c : natural := 8; -- default=8 |
|
-- "response time window" for processor-internal memories and IO devices |
constant max_proc_int_response_time_c : natural := 15; -- cycles after which an *unacknowledged* internal bus access will timeout and trigger a bus fault exception (min 2) |
|
-- Helper Functions ----------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
function index_size_f(input : natural) return natural; |
81,7 → 83,7
-- Architecture Constants (do not modify!) ------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
constant data_width_c : natural := 32; -- native data path width - do not change! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01050400"; -- no touchy! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01050408"; -- no touchy! |
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off! |
constant rf_r0_is_reg_c : boolean := true; -- x0 is a *physical register* that has to be initialized to zero by the CPU |
constant def_rst_val_c : std_ulogic := cond_sel_stdulogic_f(dedicated_reset_c, '0', '-'); |
263,14 → 265,13
constant ctrl_bus_derr_ack_c : natural := 38; -- acknowledge data access bus exceptions |
constant ctrl_bus_fence_c : natural := 39; -- executed fence operation |
constant ctrl_bus_fencei_c : natural := 40; -- executed fencei operation |
constant ctrl_bus_excl_c : natural := 41; -- exclusive bus access |
constant ctrl_bus_lock_c : natural := 41; -- make atomic/exclusive access lock |
constant ctrl_bus_de_lock_c : natural := 42; -- remove atomic/exclusive access |
constant ctrl_bus_ch_lock_c : natural := 43; -- evaluate atomic/exclusive lock (SC operation) |
-- co-processors -- |
constant ctrl_cp_id_lsb_c : natural := 42; -- cp select ID lsb |
constant ctrl_cp_id_hsb_c : natural := 43; -- cp select ID |
constant ctrl_cp_id_msb_c : natural := 44; -- cp select ID msb |
-- current privilege level -- |
constant ctrl_priv_lvl_lsb_c : natural := 45; -- privilege level lsb |
constant ctrl_priv_lvl_msb_c : natural := 46; -- privilege level msb |
constant ctrl_cp_id_lsb_c : natural := 44; -- cp select ID lsb |
constant ctrl_cp_id_hsb_c : natural := 45; -- cp select ID |
constant ctrl_cp_id_msb_c : natural := 46; -- cp select ID msb |
-- instruction's control blocks (used by cpu co-processors) -- |
constant ctrl_ir_funct3_0_c : natural := 47; -- funct3 bit 0 |
constant ctrl_ir_funct3_1_c : natural := 48; -- funct3 bit 1 |
295,9 → 296,12
constant ctrl_ir_opcode7_5_c : natural := 67; -- opcode7 bit 5 |
constant ctrl_ir_opcode7_6_c : natural := 68; -- opcode7 bit 6 |
-- CPU status -- |
constant ctrl_sleep_c : natural := 69; -- set when CPU is in sleep mode |
constant ctrl_priv_lvl_lsb_c : natural := 69; -- privilege level lsb |
constant ctrl_priv_lvl_msb_c : natural := 70; -- privilege level msb |
constant ctrl_sleep_c : natural := 71; -- set when CPU is in sleep mode |
constant ctrl_trap_c : natural := 72; -- set when CPU is entering trap execution |
-- control bus size -- |
constant ctrl_width_c : natural := 70; -- control bus size |
constant ctrl_width_c : natural := 73; -- control bus size |
|
-- Comparator Bus ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
723,12 → 727,12
|
-- Co-Processor IDs ----------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
constant cp_sel_muldiv_c : std_ulogic_vector(2 downto 0) := "000"; -- multiplication/division operations ('M' extension) |
constant cp_sel_atomic_c : std_ulogic_vector(2 downto 0) := "001"; -- atomic operations; success/failure evaluation ('A' extension) |
constant cp_sel_csr_rd_c : std_ulogic_vector(2 downto 0) := "000"; -- CSR read access ('Zicsr' extension) |
constant cp_sel_muldiv_c : std_ulogic_vector(2 downto 0) := "001"; -- multiplication/division operations ('M' extension) |
constant cp_sel_bitmanip_c : std_ulogic_vector(2 downto 0) := "010"; -- bit manipulation ('B' extension) |
constant cp_sel_csr_rd_c : std_ulogic_vector(2 downto 0) := "011"; -- CSR read access ('Zicsr' extension) |
constant cp_sel_fpu_c : std_ulogic_vector(2 downto 0) := "100"; -- loating-point unit ('Zfinx' extension) |
--constant cp_sel_crypto_c : std_ulogic_vector(2 downto 0) := "101"; -- crypto operations ('K' extension) |
constant cp_sel_fpu_c : std_ulogic_vector(2 downto 0) := "011"; -- floating-point unit ('Zfinx' extension) |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "100"; -- reserved |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "101"; -- reserved |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "110"; -- reserved |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "111"; -- reserved |
|
873,7 → 877,7
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_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
-- Extension Options -- |
901,6 → 905,7
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
-- External memory interface -- |
MEM_EXT_EN : boolean := false; -- implement external memory bus interface? |
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled) |
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)? |
923,7 → 928,7
clk_i : in std_ulogic := '0'; -- global clock, rising edge |
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async |
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o : out std_ulogic_vector(03 downto 0); -- request tag |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
931,7 → 936,7
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_tag_i : in std_ulogic; -- response tag |
wb_lock_o : out std_ulogic; -- exclusive access request |
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_EN = true) -- |
984,7 → 989,6
-- General -- |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
CPU_BOOT_ADDR : std_ulogic_vector(31 downto 0) := x"00000000"; -- cpu boot address |
BUS_TIMEOUT : natural := 63; -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_B : boolean := false; -- implement bit manipulation extensions? |
1019,7 → 1023,7
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
i_bus_we_o : out std_ulogic; -- write enable |
i_bus_re_o : out std_ulogic; -- read enable |
i_bus_cancel_o : out std_ulogic := '0'; -- cancel current bus transaction |
i_bus_lock_o : out std_ulogic; -- exclusive access request |
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 |
1031,13 → 1035,11
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
d_bus_we_o : out std_ulogic; -- write enable |
d_bus_re_o : out std_ulogic; -- read enable |
d_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
d_bus_lock_o : out std_ulogic; -- exclusive access request |
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 |
d_bus_excl_o : out std_ulogic; -- exclusive access |
d_bus_excl_i : in std_ulogic; -- state of exclusiv access (set if success) |
-- system time input from MTIME -- |
time_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time |
-- interrupts (risc-v compliant) -- |
1085,6 → 1087,7
alu_wait_i : in std_ulogic; -- wait for ALU |
bus_i_wait_i : in std_ulogic; -- wait for bus |
bus_d_wait_i : in std_ulogic; -- wait for bus |
excl_state_i : in std_ulogic; -- atomic/exclusive access lock status |
-- data input -- |
instr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- instruction |
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status |
1236,13 → 1239,11
-- ------------------------------------------------------------------------------------------- |
component neorv32_cpu_bus |
generic ( |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension? |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension? |
-- Physical memory protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Bus Timeout -- |
BUS_TIMEOUT : natural := 63 -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024 -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
); |
port ( |
-- global control -- |
1263,7 → 1264,7
mar_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current memory address register |
d_wait_o : out std_ulogic; -- wait for access to complete |
-- |
bus_excl_ok_o : out std_ulogic; -- bus exclusive access successful |
excl_state_o : out std_ulogic; -- atomic/exclusive access status |
ma_load_o : out std_ulogic; -- misaligned load data address |
ma_store_o : out std_ulogic; -- misaligned store data address |
be_load_o : out std_ulogic; -- bus error on load data access |
1278,7 → 1279,7
i_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
i_bus_we_o : out std_ulogic; -- write enable |
i_bus_re_o : out std_ulogic; -- read enable |
i_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
i_bus_lock_o : out std_ulogic; -- exclusive access request |
i_bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
i_bus_err_i : in std_ulogic; -- bus transfer error |
i_bus_fence_o : out std_ulogic; -- fence operation |
1289,15 → 1290,37
d_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
d_bus_we_o : out std_ulogic; -- write enable |
d_bus_re_o : out std_ulogic; -- read enable |
d_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
d_bus_lock_o : out std_ulogic; -- exclusive access request |
d_bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
d_bus_err_i : in std_ulogic; -- bus transfer error |
d_bus_fence_o : out std_ulogic; -- fence operation |
d_bus_excl_o : out std_ulogic; -- exclusive access request |
d_bus_excl_i : in std_ulogic -- state of exclusiv access (set if success) |
d_bus_fence_o : out std_ulogic -- fence operation |
); |
end component; |
|
-- Component: Bus Keeper ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
component neorv32_bus_keeper is |
generic ( |
-- Internal instruction memory -- |
MEM_INT_IMEM_EN : 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_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 8*1024 -- size of processor-internal data memory in bytes |
); |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
rstn_i : in std_ulogic; -- global reset line, low-active |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
ack_i : in std_ulogic; -- transfer acknowledge from bus system |
err_i : in std_ulogic; -- transfer error from bus system |
err_o : out std_ulogic -- bus error |
); |
end component; |
|
-- Component: CPU Instruction Cache ------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_icache |
1318,7 → 1341,6
host_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable |
host_we_i : in std_ulogic; -- write enable |
host_re_i : in std_ulogic; -- read enable |
host_cancel_i : in std_ulogic; -- cancel current bus transaction |
host_ack_o : out std_ulogic; -- bus transfer acknowledge |
host_err_o : out std_ulogic; -- bus transfer error |
-- peripheral bus interface -- |
1328,7 → 1350,6
bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
bus_we_o : out std_ulogic; -- write enable |
bus_re_o : out std_ulogic; -- read enable |
bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
bus_err_i : in std_ulogic -- bus transfer error |
); |
1352,8 → 1373,7
ca_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable |
ca_bus_we_i : in std_ulogic; -- write enable |
ca_bus_re_i : in std_ulogic; -- read enable |
ca_bus_cancel_i : in std_ulogic; -- cancel current bus transaction |
ca_bus_excl_i : in std_ulogic; -- exclusive access |
ca_bus_lock_i : in std_ulogic; -- exclusive access request |
ca_bus_ack_o : out std_ulogic; -- bus transfer acknowledge |
ca_bus_err_o : out std_ulogic; -- bus transfer error |
-- controller interface b -- |
1363,8 → 1383,7
cb_bus_ben_i : in std_ulogic_vector(03 downto 0); -- byte enable |
cb_bus_we_i : in std_ulogic; -- write enable |
cb_bus_re_i : in std_ulogic; -- read enable |
cb_bus_cancel_i : in std_ulogic; -- cancel current bus transaction |
cb_bus_excl_i : in std_ulogic; -- exclusive access |
cb_bus_lock_i : in std_ulogic; -- exclusive access request |
cb_bus_ack_o : out std_ulogic; -- bus transfer acknowledge |
cb_bus_err_o : out std_ulogic; -- bus transfer error |
-- peripheral bus -- |
1375,8 → 1394,7
p_bus_ben_o : out std_ulogic_vector(03 downto 0); -- byte enable |
p_bus_we_o : out std_ulogic; -- write enable |
p_bus_re_o : out std_ulogic; -- read enable |
p_bus_cancel_o : out std_ulogic; -- cancel current bus transaction |
p_bus_excl_o : out std_ulogic; -- exclusive access |
p_bus_lock_o : out std_ulogic; -- exclusive access request |
p_bus_ack_i : in std_ulogic; -- bus transfer acknowledge |
p_bus_err_i : in std_ulogic -- bus transfer error |
); |
1635,38 → 1653,38
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes |
-- Internal data memory -- |
MEM_INT_DMEM_EN : 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_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes |
-- Bus Timeout -- |
BUS_TIMEOUT : natural := 63 -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
); |
port ( |
-- global control -- |
clk_i : in std_ulogic; -- global clock line |
rstn_i : in std_ulogic; -- global reset line, low-active |
clk_i : in std_ulogic; -- global clock line |
rstn_i : in std_ulogic; -- global reset line, low-active |
-- host access -- |
src_i : in std_ulogic; -- access type (0: data, 1:instruction) |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
cancel_i : in std_ulogic; -- cancel current bus transaction |
excl_i : in std_ulogic; -- exclusive access request |
excl_o : out std_ulogic; -- state of exclusiv access (set if success) |
ack_o : out std_ulogic; -- transfer acknowledge |
err_o : out std_ulogic; -- transfer error |
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level |
src_i : in std_ulogic; -- access type (0: data, 1:instruction) |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
lock_i : in std_ulogic; -- exclusive access request |
ack_o : out std_ulogic; -- transfer acknowledge |
err_o : out std_ulogic; -- transfer error |
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level |
-- wishbone interface -- |
wb_tag_o : out std_ulogic_vector(03 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_tag_i : in std_ulogic; -- response tag |
wb_ack_i : in std_ulogic; -- transfer acknowledge |
wb_err_i : in std_ulogic -- transfer error |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_lock_o : out std_ulogic; -- exclusive access request |
wb_ack_i : in std_ulogic; -- transfer acknowledge |
wb_err_i : in std_ulogic -- transfer error |
); |
end component; |
|
/neorv32_sysinfo.vhd
131,7 → 131,9
sysinfo_mem(2)(05) <= bool_to_ulogic_f(xbus_big_endian_c); -- is external memory bus interface using BIG-endian byte-order? |
sysinfo_mem(2)(06) <= bool_to_ulogic_f(ICACHE_EN); -- processor-internal instruction cache implemented? |
-- |
sysinfo_mem(2)(15 downto 07) <= (others => '0'); -- reserved |
sysinfo_mem(2)(14 downto 07) <= (others => '0'); -- reserved |
-- Misc -- |
sysinfo_mem(2)(15) <= bool_to_ulogic_f(dedicated_reset_c); -- dedicated hardware reset of all core registers? |
-- IO -- |
sysinfo_mem(2)(16) <= bool_to_ulogic_f(IO_GPIO_EN); -- general purpose input/output port unit (GPIO) implemented? |
sysinfo_mem(2)(17) <= bool_to_ulogic_f(IO_MTIME_EN); -- machine system timer (MTIME) implemented? |
/neorv32_top.vhd
60,7 → 60,7
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_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
|
95,6 → 95,7
|
-- External memory interface -- |
MEM_EXT_EN : boolean := false; -- implement external memory bus interface? |
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled) |
|
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
119,7 → 120,7
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async |
|
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o : out std_ulogic_vector(03 downto 0); -- request tag |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
127,7 → 128,7
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_tag_i : in std_ulogic := '0'; -- response tag |
wb_lock_o : out std_ulogic; -- exclusive access request |
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge |
wb_err_i : in std_ulogic := '0'; -- transfer error |
|
190,10 → 191,6
-- CPU boot address -- |
constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(BOOTLOADER_EN, boot_rom_base_c, ispace_base_c); |
|
-- Bus timeout -- |
constant bus_timeout_temp_c : natural := 2**index_size_f(bus_timeout_c); -- round to next power-of-two |
constant bus_timeout_proc_c : natural := cond_sel_natural_f(ICACHE_EN, ((ICACHE_BLOCK_SIZE/4)*bus_timeout_temp_c)-1, bus_timeout_c); |
|
-- alignment check for internal memories -- |
constant imem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) := (others => '0'); |
constant dmem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) := (others => '0'); |
231,16 → 228,14
ben : std_ulogic_vector(03 downto 0); -- byte enable |
we : std_ulogic; -- write enable |
re : std_ulogic; -- read enable |
cancel : std_ulogic; -- cancel current transfer |
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 |
src : std_ulogic; -- access source (1=instruction fetch, 0=data access) |
excl : std_ulogic; -- exclusive access |
lock : std_ulogic; -- exclusive access request |
end record; |
signal cpu_i, i_cache, cpu_d, p_bus : bus_interface_t; |
signal cpu_d_exclr : std_ulogic; -- CPU D-bus, exclusive access response |
|
-- io space access -- |
signal io_acc : std_ulogic; |
257,7 → 252,6
signal wishbone_rdata : std_ulogic_vector(data_width_c-1 downto 0); |
signal wishbone_ack : std_ulogic; |
signal wishbone_err : std_ulogic; |
signal wishbone_exclr : std_ulogic; |
signal gpio_rdata : std_ulogic_vector(data_width_c-1 downto 0); |
signal gpio_ack : std_ulogic; |
signal mtime_rdata : std_ulogic_vector(data_width_c-1 downto 0); |
284,6 → 278,7
signal neoled_ack : std_ulogic; |
signal sysinfo_rdata : std_ulogic_vector(data_width_c-1 downto 0); |
signal sysinfo_ack : std_ulogic; |
signal bus_keeper_err : std_ulogic; |
|
-- IRQs -- |
signal mtime_irq : std_ulogic; |
332,10 → 327,7
assert not (dspace_base_c /= x"80000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framework." severity warning; |
-- memory system - the i-cache is intended to accelerate instruction fetch via the external memory interface only -- |
assert not ((ICACHE_EN = true) and (MEM_EXT_EN = false)) report "NEORV32 PROCESSOR CONFIG NOTE. Implementing i-cache without having the external memory interface implemented. The i-cache is intended to accelerate instruction fetch via the external memory interface." severity note; |
-- memory system - cached instruction fetch latency check -- |
assert not (ICACHE_EN = true) report "NEORV32 PROCESSOR CONFIG WARNING! Implementing i-cache. Increasing bus access timeout from " & integer'image(bus_timeout_c) & " cycles to " & integer'image(bus_timeout_proc_c) & " cycles." severity warning; |
|
|
-- Reset Generator ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
reset_generator_sync: process(clk_i) |
411,7 → 403,6
-- General -- |
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id |
CPU_BOOT_ADDR => cpu_boot_addr_c, -- cpu boot address |
BUS_TIMEOUT => bus_timeout_proc_c, -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension? |
CPU_EXTENSION_RISCV_B => CPU_EXTENSION_RISCV_B, -- implement bit manipulation extensions? |
445,7 → 436,7
i_bus_ben_o => cpu_i.ben, -- byte enable |
i_bus_we_o => cpu_i.we, -- write enable |
i_bus_re_o => cpu_i.re, -- read enable |
i_bus_cancel_o => cpu_i.cancel, -- cancel current bus transaction |
i_bus_lock_o => cpu_i.lock, -- exclusive access request |
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 |
457,13 → 448,11
d_bus_ben_o => cpu_d.ben, -- byte enable |
d_bus_we_o => cpu_d.we, -- write enable |
d_bus_re_o => cpu_d.re, -- read enable |
d_bus_cancel_o => cpu_d.cancel, -- cancel current bus transaction |
d_bus_lock_o => cpu_d.lock, -- exclusive access request |
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 |
d_bus_excl_o => cpu_d.excl, -- exclusive access |
d_bus_excl_i => cpu_d_exclr, -- state of exclusiv access (set if success) |
-- system time input from MTIME -- |
time_i => mtime_time, -- current system time |
-- interrupts (risc-v compliant) -- |
476,9 → 465,8
); |
|
-- misc -- |
cpu_i.excl <= '0'; -- i-fetch cannot do exclusive accesses |
cpu_i.src <= '1'; -- initialized but unused |
cpu_d.src <= '0'; -- initialized but unused |
cpu_i.src <= '1'; -- initialized but unused |
cpu_d.src <= '0'; -- initialized but unused |
|
-- advanced memory control -- |
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation |
530,7 → 518,6
host_ben_i => cpu_i.ben, -- byte enable |
host_we_i => cpu_i.we, -- write enable |
host_re_i => cpu_i.re, -- read enable |
host_cancel_i => cpu_i.cancel, -- cancel current bus transaction |
host_ack_o => cpu_i.ack, -- bus transfer acknowledge |
host_err_o => cpu_i.err, -- bus transfer error |
-- peripheral bus interface -- |
540,29 → 527,27
bus_ben_o => i_cache.ben, -- byte enable |
bus_we_o => i_cache.we, -- write enable |
bus_re_o => i_cache.re, -- read enable |
bus_cancel_o => i_cache.cancel, -- cancel current bus transaction |
bus_ack_i => i_cache.ack, -- bus transfer acknowledge |
bus_err_i => i_cache.err -- bus transfer error |
); |
end generate; |
|
-- TODO: do not use LOCKED instruction fetch -- |
i_cache.lock <= '0'; |
|
neorv32_icache_inst_false: |
if (ICACHE_EN = false) generate |
i_cache.addr <= cpu_i.addr; |
cpu_i.rdata <= i_cache.rdata; |
i_cache.wdata <= cpu_i.wdata; |
i_cache.ben <= cpu_i.ben; |
i_cache.we <= cpu_i.we; |
i_cache.re <= cpu_i.re; |
i_cache.cancel <= cpu_i.cancel; |
cpu_i.ack <= i_cache.ack; |
cpu_i.err <= i_cache.err; |
i_cache.addr <= cpu_i.addr; |
cpu_i.rdata <= i_cache.rdata; |
i_cache.wdata <= cpu_i.wdata; |
i_cache.ben <= cpu_i.ben; |
i_cache.we <= cpu_i.we; |
i_cache.re <= cpu_i.re; |
cpu_i.ack <= i_cache.ack; |
cpu_i.err <= i_cache.err; |
end generate; |
|
-- no exclusive accesses for i-fetch -- |
i_cache.excl <= '0'; |
|
|
-- CPU Bus Switch ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_busswitch_inst: neorv32_busswitch |
581,8 → 566,7
ca_bus_ben_i => cpu_d.ben, -- byte enable |
ca_bus_we_i => cpu_d.we, -- write enable |
ca_bus_re_i => cpu_d.re, -- read enable |
ca_bus_cancel_i => cpu_d.cancel, -- cancel current bus transaction |
ca_bus_excl_i => cpu_d.excl, -- exclusive access |
ca_bus_lock_i => cpu_d.lock, -- exclusive access request |
ca_bus_ack_o => cpu_d.ack, -- bus transfer acknowledge |
ca_bus_err_o => cpu_d.err, -- bus transfer error |
-- controller interface b -- |
592,8 → 576,7
cb_bus_ben_i => i_cache.ben, -- byte enable |
cb_bus_we_i => i_cache.we, -- write enable |
cb_bus_re_i => i_cache.re, -- read enable |
cb_bus_cancel_i => i_cache.cancel, -- cancel current bus transaction |
cb_bus_excl_i => i_cache.excl, -- exclusive access |
cb_bus_lock_i => i_cache.lock, -- exclusive access request |
cb_bus_ack_o => i_cache.ack, -- bus transfer acknowledge |
cb_bus_err_o => i_cache.err, -- bus transfer error |
-- peripheral bus -- |
604,8 → 587,7
p_bus_ben_o => p_bus.ben, -- byte enable |
p_bus_we_o => p_bus.we, -- write enable |
p_bus_re_o => p_bus.re, -- read enable |
p_bus_cancel_o => p_bus.cancel, -- cancel current bus transaction |
p_bus_excl_o => p_bus.excl, -- exclusive access |
p_bus_lock_o => p_bus.lock, -- exclusive access request |
p_bus_ack_i => p_bus.ack, -- bus transfer acknowledge |
p_bus_err_i => p_bus.err -- bus transfer error |
); |
622,13 → 604,33
spi_ack or twi_ack or pwm_ack or wdt_ack or trng_ack or cfs_ack or nco_ack or neoled_ack or sysinfo_ack); |
|
-- processor bus: CPU transfer data bus error input -- |
p_bus.err <= wishbone_err; |
p_bus.err <= bus_keeper_err or wishbone_err; |
|
-- exclusive access status -- |
-- since all internal modules/memories are only accessible to this CPU internal atomic access cannot fail |
cpu_d_exclr <= wishbone_exclr; -- only external atomic memory accesses can fail |
|
-- Processor-Internal Bus Keeper (BUSKEEPER) ---------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_bus_keeper_inst: neorv32_bus_keeper |
generic map ( |
-- Internal instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- 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_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE -- size of processor-internal data memory in bytes |
) |
port map ( |
-- host access -- |
clk_i => clk_i, -- global clock line |
rstn_i => sys_rstn, -- global reset line, low-active |
addr_i => p_bus.addr, -- address |
rden_i => p_bus.re, -- read enable |
wren_i => p_bus.we, -- write enable |
ack_i => p_bus.ack, -- transfer acknowledge from bus system |
err_i => p_bus.err, -- transfer error from bus system |
err_o => bus_keeper_err -- bus error |
); |
|
|
-- Processor-Internal Instruction Memory (IMEM) ------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_int_imem_inst_true: |
724,7 → 726,9
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
-- Internal data memory -- |
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE -- size of processor-internal data memory in bytes |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes |
-- Bus Timeout -- |
BUS_TIMEOUT => MEM_EXT_TIMEOUT -- cycles after an UNACKNOWLEDGED bus access triggers a bus fault exception |
) |
port map ( |
-- global control -- |
738,9 → 742,7
ben_i => p_bus.ben, -- byte write enable |
data_i => p_bus.wdata, -- data in |
data_o => wishbone_rdata, -- data out |
cancel_i => p_bus.cancel, -- cancel current transaction |
excl_i => p_bus.excl, -- exclusive access request |
excl_o => wishbone_exclr, -- state of exclusiv access (set if success) |
lock_i => p_bus.lock, -- exclusive access request |
ack_o => wishbone_ack, -- transfer acknowledge |
err_o => wishbone_err, -- transfer error |
priv_i => p_bus.priv, -- current CPU privilege level |
753,7 → 755,7
wb_sel_o => wb_sel_o, -- byte enable |
wb_stb_o => wb_stb_o, -- strobe |
wb_cyc_o => wb_cyc_o, -- valid cycle |
wb_tag_i => wb_tag_i, -- response tag |
wb_lock_o => wb_lock_o, -- exclusive access request |
wb_ack_i => wb_ack_i, -- transfer acknowledge |
wb_err_i => wb_err_i -- transfer error |
); |
764,7 → 766,6
wishbone_rdata <= (others => '0'); |
wishbone_ack <= '0'; |
wishbone_err <= '0'; |
wishbone_exclr <= '0'; |
-- |
wb_adr_o <= (others => '0'); |
wb_dat_o <= (others => '0'); |
/neorv32_wishbone.vhd
2,7 → 2,7
-- # << NEORV32 - External Bus Interface (WISHBONE) >> # |
-- # ********************************************************************************************* # |
-- # The interface provides registers for all outgoing and for all incoming signals. If the host # |
-- # cancels an activetransfer, the Wishbone arbiter still waits some time for the bus system to # |
-- # cancels an active transfer, the Wishbone arbiter still waits some time for the bus system to # |
-- # ACK/ERR the transfer before the arbiter forces termination. # |
-- # # |
-- # Even when all processor-internal memories and IO devices are disabled, the EXTERNAL address # |
9,7 → 9,7
-- # space ENDS at address 0xffff0000 (begin of internal BOOTROM address space). # |
-- # # |
-- # All bus accesses from the CPU, which do not target the internal IO region / the internal # |
-- # bootlloader / the internal instruction or data memories (if implemented), are delegated via # |
-- # bootloader / the internal instruction or data memories (if implemented), are delegated via # |
-- # this Wishbone gateway to the external bus interface. Accessed peripherals can have a response # |
-- # latency of up to BUS_TIMEOUT - 2 cycles. # |
-- # # |
68,41 → 68,39
); |
port ( |
-- global control -- |
clk_i : in std_ulogic; -- global clock line |
rstn_i : in std_ulogic; -- global reset line, low-active |
clk_i : in std_ulogic; -- global clock line |
rstn_i : in std_ulogic; -- global reset line, low-active |
-- host access -- |
src_i : in std_ulogic; -- access type (0: data, 1:instruction) |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
cancel_i : in std_ulogic; -- cancel current bus transaction |
excl_i : in std_ulogic; -- exclusive access request |
excl_o : out std_ulogic; -- state of exclusiv access (set if failed) |
ack_o : out std_ulogic; -- transfer acknowledge |
err_o : out std_ulogic; -- transfer error |
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level |
src_i : in std_ulogic; -- access type (0: data, 1:instruction) |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
ben_i : in std_ulogic_vector(03 downto 0); -- byte write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
lock_i : in std_ulogic; -- exclusive access request |
ack_o : out std_ulogic; -- transfer acknowledge |
err_o : out std_ulogic; -- transfer error |
priv_i : in std_ulogic_vector(01 downto 0); -- current CPU privilege level |
-- wishbone interface -- |
wb_tag_o : out std_ulogic_vector(03 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_tag_i : in std_ulogic; -- response tag |
wb_ack_i : in std_ulogic; -- transfer acknowledge |
wb_err_i : in std_ulogic -- transfer error |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_lock_o : out std_ulogic; -- exclusive access request |
wb_ack_i : in std_ulogic; -- transfer acknowledge |
wb_err_i : in std_ulogic -- transfer error |
); |
end neorv32_wishbone; |
|
architecture neorv32_wishbone_rtl of neorv32_wishbone is |
|
-- constants -- |
constant xbus_timeout_c : natural := BUS_TIMEOUT/4; |
-- timeout enable -- |
constant timeout_en_c : boolean := boolean(BUS_TIMEOUT /= 0); -- timeout enabled if BUS_TIMEOUT > 0 |
|
-- access control -- |
signal int_imem_acc : std_ulogic; |
111,7 → 109,7
signal xbus_access : std_ulogic; |
|
-- bus arbiter |
type ctrl_state_t is (IDLE, BUSY, CANCELED, RESYNC); |
type ctrl_state_t is (IDLE, BUSY, RESYNC); |
type ctrl_t is record |
state : ctrl_state_t; |
we : std_ulogic; |
123,10 → 121,9
sel : std_ulogic_vector(3 downto 0); |
ack : std_ulogic; |
err : std_ulogic; |
timeout : std_ulogic_vector(index_size_f(xbus_timeout_c)-1 downto 0); |
timeout : std_ulogic_vector(index_size_f(BUS_TIMEOUT)-1 downto 0); |
src : std_ulogic; |
excl : std_ulogic; |
exclr : std_ulogic; -- response |
lock : std_ulogic; |
priv : std_ulogic_vector(1 downto 0); |
end record; |
signal ctrl : ctrl_t; |
137,9 → 134,10
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- max bus timeout latency lower than recommended -- |
assert not (BUS_TIMEOUT <= 32) report "NEORV32 PROCESSOR CONFIG WARNING: Bus timeout should be >32 when using external bus interface." severity warning; |
-- external memory iterface protocol + max timeout latency notifier (warning) -- |
-- bus timeout -- |
assert not (BUS_TIMEOUT /= 0) report "NEORV32 PROCESSOR CONFIG WARNING: Using auto-timeout for external bus interface (" & integer'image(BUS_TIMEOUT) & " cycles)." severity warning; |
assert not (BUS_TIMEOUT /= 0) report "NEORV32 PROCESSOR CONFIG WARNING: Using no auto-timeout for external bus interface (might cause permanent CPU stall)." severity warning; |
-- external memory interface protocol + max timeout latency notifier (warning) -- |
assert not (wb_pipe_mode_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing external memory interface using STANDARD Wishbone protocol." severity note; |
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG NOTE! Implementing external memory interface using PIEPLINED Wishbone protocol." severity note; |
-- endianness -- |
163,27 → 161,25
begin |
if (rstn_i = '0') then |
ctrl.state <= IDLE; |
ctrl.we <= '0'; |
ctrl.we <= def_rst_val_c; |
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'; |
ctrl.src <= '0'; |
ctrl.excl <= '0'; |
ctrl.exclr <= '0'; |
ctrl.priv <= "00"; |
ctrl.adr <= (others => def_rst_val_c); |
ctrl.wdat <= (others => def_rst_val_c); |
ctrl.rdat <= (others => def_rst_val_c); |
ctrl.sel <= (others => def_rst_val_c); |
ctrl.timeout <= (others => def_rst_val_c); |
ctrl.ack <= def_rst_val_c; |
ctrl.err <= def_rst_val_c; |
ctrl.src <= def_rst_val_c; |
ctrl.lock <= def_rst_val_c; |
ctrl.priv <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
-- defaults -- |
ctrl.rdat <= (others => '0'); |
ctrl.ack <= '0'; |
ctrl.err <= '0'; |
ctrl.exclr <= '0'; |
ctrl.timeout <= std_ulogic_vector(to_unsigned(xbus_timeout_c, index_size_f(xbus_timeout_c))); |
ctrl.timeout <= std_ulogic_vector(to_unsigned(BUS_TIMEOUT, index_size_f(BUS_TIMEOUT))); |
|
-- state machine -- |
case ctrl.state is |
203,36 → 199,29
ctrl.sel <= bit_rev_f(ben_i); |
end if; |
ctrl.src <= src_i; |
ctrl.excl <= excl_i; |
ctrl.lock <= lock_i; |
ctrl.priv <= priv_i; |
-- valid new or buffered read/write request -- |
if ((xbus_access and (wren_i or ctrl.wr_req or rden_i or ctrl.rd_req) and (not cancel_i)) = '1') then |
if ((xbus_access and (wren_i or ctrl.wr_req or rden_i or ctrl.rd_req)) = '1') then |
ctrl.state <= BUSY; |
end if; |
|
when BUSY => -- transfer in progress |
-- ------------------------------------------------------------ |
ctrl.rdat <= wb_dat_i; |
ctrl.exclr <= wb_tag_i; -- set if exclusive access success |
if (cancel_i = '1') then -- transfer canceled by host |
ctrl.state <= CANCELED; |
elsif (wb_err_i = '1') then -- abnormal bus termination |
ctrl.rdat <= wb_dat_i; |
if (wb_err_i = '1') then -- abnormal bus termination |
ctrl.err <= '1'; |
ctrl.state <= CANCELED; |
ctrl.state <= IDLE; |
elsif (wb_ack_i = '1') then -- normal bus termination |
ctrl.ack <= '1'; |
ctrl.state <= IDLE; |
elsif (timeout_en_c = true) and (or_all_f(ctrl.timeout) = '0') then -- valid timeout |
ctrl.err <= '1'; |
ctrl.state <= IDLE; |
end if; |
|
when CANCELED => -- wait for cycle to be completed either by peripheral or by timeout (ignore result of transfer) |
-- ------------------------------------------------------------ |
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 <= RESYNC; |
-- timeout counter -- |
if (timeout_en_c = true) then |
ctrl.timeout <= std_ulogic_vector(unsigned(ctrl.timeout) - 1); -- timeout counter |
end if; |
|
when RESYNC => -- make sure transfer is done! |
255,14 → 244,14
data_o <= ctrl.rdat when (xbus_big_endian_c = true) else bswap32_f(ctrl.rdat); -- endianness conversion |
ack_o <= ctrl.ack; |
err_o <= ctrl.err; |
excl_o <= ctrl.exclr; |
|
-- wishbone interface -- |
wb_tag_o(0) <= '1' when (ctrl.priv = priv_mode_m_c) else '0'; -- privileged access when in machine mode |
wb_tag_o(1) <= '0'; -- 0 = secure, 1 = non-secure |
wb_tag_o(2) <= ctrl.src; -- 0 = data access, 1 = instruction access |
wb_tag_o(3) <= ctrl.excl; -- 1 = exclusive access request |
|
wb_lock_o <= ctrl.lock; -- 1 = exclusive access request |
|
wb_adr_o <= ctrl.adr; |
wb_dat_o <= ctrl.wdat; |
wb_we_o <= ctrl.we; |