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 64 to Rev 65
- ↔ Reverse comparison
Rev 64 → Rev 65
/neorv32_application_image.vhd
113,17 → 113,17
00000099 => x"00000593", |
00000100 => x"b0050513", |
00000101 => x"00112623", |
00000102 => x"118000ef", |
00000102 => x"088000ef", |
00000103 => x"718000ef", |
00000104 => x"00050c63", |
00000105 => x"6c8000ef", |
00000106 => x"00001537", |
00000107 => x"a6050513", |
00000108 => x"170000ef", |
00000108 => x"118000ef", |
00000109 => x"020000ef", |
00000110 => x"00001537", |
00000111 => x"a3c50513", |
00000112 => x"160000ef", |
00000112 => x"108000ef", |
00000113 => x"00c12083", |
00000114 => x"00100513", |
00000115 => x"01010113", |
140,7 → 140,7
00000126 => x"0ff57513", |
00000127 => x"6c8000ef", |
00000128 => x"0c800513", |
00000129 => x"14c000ef", |
00000129 => x"148000ef", |
00000130 => x"00040513", |
00000131 => x"fe5ff06f", |
00000132 => x"fe802503", |
183,12 → 183,12
00000169 => x"f9dff06f", |
00000170 => x"0017d793", |
00000171 => x"ff1ff06f", |
00000172 => x"f71ff06f", |
00000172 => x"00040737", |
00000173 => x"fa002783", |
00000174 => x"fe07cee3", |
00000175 => x"faa02223", |
00000176 => x"00008067", |
00000177 => x"ff1ff06f", |
00000174 => x"00e7f7b3", |
00000175 => x"fe079ce3", |
00000176 => x"faa02223", |
00000177 => x"00008067", |
00000178 => x"ff010113", |
00000179 => x"00812423", |
00000180 => x"01212023", |
207,69 → 207,69
00000193 => x"00008067", |
00000194 => x"01249663", |
00000195 => x"00d00513", |
00000196 => x"fa5ff0ef", |
00000196 => x"fa1ff0ef", |
00000197 => x"00048513", |
00000198 => x"f9dff0ef", |
00000198 => x"f99ff0ef", |
00000199 => x"fc9ff06f", |
00000200 => x"fa9ff06f", |
00000201 => x"ff010113", |
00000202 => x"c81026f3", |
00000203 => x"c0102773", |
00000204 => x"c81027f3", |
00000205 => x"fed79ae3", |
00000206 => x"00e12023", |
00000207 => x"00f12223", |
00000208 => x"00012503", |
00000209 => x"00412583", |
00000210 => x"01010113", |
00000211 => x"00008067", |
00000212 => x"fd010113", |
00000213 => x"00a12623", |
00000214 => x"fe002503", |
00000215 => x"3e800593", |
00000216 => x"02112623", |
00000217 => x"02812423", |
00000218 => x"02912223", |
00000219 => x"03212023", |
00000220 => x"01312e23", |
00000221 => x"61c000ef", |
00000222 => x"00c12603", |
00000223 => x"00000693", |
00000224 => x"00000593", |
00000225 => x"574000ef", |
00000226 => x"00050413", |
00000227 => x"00058993", |
00000228 => x"f95ff0ef", |
00000229 => x"00058913", |
00000230 => x"00050493", |
00000231 => x"f89ff0ef", |
00000232 => x"00b96663", |
00000233 => x"05259263", |
00000234 => x"04a4f063", |
00000235 => x"008484b3", |
00000236 => x"0084b433", |
00000237 => x"01390933", |
00000238 => x"01240433", |
00000239 => x"f69ff0ef", |
00000240 => x"fe85eee3", |
00000241 => x"00b41463", |
00000242 => x"fe956ae3", |
00000243 => x"02c12083", |
00000244 => x"02812403", |
00000245 => x"02412483", |
00000246 => x"02012903", |
00000247 => x"01c12983", |
00000248 => x"03010113", |
00000249 => x"00008067", |
00000250 => x"01c99913", |
00000251 => x"00445413", |
00000252 => x"00896433", |
00000253 => x"00040a63", |
00000254 => x"00040863", |
00000255 => x"fff40413", |
00000256 => x"00000013", |
00000257 => x"ff1ff06f", |
00000258 => x"fc5ff06f", |
00000200 => x"ff010113", |
00000201 => x"c81026f3", |
00000202 => x"c0102773", |
00000203 => x"c81027f3", |
00000204 => x"fed79ae3", |
00000205 => x"00e12023", |
00000206 => x"00f12223", |
00000207 => x"00012503", |
00000208 => x"00412583", |
00000209 => x"01010113", |
00000210 => x"00008067", |
00000211 => x"fd010113", |
00000212 => x"00a12623", |
00000213 => x"fe002503", |
00000214 => x"3e800593", |
00000215 => x"02112623", |
00000216 => x"02812423", |
00000217 => x"02912223", |
00000218 => x"03212023", |
00000219 => x"01312e23", |
00000220 => x"620000ef", |
00000221 => x"00c12603", |
00000222 => x"00000693", |
00000223 => x"00000593", |
00000224 => x"578000ef", |
00000225 => x"00050413", |
00000226 => x"00058993", |
00000227 => x"f95ff0ef", |
00000228 => x"00058913", |
00000229 => x"00050493", |
00000230 => x"f89ff0ef", |
00000231 => x"00b96663", |
00000232 => x"05259263", |
00000233 => x"04a4f063", |
00000234 => x"008484b3", |
00000235 => x"0084b433", |
00000236 => x"01390933", |
00000237 => x"01240433", |
00000238 => x"f69ff0ef", |
00000239 => x"fe85eee3", |
00000240 => x"00b41463", |
00000241 => x"fe956ae3", |
00000242 => x"02c12083", |
00000243 => x"02812403", |
00000244 => x"02412483", |
00000245 => x"02012903", |
00000246 => x"01c12983", |
00000247 => x"03010113", |
00000248 => x"00008067", |
00000249 => x"01c99913", |
00000250 => x"00445413", |
00000251 => x"00896433", |
00000252 => x"00040a63", |
00000253 => x"00040863", |
00000254 => x"fff40413", |
00000255 => x"00000013", |
00000256 => x"ff1ff06f", |
00000257 => x"fc5ff06f", |
00000258 => x"00000000", |
00000259 => x"00000000", |
00000260 => x"fc010113", |
00000261 => x"02112e23", |
421,7 → 421,7
00000407 => x"00f487b3", |
00000408 => x"0007c503", |
00000409 => x"ffc40413", |
00000410 => x"c4dff0ef", |
00000410 => x"c49ff0ef", |
00000411 => x"ff3414e3", |
00000412 => x"01c12083", |
00000413 => x"01812403", |
438,7 → 438,7
00000424 => x"18050463", |
00000425 => x"00001537", |
00000426 => x"b2450513", |
00000427 => x"c75ff0ef", |
00000427 => x"c1dff0ef", |
00000428 => x"34202473", |
00000429 => x"00900713", |
00000430 => x"00f47793", |
463,7 → 463,7
00000449 => x"10f40663", |
00000450 => x"00001537", |
00000451 => x"c8450513", |
00000452 => x"c11ff0ef", |
00000452 => x"bb9ff0ef", |
00000453 => x"00040513", |
00000454 => x"f05ff0ef", |
00000455 => x"0380006f", |
473,21 → 473,21
00000459 => x"fcf76ee3", |
00000460 => x"00001537", |
00000461 => x"c7450513", |
00000462 => x"be9ff0ef", |
00000462 => x"b91ff0ef", |
00000463 => x"00048513", |
00000464 => x"b85ff0ef", |
00000464 => x"b71ff0ef", |
00000465 => x"0100006f", |
00000466 => x"00001537", |
00000467 => x"b2c50513", |
00000468 => x"bd1ff0ef", |
00000468 => x"b79ff0ef", |
00000469 => x"00001537", |
00000470 => x"c9c50513", |
00000471 => x"bc5ff0ef", |
00000471 => x"b6dff0ef", |
00000472 => x"34002573", |
00000473 => x"eb9ff0ef", |
00000474 => x"00001537", |
00000475 => x"ca450513", |
00000476 => x"bb1ff0ef", |
00000476 => x"b59ff0ef", |
00000477 => x"34302573", |
00000478 => x"ea5ff0ef", |
00000479 => x"00812403", |
496,7 → 496,7
00000482 => x"00001537", |
00000483 => x"cb050513", |
00000484 => x"01010113", |
00000485 => x"b8dff06f", |
00000485 => x"b35ff06f", |
00000486 => x"00001537", |
00000487 => x"b4c50513", |
00000488 => x"fb1ff06f", |
/neorv32_bootloader_image.vhd
1,6 → 1,6
-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32 |
-- Auto-generated memory init file (for BOOTLOADER) from source file <bootloader/main.bin> |
-- Size: 4048 bytes |
-- Size: 4088 bytes |
|
library ieee; |
use ieee.std_logic_1164.all; |
51,7 → 51,7
00000037 => x"00158593", |
00000038 => x"ff5ff06f", |
00000039 => x"00001597", |
00000040 => x"f3458593", |
00000040 => x"f5c58593", |
00000041 => x"80010617", |
00000042 => x"f5c60613", |
00000043 => x"80010697", |
105,924 → 105,934
00000091 => x"0007a023", |
00000092 => x"8001a223", |
00000093 => x"ffff07b7", |
00000094 => x"4b878793", |
00000094 => x"4bc78793", |
00000095 => x"30579073", |
00000096 => x"00000613", |
00000097 => x"00000593", |
00000098 => x"00200513", |
00000099 => x"381000ef", |
00000100 => x"409000ef", |
00000101 => x"00048493", |
00000102 => x"00050863", |
00000103 => x"00100513", |
00000104 => x"00000593", |
00000105 => x"435000ef", |
00000106 => x"00005537", |
00000107 => x"00000613", |
00000108 => x"00000593", |
00000109 => x"b0050513", |
00000110 => x"225000ef", |
00000111 => x"1bd000ef", |
00000112 => x"02050a63", |
00000113 => x"1c5000ef", |
00000114 => x"fe002783", |
00000115 => x"0027d793", |
00000116 => x"00a78533", |
00000117 => x"00f537b3", |
00000118 => x"00b785b3", |
00000119 => x"1d9000ef", |
00000120 => x"08000793", |
00000121 => x"30479073", |
00000122 => x"30046073", |
00000123 => x"00000013", |
00000096 => x"00000693", |
00000097 => x"00000613", |
00000098 => x"00000593", |
00000099 => x"00200513", |
00000100 => x"399000ef", |
00000101 => x"42d000ef", |
00000102 => x"00048493", |
00000103 => x"00050863", |
00000104 => x"00100513", |
00000105 => x"00000593", |
00000106 => x"459000ef", |
00000107 => x"00005537", |
00000108 => x"00000613", |
00000109 => x"00000593", |
00000110 => x"b0050513", |
00000111 => x"1f9000ef", |
00000112 => x"1bd000ef", |
00000113 => x"02050a63", |
00000114 => x"325000ef", |
00000115 => x"fe002783", |
00000116 => x"0027d793", |
00000117 => x"00a78533", |
00000118 => x"00f537b3", |
00000119 => x"00b785b3", |
00000120 => x"1ad000ef", |
00000121 => x"08000793", |
00000122 => x"30479073", |
00000123 => x"30046073", |
00000124 => x"00000013", |
00000125 => x"ffff1537", |
00000126 => x"f0050513", |
00000127 => x"2a9000ef", |
00000128 => x"f1302573", |
00000129 => x"244000ef", |
00000130 => x"ffff1537", |
00000131 => x"f3850513", |
00000132 => x"295000ef", |
00000133 => x"fe002503", |
00000134 => x"230000ef", |
00000135 => x"ffff1537", |
00000136 => x"f4050513", |
00000137 => x"281000ef", |
00000138 => x"30102573", |
00000139 => x"21c000ef", |
00000140 => x"ffff1537", |
00000141 => x"f4850513", |
00000142 => x"26d000ef", |
00000143 => x"fe402503", |
00000144 => x"ffff1437", |
00000145 => x"204000ef", |
00000146 => x"ffff1537", |
00000147 => x"f5050513", |
00000148 => x"255000ef", |
00000149 => x"fe802503", |
00000150 => x"1f0000ef", |
00000151 => x"ffff1537", |
00000152 => x"f5850513", |
00000153 => x"241000ef", |
00000154 => x"ff802503", |
00000155 => x"1dc000ef", |
00000156 => x"f6040513", |
00000157 => x"231000ef", |
00000158 => x"ff002503", |
00000159 => x"1cc000ef", |
00000160 => x"ffff1537", |
00000161 => x"f6c50513", |
00000162 => x"21d000ef", |
00000163 => x"ffc02503", |
00000164 => x"1b8000ef", |
00000165 => x"f6040513", |
00000166 => x"20d000ef", |
00000167 => x"ff402503", |
00000168 => x"1a8000ef", |
00000169 => x"0d5000ef", |
00000170 => x"06050663", |
00000171 => x"ffff1537", |
00000172 => x"f7450513", |
00000173 => x"1f1000ef", |
00000174 => x"0d1000ef", |
00000175 => x"fe002403", |
00000176 => x"00341413", |
00000177 => x"00a40933", |
00000178 => x"00893433", |
00000179 => x"00b40433", |
00000180 => x"0fd000ef", |
00000181 => x"02051663", |
00000182 => x"0b1000ef", |
00000183 => x"fe85eae3", |
00000184 => x"00b41463", |
00000185 => x"ff2566e3", |
00000186 => x"00100513", |
00000187 => x"4d4000ef", |
00000188 => x"ffff1537", |
00000189 => x"f9c50513", |
00000190 => x"1ad000ef", |
00000191 => x"0cc000ef", |
00000192 => x"199000ef", |
00000193 => x"fc050ae3", |
00000194 => x"ffff1537", |
00000195 => x"fa050513", |
00000196 => x"195000ef", |
00000197 => x"0a8000ef", |
00000198 => x"ffff19b7", |
00000199 => x"ffff1a37", |
00000200 => x"07200a93", |
00000201 => x"06800b13", |
00000202 => x"07500b93", |
00000203 => x"07300c13", |
00000204 => x"ffff1937", |
00000205 => x"ffff1cb7", |
00000206 => x"fac98513", |
00000207 => x"169000ef", |
00000208 => x"149000ef", |
00000209 => x"00050413", |
00000210 => x"125000ef", |
00000211 => x"f9ca0513", |
00000212 => x"155000ef", |
00000213 => x"01541863", |
00000214 => x"ffff02b7", |
00000215 => x"00028067", |
00000216 => x"fd9ff06f", |
00000217 => x"01641663", |
00000218 => x"054000ef", |
00000219 => x"fcdff06f", |
00000220 => x"00000513", |
00000221 => x"01740e63", |
00000222 => x"01841663", |
00000223 => x"680000ef", |
00000224 => x"fb9ff06f", |
00000225 => x"06c00793", |
00000226 => x"00f41863", |
00000227 => x"00100513", |
00000228 => x"430000ef", |
00000229 => x"fa5ff06f", |
00000230 => x"06500793", |
00000231 => x"00f41c63", |
00000232 => x"0004a783", |
00000233 => x"f4079ce3", |
00000234 => x"ea8c8513", |
00000235 => x"0f9000ef", |
00000236 => x"f89ff06f", |
00000237 => x"fb490513", |
00000238 => x"ff5ff06f", |
00000239 => x"ffff1537", |
00000240 => x"de850513", |
00000241 => x"0e10006f", |
00000242 => x"ff010113", |
00000243 => x"00112623", |
00000244 => x"30047073", |
00000245 => x"00000013", |
00000125 => x"00000013", |
00000126 => x"ffff1537", |
00000127 => x"f2850513", |
00000128 => x"295000ef", |
00000129 => x"f1302573", |
00000130 => x"244000ef", |
00000131 => x"ffff1537", |
00000132 => x"f6050513", |
00000133 => x"281000ef", |
00000134 => x"fe002503", |
00000135 => x"230000ef", |
00000136 => x"ffff1537", |
00000137 => x"f6850513", |
00000138 => x"26d000ef", |
00000139 => x"30102573", |
00000140 => x"21c000ef", |
00000141 => x"ffff1537", |
00000142 => x"f7050513", |
00000143 => x"259000ef", |
00000144 => x"fe402503", |
00000145 => x"ffff1437", |
00000146 => x"204000ef", |
00000147 => x"ffff1537", |
00000148 => x"f7850513", |
00000149 => x"241000ef", |
00000150 => x"fe802503", |
00000151 => x"1f0000ef", |
00000152 => x"ffff1537", |
00000153 => x"f8050513", |
00000154 => x"22d000ef", |
00000155 => x"ff802503", |
00000156 => x"1dc000ef", |
00000157 => x"f8840513", |
00000158 => x"21d000ef", |
00000159 => x"ff002503", |
00000160 => x"1cc000ef", |
00000161 => x"ffff1537", |
00000162 => x"f9450513", |
00000163 => x"209000ef", |
00000164 => x"ffc02503", |
00000165 => x"1b8000ef", |
00000166 => x"f8840513", |
00000167 => x"1f9000ef", |
00000168 => x"ff402503", |
00000169 => x"1a8000ef", |
00000170 => x"0d5000ef", |
00000171 => x"06050663", |
00000172 => x"ffff1537", |
00000173 => x"f9c50513", |
00000174 => x"1dd000ef", |
00000175 => x"231000ef", |
00000176 => x"fe002403", |
00000177 => x"00341413", |
00000178 => x"00a40933", |
00000179 => x"00893433", |
00000180 => x"00b40433", |
00000181 => x"0d1000ef", |
00000182 => x"02051663", |
00000183 => x"211000ef", |
00000184 => x"fe85eae3", |
00000185 => x"00b41463", |
00000186 => x"ff2566e3", |
00000187 => x"00100513", |
00000188 => x"4d4000ef", |
00000189 => x"ffff1537", |
00000190 => x"fc450513", |
00000191 => x"199000ef", |
00000192 => x"0cc000ef", |
00000193 => x"185000ef", |
00000194 => x"fc050ae3", |
00000195 => x"ffff1537", |
00000196 => x"fc850513", |
00000197 => x"181000ef", |
00000198 => x"0a8000ef", |
00000199 => x"ffff19b7", |
00000200 => x"ffff1a37", |
00000201 => x"07200a93", |
00000202 => x"06800b13", |
00000203 => x"07500b93", |
00000204 => x"07300c13", |
00000205 => x"ffff1937", |
00000206 => x"ffff1cb7", |
00000207 => x"fd498513", |
00000208 => x"155000ef", |
00000209 => x"135000ef", |
00000210 => x"00050413", |
00000211 => x"0f9000ef", |
00000212 => x"fc4a0513", |
00000213 => x"141000ef", |
00000214 => x"01541863", |
00000215 => x"ffff02b7", |
00000216 => x"00028067", |
00000217 => x"fd9ff06f", |
00000218 => x"01641663", |
00000219 => x"054000ef", |
00000220 => x"fcdff06f", |
00000221 => x"00000513", |
00000222 => x"01740e63", |
00000223 => x"01841663", |
00000224 => x"680000ef", |
00000225 => x"fb9ff06f", |
00000226 => x"06c00793", |
00000227 => x"00f41863", |
00000228 => x"00100513", |
00000229 => x"430000ef", |
00000230 => x"fa5ff06f", |
00000231 => x"06500793", |
00000232 => x"00f41c63", |
00000233 => x"0004a783", |
00000234 => x"f4079ce3", |
00000235 => x"ed0c8513", |
00000236 => x"0e5000ef", |
00000237 => x"f89ff06f", |
00000238 => x"fdc90513", |
00000239 => x"ff5ff06f", |
00000240 => x"ffff1537", |
00000241 => x"e1050513", |
00000242 => x"0cd0006f", |
00000243 => x"ff010113", |
00000244 => x"00112623", |
00000245 => x"30047073", |
00000246 => x"00000013", |
00000247 => x"ffff1537", |
00000248 => x"e4c50513", |
00000249 => x"0c1000ef", |
00000250 => x"095000ef", |
00000251 => x"fe051ee3", |
00000252 => x"ff002783", |
00000253 => x"00078067", |
00000254 => x"0000006f", |
00000255 => x"ff010113", |
00000256 => x"00812423", |
00000257 => x"00050413", |
00000258 => x"ffff1537", |
00000259 => x"e5c50513", |
00000260 => x"00112623", |
00000261 => x"091000ef", |
00000262 => x"03040513", |
00000263 => x"0ff57513", |
00000264 => x"04d000ef", |
00000265 => x"30047073", |
00000266 => x"00000013", |
00000247 => x"00000013", |
00000248 => x"ffff1537", |
00000249 => x"e7450513", |
00000250 => x"0ad000ef", |
00000251 => x"071000ef", |
00000252 => x"fe051ee3", |
00000253 => x"ff002783", |
00000254 => x"00078067", |
00000255 => x"0000006f", |
00000256 => x"ff010113", |
00000257 => x"00812423", |
00000258 => x"00050413", |
00000259 => x"ffff1537", |
00000260 => x"e8450513", |
00000261 => x"00112623", |
00000262 => x"07d000ef", |
00000263 => x"03040513", |
00000264 => x"0ff57513", |
00000265 => x"021000ef", |
00000266 => x"30047073", |
00000267 => x"00000013", |
00000268 => x"169000ef", |
00000269 => x"00050863", |
00000270 => x"00100513", |
00000271 => x"00000593", |
00000272 => x"199000ef", |
00000273 => x"0000006f", |
00000274 => x"fe010113", |
00000275 => x"01212823", |
00000276 => x"00050913", |
00000277 => x"ffff1537", |
00000278 => x"00912a23", |
00000279 => x"e6850513", |
00000280 => x"ffff14b7", |
00000281 => x"00812c23", |
00000282 => x"01312623", |
00000283 => x"00112e23", |
00000284 => x"01c00413", |
00000285 => x"031000ef", |
00000286 => x"fc048493", |
00000287 => x"ffc00993", |
00000288 => x"008957b3", |
00000289 => x"00f7f793", |
00000290 => x"00f487b3", |
00000291 => x"0007c503", |
00000292 => x"ffc40413", |
00000293 => x"7d8000ef", |
00000294 => x"ff3414e3", |
00000295 => x"01c12083", |
00000296 => x"01812403", |
00000297 => x"01412483", |
00000298 => x"01012903", |
00000299 => x"00c12983", |
00000300 => x"02010113", |
00000301 => x"00008067", |
00000302 => x"fb010113", |
00000303 => x"04112623", |
00000304 => x"04512423", |
00000305 => x"04612223", |
00000306 => x"04712023", |
00000307 => x"02812e23", |
00000308 => x"02912c23", |
00000309 => x"02a12a23", |
00000310 => x"02b12823", |
00000311 => x"02c12623", |
00000312 => x"02d12423", |
00000313 => x"02e12223", |
00000314 => x"02f12023", |
00000315 => x"01012e23", |
00000316 => x"01112c23", |
00000317 => x"01c12a23", |
00000318 => x"01d12823", |
00000319 => x"01e12623", |
00000320 => x"01f12423", |
00000321 => x"342024f3", |
00000322 => x"800007b7", |
00000323 => x"00778793", |
00000324 => x"08f49463", |
00000325 => x"085000ef", |
00000326 => x"00050663", |
00000327 => x"00000513", |
00000328 => x"089000ef", |
00000329 => x"654000ef", |
00000330 => x"02050063", |
00000331 => x"65c000ef", |
00000332 => x"fe002783", |
00000333 => x"0027d793", |
00000334 => x"00a78533", |
00000335 => x"00f537b3", |
00000336 => x"00b785b3", |
00000337 => x"670000ef", |
00000338 => x"03c12403", |
00000339 => x"04c12083", |
00000340 => x"04812283", |
00000341 => x"04412303", |
00000342 => x"04012383", |
00000343 => x"03812483", |
00000344 => x"03412503", |
00000345 => x"03012583", |
00000346 => x"02c12603", |
00000347 => x"02812683", |
00000348 => x"02412703", |
00000349 => x"02012783", |
00000350 => x"01c12803", |
00000351 => x"01812883", |
00000352 => x"01412e03", |
00000353 => x"01012e83", |
00000354 => x"00c12f03", |
00000355 => x"00812f83", |
00000356 => x"05010113", |
00000357 => x"30200073", |
00000358 => x"00700793", |
00000359 => x"00f49a63", |
00000360 => x"8041a783", |
00000361 => x"00078663", |
00000362 => x"00100513", |
00000363 => x"e51ff0ef", |
00000364 => x"34102473", |
00000365 => x"618000ef", |
00000366 => x"04050263", |
00000367 => x"ffff1537", |
00000368 => x"e6c50513", |
00000369 => x"6e0000ef", |
00000370 => x"00048513", |
00000371 => x"e7dff0ef", |
00000372 => x"02000513", |
00000373 => x"698000ef", |
00000374 => x"00040513", |
00000375 => x"e6dff0ef", |
00000376 => x"02000513", |
00000377 => x"688000ef", |
00000378 => x"34302573", |
00000379 => x"e5dff0ef", |
00000380 => x"ffff1537", |
00000381 => x"e7450513", |
00000382 => x"6ac000ef", |
00000383 => x"00440413", |
00000384 => x"34141073", |
00000385 => x"f45ff06f", |
00000386 => x"ff010113", |
00000387 => x"00000513", |
00000388 => x"00112623", |
00000389 => x"00812423", |
00000390 => x"728000ef", |
00000391 => x"09e00513", |
00000392 => x"764000ef", |
00000393 => x"00000513", |
00000394 => x"75c000ef", |
00000395 => x"00050413", |
00000396 => x"00000513", |
00000397 => x"72c000ef", |
00000398 => x"00c12083", |
00000399 => x"0ff47513", |
00000400 => x"00812403", |
00000401 => x"01010113", |
00000402 => x"00008067", |
00000403 => x"ff010113", |
00000404 => x"00112623", |
00000405 => x"00812423", |
00000406 => x"00000513", |
00000407 => x"6e4000ef", |
00000408 => x"00500513", |
00000409 => x"720000ef", |
00000410 => x"00000513", |
00000411 => x"718000ef", |
00000412 => x"00050413", |
00000413 => x"00147413", |
00000414 => x"00000513", |
00000415 => x"6e4000ef", |
00000416 => x"fc041ce3", |
00000417 => x"00c12083", |
00000418 => x"00812403", |
00000419 => x"01010113", |
00000420 => x"00008067", |
00000421 => x"ff010113", |
00000422 => x"00000513", |
00000423 => x"00112623", |
00000424 => x"6a0000ef", |
00000425 => x"00600513", |
00000426 => x"6dc000ef", |
00000427 => x"00c12083", |
00000428 => x"00000513", |
00000429 => x"01010113", |
00000430 => x"6a80006f", |
00000431 => x"ff010113", |
00000432 => x"00812423", |
00000433 => x"00050413", |
00000434 => x"01055513", |
00000435 => x"0ff57513", |
00000436 => x"00112623", |
00000437 => x"6b0000ef", |
00000438 => x"00845513", |
00000439 => x"0ff57513", |
00000440 => x"6a4000ef", |
00000441 => x"0ff47513", |
00000442 => x"00812403", |
00000443 => x"00c12083", |
00000444 => x"01010113", |
00000445 => x"6900006f", |
00000446 => x"ff010113", |
00000447 => x"00812423", |
00000448 => x"00050413", |
00000449 => x"00000513", |
00000450 => x"00112623", |
00000451 => x"634000ef", |
00000452 => x"00300513", |
00000453 => x"670000ef", |
00000454 => x"00040513", |
00000455 => x"fa1ff0ef", |
00000456 => x"00000513", |
00000457 => x"660000ef", |
00000458 => x"00050413", |
00000459 => x"00000513", |
00000460 => x"630000ef", |
00000461 => x"00c12083", |
00000462 => x"0ff47513", |
00000463 => x"00812403", |
00000464 => x"01010113", |
00000465 => x"00008067", |
00000466 => x"fd010113", |
00000467 => x"02812423", |
00000468 => x"02912223", |
00000469 => x"03212023", |
00000470 => x"01312e23", |
00000471 => x"01412c23", |
00000472 => x"02112623", |
00000473 => x"00050913", |
00000474 => x"00058993", |
00000475 => x"00c10493", |
00000476 => x"00000413", |
00000477 => x"00400a13", |
00000478 => x"02091e63", |
00000479 => x"50c000ef", |
00000480 => x"00a48023", |
00000481 => x"00140413", |
00000482 => x"00148493", |
00000483 => x"ff4416e3", |
00000484 => x"02c12083", |
00000485 => x"02812403", |
00000486 => x"00c12503", |
00000487 => x"02412483", |
00000488 => x"02012903", |
00000489 => x"01c12983", |
00000490 => x"01812a03", |
00000491 => x"03010113", |
00000492 => x"00008067", |
00000493 => x"00898533", |
00000494 => x"f41ff0ef", |
00000495 => x"fc5ff06f", |
00000496 => x"fd010113", |
00000497 => x"01412c23", |
00000498 => x"02812423", |
00000499 => x"80418793", |
00000500 => x"02112623", |
00000501 => x"02912223", |
00000502 => x"03212023", |
00000503 => x"01312e23", |
00000504 => x"01512a23", |
00000505 => x"01612823", |
00000506 => x"01712623", |
00000507 => x"01812423", |
00000508 => x"00100713", |
00000509 => x"00e7a023", |
00000510 => x"00050413", |
00000511 => x"80418a13", |
00000512 => x"02051863", |
00000513 => x"ffff1537", |
00000514 => x"e7850513", |
00000515 => x"498000ef", |
00000516 => x"080005b7", |
00000517 => x"00040513", |
00000518 => x"f31ff0ef", |
00000519 => x"4788d7b7", |
00000520 => x"afe78793", |
00000521 => x"02f50a63", |
00000522 => x"00000513", |
00000523 => x"01c0006f", |
00000524 => x"ffff1537", |
00000525 => x"e9850513", |
00000526 => x"46c000ef", |
00000527 => x"4c0000ef", |
00000528 => x"00051663", |
00000529 => x"00300513", |
00000530 => x"bb5ff0ef", |
00000531 => x"dbdff0ef", |
00000532 => x"fc0510e3", |
00000533 => x"ff1ff06f", |
00000534 => x"080009b7", |
00000535 => x"00498593", |
00000536 => x"00040513", |
00000537 => x"ee5ff0ef", |
00000538 => x"00050a93", |
00000539 => x"00898593", |
00000540 => x"00040513", |
00000541 => x"ed5ff0ef", |
00000542 => x"ff002c03", |
00000543 => x"00050b13", |
00000544 => x"ffcafb93", |
00000545 => x"00000913", |
00000546 => x"00000493", |
00000547 => x"00c98993", |
00000548 => x"013905b3", |
00000549 => x"052b9c63", |
00000550 => x"016484b3", |
00000551 => x"00200513", |
00000552 => x"fa0494e3", |
00000553 => x"ffff1537", |
00000554 => x"ea450513", |
00000555 => x"3f8000ef", |
00000556 => x"02c12083", |
00000557 => x"02812403", |
00000558 => x"800007b7", |
00000559 => x"0157a023", |
00000560 => x"000a2023", |
00000561 => x"02412483", |
00000562 => x"02012903", |
00000563 => x"01c12983", |
00000564 => x"01812a03", |
00000565 => x"01412a83", |
00000566 => x"01012b03", |
00000567 => x"00c12b83", |
00000568 => x"00812c03", |
00000569 => x"03010113", |
00000570 => x"00008067", |
00000571 => x"00040513", |
00000572 => x"e59ff0ef", |
00000573 => x"012c07b3", |
00000574 => x"00a484b3", |
00000575 => x"00a7a023", |
00000576 => x"00490913", |
00000577 => x"f8dff06f", |
00000578 => x"ff010113", |
00000579 => x"00112623", |
00000580 => x"00812423", |
00000581 => x"00912223", |
00000582 => x"00058413", |
00000583 => x"00050493", |
00000584 => x"d75ff0ef", |
00000585 => x"00000513", |
00000586 => x"418000ef", |
00000587 => x"00200513", |
00000588 => x"454000ef", |
00000589 => x"00048513", |
00000590 => x"d85ff0ef", |
00000591 => x"00040513", |
00000592 => x"444000ef", |
00000593 => x"00000513", |
00000594 => x"418000ef", |
00000595 => x"00812403", |
00000596 => x"00c12083", |
00000597 => x"00412483", |
00000598 => x"01010113", |
00000599 => x"cf1ff06f", |
00000600 => x"fe010113", |
00000601 => x"00812c23", |
00000602 => x"00912a23", |
00000603 => x"01212823", |
00000604 => x"00112e23", |
00000605 => x"00050493", |
00000606 => x"00b12623", |
00000607 => x"00000413", |
00000608 => x"00400913", |
00000609 => x"00c10793", |
00000610 => x"008787b3", |
00000611 => x"0007c583", |
00000612 => x"00848533", |
00000613 => x"00140413", |
00000614 => x"f71ff0ef", |
00000615 => x"ff2414e3", |
00000616 => x"01c12083", |
00000617 => x"01812403", |
00000618 => x"01412483", |
00000619 => x"01012903", |
00000620 => x"02010113", |
00000621 => x"00008067", |
00000622 => x"ff010113", |
00000623 => x"00112623", |
00000624 => x"00812423", |
00000625 => x"00050413", |
00000626 => x"ccdff0ef", |
00000627 => x"00000513", |
00000628 => x"370000ef", |
00000629 => x"0d800513", |
00000630 => x"3ac000ef", |
00000631 => x"00040513", |
00000632 => x"cddff0ef", |
00000633 => x"00000513", |
00000634 => x"378000ef", |
00000635 => x"00812403", |
00000636 => x"00c12083", |
00000637 => x"01010113", |
00000638 => x"c55ff06f", |
00000639 => x"fe010113", |
00000640 => x"800007b7", |
00000641 => x"00812c23", |
00000642 => x"0007a403", |
00000643 => x"00112e23", |
00000644 => x"00912a23", |
00000645 => x"01212823", |
00000646 => x"01312623", |
00000647 => x"01412423", |
00000648 => x"01512223", |
00000649 => x"02041863", |
00000650 => x"ffff1537", |
00000651 => x"ea850513", |
00000652 => x"01812403", |
00000653 => x"01c12083", |
00000654 => x"01412483", |
00000655 => x"01012903", |
00000656 => x"00c12983", |
00000657 => x"00812a03", |
00000658 => x"00412a83", |
00000659 => x"02010113", |
00000660 => x"2540006f", |
00000661 => x"ffff1537", |
00000662 => x"ec450513", |
00000663 => x"248000ef", |
00000664 => x"00040513", |
00000665 => x"9e5ff0ef", |
00000666 => x"ffff1537", |
00000667 => x"ecc50513", |
00000668 => x"234000ef", |
00000669 => x"08000537", |
00000670 => x"9d1ff0ef", |
00000671 => x"ffff1537", |
00000672 => x"ee450513", |
00000673 => x"220000ef", |
00000674 => x"200000ef", |
00000675 => x"00050493", |
00000676 => x"1dc000ef", |
00000677 => x"07900793", |
00000678 => x"0af49e63", |
00000679 => x"b6dff0ef", |
00000680 => x"00051663", |
00000681 => x"00300513", |
00000682 => x"955ff0ef", |
00000683 => x"ffff1537", |
00000684 => x"ef050513", |
00000685 => x"01045493", |
00000686 => x"1ec000ef", |
00000687 => x"00148493", |
00000688 => x"08000937", |
00000689 => x"fff00993", |
00000690 => x"00010a37", |
00000691 => x"fff48493", |
00000692 => x"07349063", |
00000693 => x"4788d5b7", |
00000694 => x"afe58593", |
00000695 => x"08000537", |
00000696 => x"e81ff0ef", |
00000697 => x"08000537", |
00000698 => x"00040593", |
00000699 => x"00450513", |
00000700 => x"e71ff0ef", |
00000701 => x"ff002a03", |
00000702 => x"080009b7", |
00000703 => x"ffc47413", |
00000704 => x"00000493", |
00000705 => x"00000913", |
00000706 => x"00c98a93", |
00000707 => x"01548533", |
00000708 => x"009a07b3", |
00000709 => x"02849663", |
00000710 => x"00898513", |
00000711 => x"412005b3", |
00000712 => x"e41ff0ef", |
00000713 => x"ffff1537", |
00000714 => x"ea450513", |
00000715 => x"f05ff06f", |
00000716 => x"00090513", |
00000717 => x"e85ff0ef", |
00000718 => x"01490933", |
00000719 => x"f91ff06f", |
00000720 => x"0007a583", |
00000721 => x"00448493", |
00000722 => x"00b90933", |
00000723 => x"e15ff0ef", |
00000724 => x"fbdff06f", |
00000725 => x"01c12083", |
00000726 => x"01812403", |
00000727 => x"01412483", |
00000728 => x"01012903", |
00000729 => x"00c12983", |
00000730 => x"00812a03", |
00000731 => x"00412a83", |
00000732 => x"02010113", |
00000733 => x"00008067", |
00000734 => x"fe802503", |
00000735 => x"01155513", |
00000736 => x"00157513", |
00000737 => x"00008067", |
00000738 => x"ff010113", |
00000739 => x"f9402783", |
00000740 => x"f9002703", |
00000741 => x"f9402683", |
00000742 => x"fed79ae3", |
00000743 => x"00e12023", |
00000744 => x"00f12223", |
00000745 => x"00012503", |
00000746 => x"00412583", |
00000747 => x"01010113", |
00000268 => x"00000013", |
00000269 => x"18d000ef", |
00000270 => x"00050863", |
00000271 => x"00100513", |
00000272 => x"00000593", |
00000273 => x"1bd000ef", |
00000274 => x"0000006f", |
00000275 => x"fe010113", |
00000276 => x"01212823", |
00000277 => x"00050913", |
00000278 => x"ffff1537", |
00000279 => x"00912a23", |
00000280 => x"e9050513", |
00000281 => x"ffff14b7", |
00000282 => x"00812c23", |
00000283 => x"01312623", |
00000284 => x"00112e23", |
00000285 => x"01c00413", |
00000286 => x"01d000ef", |
00000287 => x"fe848493", |
00000288 => x"ffc00993", |
00000289 => x"008957b3", |
00000290 => x"00f7f793", |
00000291 => x"00f487b3", |
00000292 => x"0007c503", |
00000293 => x"ffc40413", |
00000294 => x"7ac000ef", |
00000295 => x"ff3414e3", |
00000296 => x"01c12083", |
00000297 => x"01812403", |
00000298 => x"01412483", |
00000299 => x"01012903", |
00000300 => x"00c12983", |
00000301 => x"02010113", |
00000302 => x"00008067", |
00000303 => x"fb010113", |
00000304 => x"04112623", |
00000305 => x"04512423", |
00000306 => x"04612223", |
00000307 => x"04712023", |
00000308 => x"02812e23", |
00000309 => x"02912c23", |
00000310 => x"02a12a23", |
00000311 => x"02b12823", |
00000312 => x"02c12623", |
00000313 => x"02d12423", |
00000314 => x"02e12223", |
00000315 => x"02f12023", |
00000316 => x"01012e23", |
00000317 => x"01112c23", |
00000318 => x"01c12a23", |
00000319 => x"01d12823", |
00000320 => x"01e12623", |
00000321 => x"01f12423", |
00000322 => x"342024f3", |
00000323 => x"800007b7", |
00000324 => x"00778793", |
00000325 => x"08f49463", |
00000326 => x"0a9000ef", |
00000327 => x"00050663", |
00000328 => x"00000513", |
00000329 => x"0ad000ef", |
00000330 => x"654000ef", |
00000331 => x"02050063", |
00000332 => x"7bc000ef", |
00000333 => x"fe002783", |
00000334 => x"0027d793", |
00000335 => x"00a78533", |
00000336 => x"00f537b3", |
00000337 => x"00b785b3", |
00000338 => x"644000ef", |
00000339 => x"03c12403", |
00000340 => x"04c12083", |
00000341 => x"04812283", |
00000342 => x"04412303", |
00000343 => x"04012383", |
00000344 => x"03812483", |
00000345 => x"03412503", |
00000346 => x"03012583", |
00000347 => x"02c12603", |
00000348 => x"02812683", |
00000349 => x"02412703", |
00000350 => x"02012783", |
00000351 => x"01c12803", |
00000352 => x"01812883", |
00000353 => x"01412e03", |
00000354 => x"01012e83", |
00000355 => x"00c12f03", |
00000356 => x"00812f83", |
00000357 => x"05010113", |
00000358 => x"30200073", |
00000359 => x"00700793", |
00000360 => x"00f49a63", |
00000361 => x"8041a783", |
00000362 => x"00078663", |
00000363 => x"00100513", |
00000364 => x"e51ff0ef", |
00000365 => x"34102473", |
00000366 => x"5ec000ef", |
00000367 => x"04050263", |
00000368 => x"ffff1537", |
00000369 => x"e9450513", |
00000370 => x"6cc000ef", |
00000371 => x"00048513", |
00000372 => x"e7dff0ef", |
00000373 => x"02000513", |
00000374 => x"66c000ef", |
00000375 => x"00040513", |
00000376 => x"e6dff0ef", |
00000377 => x"02000513", |
00000378 => x"65c000ef", |
00000379 => x"34302573", |
00000380 => x"e5dff0ef", |
00000381 => x"ffff1537", |
00000382 => x"e9c50513", |
00000383 => x"698000ef", |
00000384 => x"00440413", |
00000385 => x"34141073", |
00000386 => x"f45ff06f", |
00000387 => x"ff010113", |
00000388 => x"00000513", |
00000389 => x"00112623", |
00000390 => x"00812423", |
00000391 => x"74c000ef", |
00000392 => x"09e00513", |
00000393 => x"788000ef", |
00000394 => x"00000513", |
00000395 => x"780000ef", |
00000396 => x"00050413", |
00000397 => x"00000513", |
00000398 => x"750000ef", |
00000399 => x"00c12083", |
00000400 => x"0ff47513", |
00000401 => x"00812403", |
00000402 => x"01010113", |
00000403 => x"00008067", |
00000404 => x"ff010113", |
00000405 => x"00112623", |
00000406 => x"00812423", |
00000407 => x"00000513", |
00000408 => x"708000ef", |
00000409 => x"00500513", |
00000410 => x"744000ef", |
00000411 => x"00000513", |
00000412 => x"73c000ef", |
00000413 => x"00050413", |
00000414 => x"00147413", |
00000415 => x"00000513", |
00000416 => x"708000ef", |
00000417 => x"fc041ce3", |
00000418 => x"00c12083", |
00000419 => x"00812403", |
00000420 => x"01010113", |
00000421 => x"00008067", |
00000422 => x"ff010113", |
00000423 => x"00000513", |
00000424 => x"00112623", |
00000425 => x"6c4000ef", |
00000426 => x"00600513", |
00000427 => x"700000ef", |
00000428 => x"00c12083", |
00000429 => x"00000513", |
00000430 => x"01010113", |
00000431 => x"6cc0006f", |
00000432 => x"ff010113", |
00000433 => x"00812423", |
00000434 => x"00050413", |
00000435 => x"01055513", |
00000436 => x"0ff57513", |
00000437 => x"00112623", |
00000438 => x"6d4000ef", |
00000439 => x"00845513", |
00000440 => x"0ff57513", |
00000441 => x"6c8000ef", |
00000442 => x"0ff47513", |
00000443 => x"00812403", |
00000444 => x"00c12083", |
00000445 => x"01010113", |
00000446 => x"6b40006f", |
00000447 => x"ff010113", |
00000448 => x"00812423", |
00000449 => x"00050413", |
00000450 => x"00000513", |
00000451 => x"00112623", |
00000452 => x"658000ef", |
00000453 => x"00300513", |
00000454 => x"694000ef", |
00000455 => x"00040513", |
00000456 => x"fa1ff0ef", |
00000457 => x"00000513", |
00000458 => x"684000ef", |
00000459 => x"00050413", |
00000460 => x"00000513", |
00000461 => x"654000ef", |
00000462 => x"00c12083", |
00000463 => x"0ff47513", |
00000464 => x"00812403", |
00000465 => x"01010113", |
00000466 => x"00008067", |
00000467 => x"fd010113", |
00000468 => x"02812423", |
00000469 => x"02912223", |
00000470 => x"03212023", |
00000471 => x"01312e23", |
00000472 => x"01412c23", |
00000473 => x"02112623", |
00000474 => x"00050913", |
00000475 => x"00058993", |
00000476 => x"00c10493", |
00000477 => x"00000413", |
00000478 => x"00400a13", |
00000479 => x"02091e63", |
00000480 => x"4f8000ef", |
00000481 => x"00a48023", |
00000482 => x"00140413", |
00000483 => x"00148493", |
00000484 => x"ff4416e3", |
00000485 => x"02c12083", |
00000486 => x"02812403", |
00000487 => x"00c12503", |
00000488 => x"02412483", |
00000489 => x"02012903", |
00000490 => x"01c12983", |
00000491 => x"01812a03", |
00000492 => x"03010113", |
00000493 => x"00008067", |
00000494 => x"00898533", |
00000495 => x"f41ff0ef", |
00000496 => x"fc5ff06f", |
00000497 => x"fd010113", |
00000498 => x"01412c23", |
00000499 => x"02812423", |
00000500 => x"80418793", |
00000501 => x"02112623", |
00000502 => x"02912223", |
00000503 => x"03212023", |
00000504 => x"01312e23", |
00000505 => x"01512a23", |
00000506 => x"01612823", |
00000507 => x"01712623", |
00000508 => x"01812423", |
00000509 => x"00100713", |
00000510 => x"00e7a023", |
00000511 => x"00050413", |
00000512 => x"80418a13", |
00000513 => x"02051863", |
00000514 => x"ffff1537", |
00000515 => x"ea050513", |
00000516 => x"484000ef", |
00000517 => x"080005b7", |
00000518 => x"00040513", |
00000519 => x"f31ff0ef", |
00000520 => x"4788d7b7", |
00000521 => x"afe78793", |
00000522 => x"02f50a63", |
00000523 => x"00000513", |
00000524 => x"01c0006f", |
00000525 => x"ffff1537", |
00000526 => x"ec050513", |
00000527 => x"458000ef", |
00000528 => x"4d8000ef", |
00000529 => x"00051663", |
00000530 => x"00300513", |
00000531 => x"bb5ff0ef", |
00000532 => x"dbdff0ef", |
00000533 => x"fc0510e3", |
00000534 => x"ff1ff06f", |
00000535 => x"080009b7", |
00000536 => x"00498593", |
00000537 => x"00040513", |
00000538 => x"ee5ff0ef", |
00000539 => x"00050a93", |
00000540 => x"00898593", |
00000541 => x"00040513", |
00000542 => x"ed5ff0ef", |
00000543 => x"ff002c03", |
00000544 => x"00050b13", |
00000545 => x"ffcafb93", |
00000546 => x"00000913", |
00000547 => x"00000493", |
00000548 => x"00c98993", |
00000549 => x"013905b3", |
00000550 => x"052b9c63", |
00000551 => x"016484b3", |
00000552 => x"00200513", |
00000553 => x"fa0494e3", |
00000554 => x"ffff1537", |
00000555 => x"ecc50513", |
00000556 => x"3e4000ef", |
00000557 => x"02c12083", |
00000558 => x"02812403", |
00000559 => x"800007b7", |
00000560 => x"0157a023", |
00000561 => x"000a2023", |
00000562 => x"02412483", |
00000563 => x"02012903", |
00000564 => x"01c12983", |
00000565 => x"01812a03", |
00000566 => x"01412a83", |
00000567 => x"01012b03", |
00000568 => x"00c12b83", |
00000569 => x"00812c03", |
00000570 => x"03010113", |
00000571 => x"00008067", |
00000572 => x"00040513", |
00000573 => x"e59ff0ef", |
00000574 => x"012c07b3", |
00000575 => x"00a484b3", |
00000576 => x"00a7a023", |
00000577 => x"00490913", |
00000578 => x"f8dff06f", |
00000579 => x"ff010113", |
00000580 => x"00112623", |
00000581 => x"00812423", |
00000582 => x"00912223", |
00000583 => x"00058413", |
00000584 => x"00050493", |
00000585 => x"d75ff0ef", |
00000586 => x"00000513", |
00000587 => x"43c000ef", |
00000588 => x"00200513", |
00000589 => x"478000ef", |
00000590 => x"00048513", |
00000591 => x"d85ff0ef", |
00000592 => x"00040513", |
00000593 => x"468000ef", |
00000594 => x"00000513", |
00000595 => x"43c000ef", |
00000596 => x"00812403", |
00000597 => x"00c12083", |
00000598 => x"00412483", |
00000599 => x"01010113", |
00000600 => x"cf1ff06f", |
00000601 => x"fe010113", |
00000602 => x"00812c23", |
00000603 => x"00912a23", |
00000604 => x"01212823", |
00000605 => x"00112e23", |
00000606 => x"00050493", |
00000607 => x"00b12623", |
00000608 => x"00000413", |
00000609 => x"00400913", |
00000610 => x"00c10793", |
00000611 => x"008787b3", |
00000612 => x"0007c583", |
00000613 => x"00848533", |
00000614 => x"00140413", |
00000615 => x"f71ff0ef", |
00000616 => x"ff2414e3", |
00000617 => x"01c12083", |
00000618 => x"01812403", |
00000619 => x"01412483", |
00000620 => x"01012903", |
00000621 => x"02010113", |
00000622 => x"00008067", |
00000623 => x"ff010113", |
00000624 => x"00112623", |
00000625 => x"00812423", |
00000626 => x"00050413", |
00000627 => x"ccdff0ef", |
00000628 => x"00000513", |
00000629 => x"394000ef", |
00000630 => x"0d800513", |
00000631 => x"3d0000ef", |
00000632 => x"00040513", |
00000633 => x"cddff0ef", |
00000634 => x"00000513", |
00000635 => x"39c000ef", |
00000636 => x"00812403", |
00000637 => x"00c12083", |
00000638 => x"01010113", |
00000639 => x"c55ff06f", |
00000640 => x"fe010113", |
00000641 => x"800007b7", |
00000642 => x"00812c23", |
00000643 => x"0007a403", |
00000644 => x"00112e23", |
00000645 => x"00912a23", |
00000646 => x"01212823", |
00000647 => x"01312623", |
00000648 => x"01412423", |
00000649 => x"01512223", |
00000650 => x"02041863", |
00000651 => x"ffff1537", |
00000652 => x"ed050513", |
00000653 => x"01812403", |
00000654 => x"01c12083", |
00000655 => x"01412483", |
00000656 => x"01012903", |
00000657 => x"00c12983", |
00000658 => x"00812a03", |
00000659 => x"00412a83", |
00000660 => x"02010113", |
00000661 => x"2400006f", |
00000662 => x"ffff1537", |
00000663 => x"eec50513", |
00000664 => x"234000ef", |
00000665 => x"00040513", |
00000666 => x"9e5ff0ef", |
00000667 => x"ffff1537", |
00000668 => x"ef450513", |
00000669 => x"220000ef", |
00000670 => x"08000537", |
00000671 => x"9d1ff0ef", |
00000672 => x"ffff1537", |
00000673 => x"f0c50513", |
00000674 => x"20c000ef", |
00000675 => x"1ec000ef", |
00000676 => x"00050493", |
00000677 => x"1b0000ef", |
00000678 => x"07900793", |
00000679 => x"0af49e63", |
00000680 => x"b6dff0ef", |
00000681 => x"00051663", |
00000682 => x"00300513", |
00000683 => x"955ff0ef", |
00000684 => x"ffff1537", |
00000685 => x"f1850513", |
00000686 => x"01045493", |
00000687 => x"1d8000ef", |
00000688 => x"00148493", |
00000689 => x"08000937", |
00000690 => x"fff00993", |
00000691 => x"00010a37", |
00000692 => x"fff48493", |
00000693 => x"07349063", |
00000694 => x"4788d5b7", |
00000695 => x"afe58593", |
00000696 => x"08000537", |
00000697 => x"e81ff0ef", |
00000698 => x"08000537", |
00000699 => x"00040593", |
00000700 => x"00450513", |
00000701 => x"e71ff0ef", |
00000702 => x"ff002a03", |
00000703 => x"080009b7", |
00000704 => x"ffc47413", |
00000705 => x"00000493", |
00000706 => x"00000913", |
00000707 => x"00c98a93", |
00000708 => x"01548533", |
00000709 => x"009a07b3", |
00000710 => x"02849663", |
00000711 => x"00898513", |
00000712 => x"412005b3", |
00000713 => x"e41ff0ef", |
00000714 => x"ffff1537", |
00000715 => x"ecc50513", |
00000716 => x"f05ff06f", |
00000717 => x"00090513", |
00000718 => x"e85ff0ef", |
00000719 => x"01490933", |
00000720 => x"f91ff06f", |
00000721 => x"0007a583", |
00000722 => x"00448493", |
00000723 => x"00b90933", |
00000724 => x"e15ff0ef", |
00000725 => x"fbdff06f", |
00000726 => x"01c12083", |
00000727 => x"01812403", |
00000728 => x"01412483", |
00000729 => x"01012903", |
00000730 => x"00c12983", |
00000731 => x"00812a03", |
00000732 => x"00412a83", |
00000733 => x"02010113", |
00000734 => x"00008067", |
00000735 => x"fe802503", |
00000736 => x"01155513", |
00000737 => x"00157513", |
00000738 => x"00008067", |
00000739 => x"f9000793", |
00000740 => x"fff00713", |
00000741 => x"00e7a423", |
00000742 => x"00b7a623", |
00000743 => x"00a7a423", |
00000744 => x"00008067", |
00000745 => x"fe802503", |
00000746 => x"01255513", |
00000747 => x"00157513", |
00000748 => x"00008067", |
00000749 => x"f9000793", |
00000750 => x"fff00713", |
00000751 => x"00e7a423", |
00000752 => x"00b7a623", |
00000753 => x"00a7a423", |
00000754 => x"00008067", |
00000755 => x"fe802503", |
00000756 => x"01255513", |
00000757 => x"00157513", |
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"fa002783", |
00000796 => x"fe07cee3", |
00000797 => x"faa02223", |
00000798 => x"00008067", |
00000799 => x"fa002503", |
00000800 => x"01f55513", |
00000749 => x"fa002023", |
00000750 => x"fe002703", |
00000751 => x"00151513", |
00000752 => x"00000793", |
00000753 => x"04a77463", |
00000754 => x"000016b7", |
00000755 => x"00000713", |
00000756 => x"ffe68693", |
00000757 => x"04f6e663", |
00000758 => x"00367613", |
00000759 => x"0035f593", |
00000760 => x"fff78793", |
00000761 => x"01461613", |
00000762 => x"00c7e7b3", |
00000763 => x"01659593", |
00000764 => x"01871713", |
00000765 => x"00b7e7b3", |
00000766 => x"00e7e7b3", |
00000767 => x"10000737", |
00000768 => x"00e7e7b3", |
00000769 => x"faf02023", |
00000770 => x"00008067", |
00000771 => x"00178793", |
00000772 => x"01079793", |
00000773 => x"40a70733", |
00000774 => x"0107d793", |
00000775 => x"fa9ff06f", |
00000776 => x"ffe70513", |
00000777 => x"0fd57513", |
00000778 => x"00051a63", |
00000779 => x"0037d793", |
00000780 => x"00170713", |
00000781 => x"0ff77713", |
00000782 => x"f9dff06f", |
00000783 => x"0017d793", |
00000784 => x"ff1ff06f", |
00000785 => x"00040737", |
00000786 => x"fa002783", |
00000787 => x"00e7f7b3", |
00000788 => x"fe079ce3", |
00000789 => x"faa02223", |
00000790 => x"00008067", |
00000791 => x"fa002783", |
00000792 => x"00100513", |
00000793 => x"0007c863", |
00000794 => x"0107d513", |
00000795 => x"00154513", |
00000796 => x"00157513", |
00000797 => x"00008067", |
00000798 => x"fa402503", |
00000799 => x"fe055ee3", |
00000800 => x"0ff57513", |
00000801 => x"00008067", |
00000802 => x"fa402503", |
00000803 => x"fe055ee3", |
00000804 => x"0ff57513", |
00000805 => x"00008067", |
00000806 => x"fa402503", |
00000807 => x"01f55513", |
00000808 => x"00008067", |
00000809 => x"ff010113", |
00000810 => x"00812423", |
00000811 => x"01212023", |
00000812 => x"00112623", |
00000813 => x"00912223", |
00000814 => x"00050413", |
00000815 => x"00a00913", |
00000816 => x"00044483", |
00000817 => x"00140413", |
00000818 => x"00049e63", |
00000819 => x"00c12083", |
00000820 => x"00812403", |
00000821 => x"00412483", |
00000822 => x"00012903", |
00000823 => x"01010113", |
00000824 => x"00008067", |
00000825 => x"01249663", |
00000826 => x"00d00513", |
00000827 => x"f81ff0ef", |
00000828 => x"00048513", |
00000829 => x"f79ff0ef", |
00000830 => x"fc9ff06f", |
00000831 => x"fe802503", |
00000832 => x"01355513", |
00000833 => x"00157513", |
00000834 => x"00008067", |
00000835 => x"00757513", |
00000836 => x"00367613", |
00000837 => x"0015f593", |
00000838 => x"00a51513", |
00000839 => x"00d61613", |
00000840 => x"00c56533", |
00000841 => x"00959593", |
00000842 => x"fa800793", |
00000843 => x"00b56533", |
00000844 => x"0007a023", |
00000845 => x"10056513", |
00000846 => x"00a7a023", |
00000847 => x"00008067", |
00000848 => x"fa800713", |
00000849 => x"00072683", |
00000850 => x"00757793", |
00000851 => x"00100513", |
00000852 => x"00f51533", |
00000853 => x"00d56533", |
00000854 => x"00a72023", |
00000855 => x"00008067", |
00000856 => x"fa800713", |
00000857 => x"00072683", |
00000858 => x"00757513", |
00000859 => x"00100793", |
00000860 => x"00a797b3", |
00000861 => x"fff7c793", |
00000862 => x"00d7f7b3", |
00000863 => x"00f72023", |
00000864 => x"00008067", |
00000865 => x"faa02623", |
00000866 => x"fa802783", |
00000867 => x"fe07cee3", |
00000868 => x"fac02503", |
00000869 => x"00008067", |
00000870 => x"fe802503", |
00000871 => x"01055513", |
00000872 => x"00157513", |
00000873 => x"00008067", |
00000874 => x"00100793", |
00000875 => x"01f00713", |
00000876 => x"00a797b3", |
00000877 => x"00a74a63", |
00000878 => x"fc802703", |
00000879 => x"00f747b3", |
00000880 => x"fcf02423", |
00000881 => x"00008067", |
00000882 => x"fcc02703", |
00000883 => x"00f747b3", |
00000884 => x"fcf02623", |
00000885 => x"00008067", |
00000886 => x"fc000793", |
00000887 => x"00a7a423", |
00000888 => x"00b7a623", |
00000889 => x"00008067", |
00000890 => x"69617641", |
00000891 => x"6c62616c", |
00000892 => x"4d432065", |
00000893 => x"0a3a7344", |
00000894 => x"203a6820", |
00000895 => x"706c6548", |
00000896 => x"3a72200a", |
00000897 => x"73655220", |
00000898 => x"74726174", |
00000899 => x"3a75200a", |
00000900 => x"6c705520", |
00000901 => x"0a64616f", |
00000902 => x"203a7320", |
00000903 => x"726f7453", |
00000904 => x"6f742065", |
00000905 => x"616c6620", |
00000906 => x"200a6873", |
00000907 => x"4c203a6c", |
00000908 => x"2064616f", |
00000909 => x"6d6f7266", |
00000910 => x"616c6620", |
00000911 => x"200a6873", |
00000912 => x"45203a65", |
00000913 => x"75636578", |
00000914 => x"00006574", |
00000915 => x"746f6f42", |
00000916 => x"2e676e69", |
00000917 => x"0a0a2e2e", |
00000918 => x"00000000", |
00000919 => x"52450a07", |
00000920 => x"5f524f52", |
00000921 => x"00000000", |
00000922 => x"00007830", |
00000923 => x"58455b0a", |
00000924 => x"00002043", |
00000925 => x"00000a5d", |
00000926 => x"69617741", |
00000927 => x"676e6974", |
00000928 => x"6f656e20", |
00000929 => x"32337672", |
00000930 => x"6578655f", |
00000931 => x"6e69622e", |
00000932 => x"202e2e2e", |
00000933 => x"00000000", |
00000934 => x"64616f4c", |
00000935 => x"2e676e69", |
00000936 => x"00202e2e", |
00000937 => x"00004b4f", |
00000938 => x"65206f4e", |
00000939 => x"75636578", |
00000940 => x"6c626174", |
00000941 => x"76612065", |
00000942 => x"616c6961", |
00000943 => x"2e656c62", |
00000944 => x"00000000", |
00000945 => x"74697257", |
00000946 => x"00002065", |
00000947 => x"74796220", |
00000948 => x"74207365", |
00000949 => x"5053206f", |
00000950 => x"6c662049", |
00000951 => x"20687361", |
00000952 => x"00002040", |
00000953 => x"7928203f", |
00000954 => x"20296e2f", |
00000955 => x"00000000", |
00000956 => x"616c460a", |
00000957 => x"6e696873", |
00000958 => x"2e2e2e67", |
00000959 => x"00000020", |
00000960 => x"3c0a0a0a", |
00000961 => x"454e203c", |
00000962 => x"3356524f", |
00000963 => x"6f422032", |
00000964 => x"6f6c746f", |
00000965 => x"72656461", |
00000966 => x"0a3e3e20", |
00000967 => x"444c420a", |
00000968 => x"53203a56", |
00000969 => x"32207065", |
00000970 => x"30322031", |
00000971 => x"480a3132", |
00000972 => x"203a5657", |
00000973 => x"00000020", |
00000974 => x"4b4c430a", |
00000975 => x"0020203a", |
00000976 => x"53494d0a", |
00000977 => x"00203a41", |
00000978 => x"5550430a", |
00000979 => x"0020203a", |
00000980 => x"434f530a", |
00000981 => x"0020203a", |
00000982 => x"454d490a", |
00000983 => x"00203a4d", |
00000984 => x"74796220", |
00000985 => x"40207365", |
00000986 => x"00000000", |
00000987 => x"454d440a", |
00000988 => x"00203a4d", |
00000989 => x"75410a0a", |
00000990 => x"6f626f74", |
00000991 => x"6920746f", |
00000992 => x"7338206e", |
00000993 => x"7250202e", |
00000994 => x"20737365", |
00000995 => x"2079656b", |
00000996 => x"61206f74", |
00000997 => x"74726f62", |
00000998 => x"00000a2e", |
00000999 => x"0000000a", |
00001000 => x"726f6241", |
00001001 => x"2e646574", |
00001002 => x"00000a0a", |
00001003 => x"444d430a", |
00001004 => x"00203e3a", |
00001005 => x"61766e49", |
00001006 => x"2064696c", |
00001007 => x"00444d43", |
00001008 => x"33323130", |
00001009 => x"37363534", |
00001010 => x"62613938", |
00001011 => x"66656463" |
00000803 => x"01f55513", |
00000804 => x"00008067", |
00000805 => x"ff010113", |
00000806 => x"00812423", |
00000807 => x"01212023", |
00000808 => x"00112623", |
00000809 => x"00912223", |
00000810 => x"00050413", |
00000811 => x"00a00913", |
00000812 => x"00044483", |
00000813 => x"00140413", |
00000814 => x"00049e63", |
00000815 => x"00c12083", |
00000816 => x"00812403", |
00000817 => x"00412483", |
00000818 => x"00012903", |
00000819 => x"01010113", |
00000820 => x"00008067", |
00000821 => x"01249663", |
00000822 => x"00d00513", |
00000823 => x"f69ff0ef", |
00000824 => x"00048513", |
00000825 => x"f61ff0ef", |
00000826 => x"fc9ff06f", |
00000827 => x"ff010113", |
00000828 => x"c81026f3", |
00000829 => x"c0102773", |
00000830 => x"c81027f3", |
00000831 => x"fed79ae3", |
00000832 => x"00e12023", |
00000833 => x"00f12223", |
00000834 => x"00012503", |
00000835 => x"00412583", |
00000836 => x"01010113", |
00000837 => x"00008067", |
00000838 => x"fe802503", |
00000839 => x"01355513", |
00000840 => x"00157513", |
00000841 => x"00008067", |
00000842 => x"00757513", |
00000843 => x"0036f793", |
00000844 => x"00167613", |
00000845 => x"00a51513", |
00000846 => x"00d79793", |
00000847 => x"0015f593", |
00000848 => x"00f567b3", |
00000849 => x"00f61613", |
00000850 => x"00c7e7b3", |
00000851 => x"00959593", |
00000852 => x"fa800713", |
00000853 => x"00b7e7b3", |
00000854 => x"00072023", |
00000855 => x"1007e793", |
00000856 => x"00f72023", |
00000857 => x"00008067", |
00000858 => x"fa800713", |
00000859 => x"00072683", |
00000860 => x"00757793", |
00000861 => x"00100513", |
00000862 => x"00f51533", |
00000863 => x"00d56533", |
00000864 => x"00a72023", |
00000865 => x"00008067", |
00000866 => x"fa800713", |
00000867 => x"00072683", |
00000868 => x"00757513", |
00000869 => x"00100793", |
00000870 => x"00a797b3", |
00000871 => x"fff7c793", |
00000872 => x"00d7f7b3", |
00000873 => x"00f72023", |
00000874 => x"00008067", |
00000875 => x"faa02623", |
00000876 => x"fa802783", |
00000877 => x"fe07cee3", |
00000878 => x"fac02503", |
00000879 => x"00008067", |
00000880 => x"fe802503", |
00000881 => x"01055513", |
00000882 => x"00157513", |
00000883 => x"00008067", |
00000884 => x"00100793", |
00000885 => x"01f00713", |
00000886 => x"00a797b3", |
00000887 => x"00a74a63", |
00000888 => x"fc802703", |
00000889 => x"00f747b3", |
00000890 => x"fcf02423", |
00000891 => x"00008067", |
00000892 => x"fcc02703", |
00000893 => x"00f747b3", |
00000894 => x"fcf02623", |
00000895 => x"00008067", |
00000896 => x"fc000793", |
00000897 => x"00a7a423", |
00000898 => x"00b7a623", |
00000899 => x"00008067", |
00000900 => x"69617641", |
00000901 => x"6c62616c", |
00000902 => x"4d432065", |
00000903 => x"0a3a7344", |
00000904 => x"203a6820", |
00000905 => x"706c6548", |
00000906 => x"3a72200a", |
00000907 => x"73655220", |
00000908 => x"74726174", |
00000909 => x"3a75200a", |
00000910 => x"6c705520", |
00000911 => x"0a64616f", |
00000912 => x"203a7320", |
00000913 => x"726f7453", |
00000914 => x"6f742065", |
00000915 => x"616c6620", |
00000916 => x"200a6873", |
00000917 => x"4c203a6c", |
00000918 => x"2064616f", |
00000919 => x"6d6f7266", |
00000920 => x"616c6620", |
00000921 => x"200a6873", |
00000922 => x"45203a65", |
00000923 => x"75636578", |
00000924 => x"00006574", |
00000925 => x"746f6f42", |
00000926 => x"2e676e69", |
00000927 => x"0a0a2e2e", |
00000928 => x"00000000", |
00000929 => x"52450a07", |
00000930 => x"5f524f52", |
00000931 => x"00000000", |
00000932 => x"00007830", |
00000933 => x"58455b0a", |
00000934 => x"00002043", |
00000935 => x"00000a5d", |
00000936 => x"69617741", |
00000937 => x"676e6974", |
00000938 => x"6f656e20", |
00000939 => x"32337672", |
00000940 => x"6578655f", |
00000941 => x"6e69622e", |
00000942 => x"202e2e2e", |
00000943 => x"00000000", |
00000944 => x"64616f4c", |
00000945 => x"2e676e69", |
00000946 => x"00202e2e", |
00000947 => x"00004b4f", |
00000948 => x"65206f4e", |
00000949 => x"75636578", |
00000950 => x"6c626174", |
00000951 => x"76612065", |
00000952 => x"616c6961", |
00000953 => x"2e656c62", |
00000954 => x"00000000", |
00000955 => x"74697257", |
00000956 => x"00002065", |
00000957 => x"74796220", |
00000958 => x"74207365", |
00000959 => x"5053206f", |
00000960 => x"6c662049", |
00000961 => x"20687361", |
00000962 => x"00002040", |
00000963 => x"7928203f", |
00000964 => x"20296e2f", |
00000965 => x"00000000", |
00000966 => x"616c460a", |
00000967 => x"6e696873", |
00000968 => x"2e2e2e67", |
00000969 => x"00000020", |
00000970 => x"3c0a0a0a", |
00000971 => x"454e203c", |
00000972 => x"3356524f", |
00000973 => x"6f422032", |
00000974 => x"6f6c746f", |
00000975 => x"72656461", |
00000976 => x"0a3e3e20", |
00000977 => x"444c420a", |
00000978 => x"4f203a56", |
00000979 => x"31207463", |
00000980 => x"30322037", |
00000981 => x"480a3132", |
00000982 => x"203a5657", |
00000983 => x"00000020", |
00000984 => x"4b4c430a", |
00000985 => x"0020203a", |
00000986 => x"53494d0a", |
00000987 => x"00203a41", |
00000988 => x"5550430a", |
00000989 => x"0020203a", |
00000990 => x"434f530a", |
00000991 => x"0020203a", |
00000992 => x"454d490a", |
00000993 => x"00203a4d", |
00000994 => x"74796220", |
00000995 => x"40207365", |
00000996 => x"00000000", |
00000997 => x"454d440a", |
00000998 => x"00203a4d", |
00000999 => x"75410a0a", |
00001000 => x"6f626f74", |
00001001 => x"6920746f", |
00001002 => x"7338206e", |
00001003 => x"7250202e", |
00001004 => x"20737365", |
00001005 => x"2079656b", |
00001006 => x"61206f74", |
00001007 => x"74726f62", |
00001008 => x"00000a2e", |
00001009 => x"0000000a", |
00001010 => x"726f6241", |
00001011 => x"2e646574", |
00001012 => x"00000a0a", |
00001013 => x"444d430a", |
00001014 => x"00203e3a", |
00001015 => x"61766e49", |
00001016 => x"2064696c", |
00001017 => x"00444d43", |
00001018 => x"33323130", |
00001019 => x"37363534", |
00001020 => x"62613938", |
00001021 => x"66656463" |
); |
|
end neorv32_bootloader_image; |
/neorv32_cfs.vhd
1,9 → 1,9
-- ################################################################################################# |
-- # << NEORV32 - Custom Functions Subsystem (CFS) >> # |
-- # ********************************************************************************************* # |
-- # For tightly-coupled custom co-processors. Provides 32x32-bit memory-mapped registers. This is # |
-- # just an "example/illustration template". Modify this file to implement your own custom design # |
-- # logic. # |
-- # For tightly-coupled custom co-processors. Provides 32x32-bit memory-mapped registers. # |
-- # This is just an "example/illustration template". Modify this file to implement your own # |
-- # custom design logic. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
62,8 → 62,6
-- clock generator -- |
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); -- "clock" inputs |
-- CPU state -- |
sleep_i : in std_ulogic; -- set if cpu is in sleep mode |
-- interrupt -- |
irq_o : out std_ulogic; -- interrupt request |
-- custom io (conduits) -- |
165,21 → 163,13
clkgen_en_o <= '0'; -- not used for this minimal example |
|
|
-- Further Power Optimization ------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- The CFS can decide to go into low-power mode (by disabling all switching activity) when the CPU enters sleep mode. |
-- The sleep_i signal is high when the CPU is in sleep mode. Any interrupt including the CFS's irq_o interrupt request signal |
-- will wake up the CPU again. |
|
-- sleep_i |
|
|
-- Interrupt ------------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
-- The CFS features a single interrupt signal. This interrupt is connected to the CPU's "fast interrupt" channel 1. |
-- The interrupt is single-shot. Setting the irq_o signal high for one cycle will generate an interrupt request. |
-- It is recommended to implement some CFS mechanisms (like a register that needs to be written) in order to allow |
-- another generation on an interrupt request (simple acknowledgement). |
-- The CFS features a single interrupt signal, which is connected to the CPU's "fast interrupt" channel 1. |
-- The interrupt is high-level-active. When set, the interrupt appears as "pending" in the CPU's mie register |
-- ready to trigger execution of the according interrupt handler. |
-- Once set, the irq_o signal **has to stay set** until explicitly acknowledged by the CPU |
-- (for example by reading/writing from/to a specific CFS interface register address). |
|
irq_o <= '0'; -- not used for this minimal example |
|
/neorv32_cpu.vhd
326,8 → 326,7
alu_i => alu_res, -- ALU result |
-- data output -- |
rs1_o => rs1, -- operand 1 |
rs2_o => rs2, -- operand 2 |
cmp_o => comparator -- comparator status |
rs2_o => rs2 -- operand 2 |
); |
|
|
355,8 → 354,8
pc2_i => curr_pc, -- delayed PC |
imm_i => imm, -- immediate |
csr_i => csr_rdata, -- CSR read data |
cmp_i => comparator, -- comparator status |
-- data output -- |
cmp_o => comparator, -- comparator status |
res_o => alu_res, -- ALU result |
add_o => alu_add, -- address computation result |
fpu_flags_o => fpu_flags, -- FPU exception flags |
/neorv32_cpu_alu.vhd
63,8 → 63,8
pc2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC |
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
csr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data |
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status |
-- data output -- |
cmp_o : out std_ulogic_vector(1 downto 0); -- comparator status |
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- ALU result |
add_o : out std_ulogic_vector(data_width_c-1 downto 0); -- address computation result |
fpu_flags_o : out std_ulogic_vector(4 downto 0); -- FPU exception flags |
75,6 → 75,11
|
architecture neorv32_cpu_cpu_rtl of neorv32_cpu_alu is |
|
-- comparator -- |
signal cmp_opx : std_ulogic_vector(data_width_c downto 0); |
signal cmp_opy : std_ulogic_vector(data_width_c downto 0); |
signal cmp : std_ulogic_vector(1 downto 0); -- comparator status |
|
-- operands -- |
signal opa, opb : std_ulogic_vector(data_width_c-1 downto 0); |
|
102,8 → 107,18
|
begin |
|
-- Operand Mux ---------------------------------------------------------------------------- |
-- Comparator Unit (for conditional branches) --------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
cmp_opx <= (rs1_i(rs1_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs1_i; |
cmp_opy <= (rs2_i(rs2_i'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs2_i; |
|
cmp(cmp_equal_c) <= '1' when (rs1_i = rs2_i) else '0'; |
cmp(cmp_less_c) <= '1' when (signed(cmp_opx) < signed(cmp_opy)) else '0'; |
cmp_o <= cmp; |
|
|
-- ALU Input Operand Mux ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
opa <= pc2_i when (ctrl_i(ctrl_alu_opa_mux_c) = '1') else rs1_i; -- operand a (first ALU input operand), only required for arithmetic ops |
opb <= imm_i when (ctrl_i(ctrl_alu_opb_mux_c) = '1') else rs2_i; -- operand b (second ALU input operand) |
|
228,24 → 243,24
|
-- Co-Processor 0: Shifter (CPU Core ISA) -------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_shifter_inst: neorv32_cpu_cp_shifter |
generic map ( |
FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations |
) |
port map ( |
-- global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
ctrl_i => ctrl_i, -- main control bus |
start_i => cp_start(0), -- trigger operation |
-- data input -- |
rs1_i => rs1_i, -- rf source 1 |
rs2_i => rs2_i, -- rf source 2 |
imm_i => imm_i, -- immediate |
-- result and status -- |
res_o => cp_result(0), -- operation result |
valid_o => cp_valid(0) -- data output valid |
); |
neorv32_cpu_cp_shifter_inst: neorv32_cpu_cp_shifter |
generic map ( |
FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations |
) |
port map ( |
-- global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
ctrl_i => ctrl_i, -- main control bus |
start_i => cp_start(0), -- trigger operation |
-- data input -- |
rs1_i => rs1_i, -- rf source 1 |
rs2_i => rs2_i, -- rf source 2 |
imm_i => imm_i, -- immediate |
-- result and status -- |
res_o => cp_result(0), -- operation result |
valid_o => cp_valid(0) -- data output valid |
); |
|
|
-- Co-Processor 1: Integer Multiplication/Division ('M' Extension) ------------------------ |
279,7 → 294,7
end generate; |
|
|
-- Co-Processor 2: Bit-Manipulation Unit ('Zbb' Extension) -------------------------------- |
-- Co-Processor 2: Bit-Manipulation Unit ('B'/'Zbb' Extension) ---------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_bitmanip_inst_true: |
if (CPU_EXTENSION_RISCV_Zbb = true) generate |
294,7 → 309,7
ctrl_i => ctrl_i, -- main control bus |
start_i => cp_start(2), -- trigger operation |
-- data input -- |
cmp_i => cmp_i, -- comparator status |
cmp_i => cmp, -- comparator status |
rs1_i => rs1_i, -- rf source 1 |
rs2_i => rs2_i, -- rf source 2 |
-- result and status -- |
322,7 → 337,7
ctrl_i => ctrl_i, -- main control bus |
start_i => cp_start(3), -- trigger operation |
-- data input -- |
cmp_i => cmp_i, -- comparator status |
cmp_i => cmp, -- comparator status |
rs1_i => rs1_i, -- rf source 1 |
rs2_i => rs2_i, -- rf source 2 |
-- result and status -- |
/neorv32_cpu_control.vhd
184,7 → 184,6
-- instruction decoding helper logic -- |
type decode_aux_t is record |
alu_immediate : std_ulogic; |
rs1_is_r0 : std_ulogic; |
is_atomic_lr : std_ulogic; |
is_atomic_sc : std_ulogic; |
is_float_op : std_ulogic; |
233,8 → 232,6
irq_buf : std_ulogic_vector(interrupt_width_c-1 downto 0); |
irq_fire : std_ulogic; -- set if there is a valid source in the interrupt buffer |
exc_ack : std_ulogic; -- acknowledge all exceptions |
irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt |
irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0); |
cause : std_ulogic_vector(6 downto 0); -- trap ID for mcause CSR |
cause_nxt : std_ulogic_vector(6 downto 0); |
db_irq_fire : std_ulogic; -- set if there is a valid IRQ source in the "enter debug mode" trap buffer |
271,8 → 268,6
addr : std_ulogic_vector(11 downto 0); -- csr address |
we : std_ulogic; -- csr write enable |
we_nxt : std_ulogic; |
re : std_ulogic; -- csr read enable |
re_nxt : std_ulogic; |
wdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr write data |
rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data |
-- |
279,7 → 274,6
mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W) |
mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/W) |
mstatus_mpp : std_ulogic_vector(1 downto 0); -- mstatus.MPP: machine previous privilege mode |
mstatus_tw : std_ulogic; -- mstatus:TW trigger illegal instruction exception if WFI is executed outside of M-mode |
-- |
mie_msie : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W) |
mie_meie : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W) |
471,6 → 465,8
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => ipb.clear, -- sync reset, high-active |
level_o => open, |
half_o => open, |
-- write port -- |
wdata_i => ipb.wdata, -- write data |
we_i => ipb.we, -- write enable |
714,7 → 710,7
end if; |
-- |
execute_engine.state <= execute_engine.state_nxt; |
execute_engine.sleep <= execute_engine.sleep_nxt and (not debug_ctrl.running); -- do not execute when in debug mode |
execute_engine.sleep <= execute_engine.sleep_nxt; |
execute_engine.branched <= execute_engine.branched_nxt; |
-- |
execute_engine.state_prev <= execute_engine.state; |
775,6 → 771,10
begin |
-- signals from execute engine -- |
ctrl_o <= ctrl; |
-- prevent commits if illegal instruction -- |
ctrl_o(ctrl_rf_wb_en_c) <= ctrl(ctrl_rf_wb_en_c) and (not trap_ctrl.exc_buf(exception_iillegal_c)); |
ctrl_o(ctrl_bus_rd_c) <= ctrl(ctrl_bus_rd_c) and (not trap_ctrl.exc_buf(exception_iillegal_c)); |
ctrl_o(ctrl_bus_wr_c) <= ctrl(ctrl_bus_wr_c) and (not trap_ctrl.exc_buf(exception_iillegal_c)); |
-- current privilege level -- |
ctrl_o(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c) <= csr.privilege_rd; |
-- register addresses -- |
812,7 → 812,6
begin |
-- defaults -- |
decode_aux.alu_immediate <= '0'; |
decode_aux.rs1_is_r0 <= '0'; |
decode_aux.is_atomic_lr <= '0'; |
decode_aux.is_atomic_sc <= '0'; |
decode_aux.is_float_op <= '0'; |
824,9 → 823,6
-- is immediate ALU operation? -- |
decode_aux.alu_immediate <= not execute_engine.i_reg(instr_opcode_msb_c-1); |
|
-- is rs1 == r0? -- |
decode_aux.rs1_is_r0 <= not or_reduce_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c)); |
|
-- is atomic load-reservate/store-conditional? -- |
if (CPU_EXTENSION_RISCV_A = true) and (execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "11") then -- valid atomic sub-opcode |
decode_aux.is_atomic_lr <= not execute_engine.i_reg(instr_funct5_lsb_c); |
892,7 → 888,7
-- Execute Engine FSM Comb ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
execute_engine_fsm_comb: process(execute_engine, debug_ctrl, trap_ctrl, decode_aux, fetch_engine, cmd_issue, |
csr, ctrl, csr_acc_valid, alu_idone_i, bus_d_wait_i, excl_state_i) |
csr, ctrl, alu_idone_i, bus_d_wait_i, excl_state_i) |
variable opcode_v : std_ulogic_vector(6 downto 0); |
begin |
-- arbiter defaults -- |
924,7 → 920,6
|
-- CSR access -- |
csr.we_nxt <= '0'; |
csr.re_nxt <= '0'; |
|
-- CONTROL DEFAULTS -- |
ctrl_nxt <= (others => '0'); -- default: all off |
1080,7 → 1075,7
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_alu_opa_mux_c) <= '1'; -- ALU.OPA = PC (for AUIPC only) |
ctrl_nxt(ctrl_alu_opb_mux_c) <= '1'; -- use IMM as ALU.OPB |
ctrl_nxt(ctrl_alu_arith_c) <= alu_arith_cmd_addsub_c; -- actual ALU operation = ADD |
ctrl_nxt(ctrl_alu_arith_c) <= alu_arith_cmd_addsub_c; -- ADD |
ctrl_nxt(ctrl_alu_logic1_c downto ctrl_alu_logic0_c) <= alu_logic_cmd_movb_c; -- MOVB |
if (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_lui_c(5)) then -- LUI |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_logic_c; -- actual ALU operation = MOVB |
1127,7 → 1122,6
when opcode_syscsr_c => -- system/csr access |
-- ------------------------------------------------------------ |
if (CPU_EXTENSION_RISCV_Zicsr = true) then |
csr.re_nxt <= csr_acc_valid; -- always read CSR if valid access, only relevant for CSR-instructions |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system/environment |
execute_engine.state_nxt <= SYS_ENV; |
else -- CSR access |
1158,14 → 1152,20
-- ------------------------------------------------------------ |
execute_engine.state_nxt <= SYS_WAIT; -- default |
case decode_aux.sys_env_cmd is -- use a simplified input here (with permanent zeros) |
when funct12_ecall_c => trap_ctrl.env_call <= '1'; -- ECALL |
when funct12_ebreak_c => trap_ctrl.break_point <= '1'; -- EBREAK |
when funct12_wfi_c => execute_engine.sleep_nxt <= '1'; -- WFI |
when funct12_mret_c => -- MRET |
when funct12_ecall_c => trap_ctrl.env_call <= '1'; -- ECALL |
when funct12_ebreak_c => trap_ctrl.break_point <= '1'; -- EBREAK |
when funct12_wfi_c => -- WFI |
if (CPU_EXTENSION_RISCV_DEBUG = true) and |
((debug_ctrl.running = '1') or (csr.dcsr_step = '1')) then -- act as NOP when in debug-mode or during single-stepping |
NULL; -- executed as NOP |
else |
execute_engine.sleep_nxt <= '1'; -- go to sleep mode |
end if; |
when funct12_mret_c => -- MRET |
if (csr.priv_m_mode = '1') then -- only allowed in M-mode |
execute_engine.state_nxt <= TRAP_EXIT; |
else |
NULL; |
NULL; -- executed as NOP |
end if; |
when funct12_dret_c => -- DRET |
if (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1') then -- only allowed in debug-mode |
1172,9 → 1172,9
execute_engine.state_nxt <= TRAP_EXIT; |
debug_ctrl.dret <= '1'; |
else |
NULL; |
NULL; -- executed as NOP |
end if; |
when others => NULL; -- undefined |
when others => NULL; -- undefined / execute as NOP |
end case; |
|
|
1183,9 → 1183,9
-- CSR write access -- |
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
when funct3_csrrw_c | funct3_csrrwi_c => -- CSRRW(I) |
csr.we_nxt <= csr_acc_valid; -- always write CSR if valid access |
csr.we_nxt <= '1'; -- always write CSR |
when funct3_csrrs_c | funct3_csrrsi_c | funct3_csrrc_c | funct3_csrrci_c => -- CSRRS(I) / CSRRC(I) |
csr.we_nxt <= (not decode_aux.rs1_is_r0) and csr_acc_valid; -- write CSR if rs1/imm is not zero and if valid access |
csr.we_nxt <= or_reduce_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c)); -- write CSR if rs1/imm is not zero |
when others => -- invalid |
csr.we_nxt <= '0'; |
end case; |
1274,8 → 1274,7
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 / exception -- |
if (trap_ctrl.env_start = '1') and -- only abort if BUS EXCEPTION |
((trap_ctrl.cause = trap_lma_c) or (trap_ctrl.cause = trap_lbe_c) or (trap_ctrl.cause = trap_sma_c) or (trap_ctrl.cause = trap_sbe_c)) then |
if (trap_ctrl.env_start = '1') and (trap_ctrl.cause(6 downto 5) = "00") then -- only abort if SYNC EXCEPTION (from bus) / no IRQs and NOT DEBUG-MODE-related |
execute_engine.state_nxt <= SYS_WAIT; |
elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction |
-- data write-back -- |
1318,23 → 1317,23
end if; |
|
-- check CSR access -- |
csr_acc_valid <= '0'; -- default = invalid access |
case csr.addr is |
|
-- floating-point CSRs -- |
when csr_fflags_c | csr_frm_c | csr_fcsr_c => |
if (CPU_EXTENSION_RISCV_Zfinx = true) then -- FPU implemented? |
csr_acc_valid <= '1'; -- full access for everyone |
else |
NULL; |
end if; |
csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- full access for everyone if FPU implemented |
|
-- machine trap setup & handling -- |
when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c | csr_mip_c | csr_mtval_c => |
when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c | csr_mip_c | csr_mtval_c | |
csr_mcycle_c | csr_mcycleh_c | csr_minstret_c | csr_minstreth_c | csr_mcountinhibit_c => |
-- NOTE: MISA, MIP and MTVAL are read-only in the NEORV32 but we do not cause an exception here for compatibility. |
-- Machine-level code should read-back those CSRs after writing them to realize they are read-only. |
-- Machine-level code should read-back those CSRs after writing them to realize they are read-only. |
csr_acc_valid <= csr.priv_m_mode; -- M-mode only |
|
-- machine information registers, read-only -- |
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c => |
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only |
|
when csr_mcounteren_c | csr_menvcfg_c | csr_menvcfgh_c => -- only available if U mode is implemented |
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(CPU_EXTENSION_RISCV_U); |
|
1349,11 → 1348,7
csr_pmpaddr56_c | csr_pmpaddr57_c | csr_pmpaddr58_c | csr_pmpaddr59_c | csr_pmpaddr60_c | csr_pmpaddr61_c | csr_pmpaddr62_c | csr_pmpaddr63_c | |
csr_pmpcfg0_c | csr_pmpcfg1_c | csr_pmpcfg2_c | csr_pmpcfg3_c | csr_pmpcfg4_c | csr_pmpcfg5_c | csr_pmpcfg6_c | csr_pmpcfg7_c | -- configuration |
csr_pmpcfg8_c | csr_pmpcfg9_c | csr_pmpcfg10_c | csr_pmpcfg11_c | csr_pmpcfg12_c | csr_pmpcfg13_c | csr_pmpcfg14_c | csr_pmpcfg15_c => |
if (PMP_NUM_REGIONS > 0) then |
csr_acc_valid <= csr.priv_m_mode; -- M-mode only |
else |
NULL; |
end if; |
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(PMP_NUM_REGIONS > 0)); -- M-mode only |
|
-- hardware performance monitors (HPM) -- |
when csr_mhpmcounter3_c | csr_mhpmcounter4_c | csr_mhpmcounter5_c | csr_mhpmcounter6_c | csr_mhpmcounter7_c | csr_mhpmcounter8_c | -- counter LOW |
1371,40 → 1366,24
csr_mhpmevent15_c | csr_mhpmevent16_c | csr_mhpmevent17_c | csr_mhpmevent18_c | csr_mhpmevent19_c | csr_mhpmevent20_c | |
csr_mhpmevent21_c | csr_mhpmevent22_c | csr_mhpmevent23_c | csr_mhpmevent24_c | csr_mhpmevent25_c | csr_mhpmevent26_c | |
csr_mhpmevent27_c | csr_mhpmevent28_c | csr_mhpmevent29_c | csr_mhpmevent30_c | csr_mhpmevent31_c => |
if (HPM_NUM_CNTS > 0) then |
csr_acc_valid <= csr.priv_m_mode; -- M-mode only |
else |
NULL; |
end if; |
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(HPM_NUM_CNTS > 0)); -- M-mode only |
|
-- counters/timers -- |
when csr_mcycle_c | csr_mcycleh_c | csr_minstret_c | csr_minstreth_c => |
csr_acc_valid <= csr.priv_m_mode; -- M-mode only |
when csr_cycle_c | csr_cycleh_c => |
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- M-mode, U-mode if authorized, read-only |
when csr_instret_c | csr_instreth_c => |
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- M-mode, U-mode if authorized, read-only |
when csr_time_c | csr_timeh_c => |
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- M-mode, U-mode if authorized, read-only |
-- user-level counters/timers -- |
when csr_cycle_c | csr_cycleh_c | csr_instret_c | csr_instreth_c | csr_time_c | csr_timeh_c => |
case csr.addr(1 downto 0) is |
when "00" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy); -- cyle[h]: M-mode, U-mode if authorized, read-only |
when "01" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_tm); -- time[h]: M-mode, U-mode if authorized, read-only |
when "10" => csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_ir); -- instret[h]: M-mode, U-mode if authorized, read-only |
when others => csr_acc_valid <= '0'; |
end case; |
|
when csr_mcountinhibit_c => |
csr_acc_valid <= csr.priv_m_mode; -- M-mode only |
|
-- machine information registers, read-only -- |
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c => |
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only |
|
-- debug mode CSRs -- |
when csr_dcsr_c | csr_dpc_c | csr_dscratch0_c => |
if (CPU_EXTENSION_RISCV_DEBUG = true) then |
csr_acc_valid <= debug_ctrl.running; -- access only in debug-mode |
else |
NULL; |
end if; |
csr_acc_valid <= debug_ctrl.running and bool_to_ulogic_f(CPU_EXTENSION_RISCV_DEBUG); -- access only in debug-mode |
|
-- undefined / not implemented -- |
when others => |
NULL; -- invalid access |
csr_acc_valid <= '0'; -- invalid access |
end case; |
end process csr_access_check; |
|
1414,7 → 1393,7
illegal_instruction_check: process(execute_engine, decode_aux, csr, csr_acc_valid, debug_ctrl) |
variable opcode_v : std_ulogic_vector(6 downto 0); |
begin |
-- illegal instructions are checked in the EXECUTE stage |
-- illegal instructions are checked in the EXECUTE state |
-- the execute engine should not commit any illegal instruction |
if (execute_engine.state = EXECUTE) then |
-- defaults -- |
1587,7 → 1566,7
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_ebreak_c) or -- EBREAK |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_mret_c) and (csr.priv_m_mode = '1')) or -- MRET (only allowed in M-mode) |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_dret_c) and (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1')) or -- DRET (only allowed in D-mode) |
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) and ((csr.priv_m_mode = '1') or (csr.mstatus_tw = '0'))) then -- WFI allowed in M-mode or if mstatus.TW=0 |
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = funct12_wfi_c) then -- WFI (always allowed to execute) |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
1646,9 → 1625,8
trap_ctrl.exc_buf <= (others => '0'); |
trap_ctrl.irq_buf <= (others => '0'); |
trap_ctrl.exc_ack <= '0'; |
trap_ctrl.irq_ack <= (others => '0'); |
trap_ctrl.env_start <= '0'; |
trap_ctrl.cause <= (others => def_rst_val_c); |
trap_ctrl.cause <= (others => '0'); |
elsif rising_edge(clk_i) then |
if (CPU_EXTENSION_RISCV_Zicsr = true) then |
|
1694,7 → 1672,7
trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and mtime_irq_i; |
-- interrupt queue: NEORV32-specific fast interrupts |
for i in 0 to 15 loop |
trap_ctrl.irq_buf(interrupt_firq_0_c+i) <= csr.mie_firqe(i) and (trap_ctrl.irq_buf(interrupt_firq_0_c+i) or firq_i(i)) and (not trap_ctrl.irq_ack(interrupt_firq_0_c+i)); |
trap_ctrl.irq_buf(interrupt_firq_0_c+i) <= csr.mie_firqe(i) and firq_i(i); |
end loop; |
|
-- trap control -- |
1701,15 → 1679,13
if (trap_ctrl.env_start = '0') then -- no started trap handler |
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- trap triggered! |
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP_ENTER))) then -- fire IRQs in EXECUTE or TRAP state only to continue execution even on permanent IRQ |
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program (for mcause csr) |
trap_ctrl.exc_ack <= '1'; -- clear exceptions (no ack mask: these have highest priority and are always evaluated first!) |
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- clear interrupt with ACK mask |
trap_ctrl.env_start <= '1'; -- now execute engine can start trap handler |
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program (for mcause csr) |
trap_ctrl.exc_ack <= '1'; -- clear exceptions (no ack mask: these have highest priority and are always evaluated first!) |
trap_ctrl.env_start <= '1'; -- now execute engine can start trap handler |
end if; |
else -- trap waiting to get started |
if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine |
trap_ctrl.exc_ack <= '0'; |
trap_ctrl.irq_ack <= (others => '0'); |
trap_ctrl.env_start <= '0'; |
end if; |
end if; |
1731,8 → 1707,7
trap_priority: process(trap_ctrl) |
begin |
-- defaults -- |
trap_ctrl.cause_nxt <= (others => '0'); |
trap_ctrl.irq_ack_nxt <= (others => '0'); -- used for internal IRQ queues only |
trap_ctrl.cause_nxt <= (others => '0'); |
|
-- NOTE: Synchronous exceptions (from trap_ctrl.exc_buf) have higher priority than asynchronous |
-- exceptions (from trap_ctrl.irq_buf). |
1810,91 → 1785,73
-- ---------------------------------------------------------------------------------------- |
|
-- custom FAST interrupt requests -- |
-- here we do need a specific acknowledge mask for the FIRQs only since they are edge-triggered and internally buffered |
|
-- interrupt: 1.16 fast interrupt channel 0 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_0_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq0_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_0_c) <= '1'; |
|
-- interrupt: 1.17 fast interrupt channel 1 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_1_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq1_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_1_c) <= '1'; |
|
-- interrupt: 1.18 fast interrupt channel 2 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_2_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq2_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_2_c) <= '1'; |
|
-- interrupt: 1.19 fast interrupt channel 3 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_3_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq3_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_3_c) <= '1'; |
|
-- interrupt: 1.20 fast interrupt channel 4 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_4_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq4_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_4_c) <= '1'; |
|
-- interrupt: 1.21 fast interrupt channel 5 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_5_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq5_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_5_c) <= '1'; |
|
-- interrupt: 1.22 fast interrupt channel 6 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_6_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq6_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_6_c) <= '1'; |
|
-- interrupt: 1.23 fast interrupt channel 7 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_7_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq7_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_7_c) <= '1'; |
|
-- interrupt: 1.24 fast interrupt channel 8 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_8_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq8_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_8_c) <= '1'; |
|
-- interrupt: 1.25 fast interrupt channel 9 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_9_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq9_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_9_c) <= '1'; |
|
-- interrupt: 1.26 fast interrupt channel 10 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_10_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq10_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_10_c) <= '1'; |
|
-- interrupt: 1.27 fast interrupt channel 11 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_11_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq11_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_11_c) <= '1'; |
|
-- interrupt: 1.28 fast interrupt channel 12 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_12_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq12_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_12_c) <= '1'; |
|
-- interrupt: 1.29 fast interrupt channel 13 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_13_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq13_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_13_c) <= '1'; |
|
-- interrupt: 1.30 fast interrupt channel 14 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_14_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq14_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_14_c) <= '1'; |
|
-- interrupt: 1.31 fast interrupt channel 15 -- |
elsif (trap_ctrl.irq_buf(interrupt_firq_15_c) = '1') then |
trap_ctrl.cause_nxt <= trap_firq15_c; |
trap_ctrl.irq_ack_nxt(interrupt_firq_15_c) <= '1'; |
|
|
-- standard RISC-V interrupts -- |
-- these will stay asserted until explicitly ACKed by the software - no irq_ack_nxt required |
|
-- interrupt: 1.11 machine external interrupt -- |
elsif (trap_ctrl.irq_buf(interrupt_mext_irq_c) = '1') then |
1940,6 → 1897,7
-- Control and Status Registers - Write Access -------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
csr_write_access: process(rstn_i, clk_i) |
variable cause_v : std_ulogic_vector(6 downto 0); |
begin |
-- NOTE: If <dedicated_reset_c> = true then <def_rst_val_c> evaluates to '-'. Register that reset to <def_rst_val_c> do |
-- NOT actually have a real reset by default (def_rst_val_c = '-') and have to be explicitly initialized by software! |
1950,7 → 1908,6
csr.mstatus_mie <= '0'; |
csr.mstatus_mpie <= '0'; |
csr.mstatus_mpp <= (others => '0'); |
csr.mstatus_tw <= '0'; |
csr.privilege <= priv_mode_m_c; -- start in MACHINE mode |
csr.mie_msie <= def_rst_val_c; |
csr.mie_meie <= def_rst_val_c; |
1994,7 → 1951,7
-- -------------------------------------------------------------------------------- |
-- CSR access by application software |
-- -------------------------------------------------------------------------------- |
if (csr.we = '1') then -- manual update |
if (csr.we = '1') and (trap_ctrl.exc_buf(exception_iillegal_c) = '0') then -- manual update if not illegal instruction |
|
-- user floating-point CSRs -- |
-- -------------------------------------------------------------------- |
2023,7 → 1980,6
if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented |
csr.mstatus_mpp(0) <= csr.wdata(11) or csr.wdata(12); |
csr.mstatus_mpp(1) <= csr.wdata(11) or csr.wdata(12); |
csr.mstatus_tw <= csr.wdata(21); |
end if; |
end if; |
-- R/W: mie - machine interrupt enable register -- |
2107,8 → 2063,8
if (csr.addr(11 downto 5) = csr_cnt_setup_c) then -- counter configuration CSR class |
-- R/W: mcountinhibit - machine counter-inhibit register -- |
if (csr.addr(4 downto 0) = csr_mcountinhibit_c(4 downto 0)) then |
csr.mcountinhibit_cy <= csr.wdata(0); -- enable auto-increment of [m]cycle[h] counter |
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter |
csr.mcountinhibit_cy <= csr.wdata(0); -- enable auto-increment of [m]cycle[h] counter |
csr.mcountinhibit_ir <= csr.wdata(2); -- enable auto-increment of [m]instret[h] counter |
if (HPM_NUM_CNTS > 0) then -- any HPMs available? |
csr.mcountinhibit_hpm <= csr.wdata(csr.mcountinhibit_hpm'left+3 downto 3); -- enable auto-increment of [m]hpmcounter*[h] counter |
end if; |
2134,8 → 2090,8
csr.dcsr_step <= csr.wdata(2); |
if (CPU_EXTENSION_RISCV_U = true) then -- user mode implemented |
csr.dcsr_ebreaku <= csr.wdata(12); |
csr.dcsr_prv(0) <= csr.wdata(1) or csr.wdata(0); |
csr.dcsr_prv(1) <= csr.wdata(1) or csr.wdata(0); |
csr.dcsr_prv(0) <= csr.wdata(1) or csr.wdata(0); |
csr.dcsr_prv(1) <= csr.wdata(1) or csr.wdata(0); |
else -- only machine mode is available |
csr.dcsr_prv <= priv_mode_m_c; |
end if; |
2181,11 → 2137,13
end if; |
|
-- trap value -- |
case trap_ctrl.cause is |
cause_v := trap_ctrl.cause; |
cause_v(5) := '0'; -- bit 5 is always zero here (= normal trapping), so we do not need to check that again |
case cause_v is |
when trap_ima_c | trap_iba_c => -- misaligned instruction address OR instruction access error |
csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- address of faulting instruction |
when trap_brk_c => -- breakpoint |
csr.mtval <= execute_engine.last_pc; -- address of breakpoint instruction |
csr.mtval <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- address of breakpoint instruction |
when trap_lma_c | trap_lbe_c | trap_sma_c | trap_sbe_c => -- misaligned load/store address OR load/store access error |
csr.mtval <= mar_i; -- faulting data access address |
when trap_iil_c => -- illegal instruction |
2257,7 → 2215,6
if (CPU_EXTENSION_RISCV_U = false) then |
csr.privilege <= priv_mode_m_c; |
csr.mstatus_mpp <= priv_mode_m_c; |
csr.mstatus_tw <= '0'; |
csr.mcounteren_cy <= '0'; |
csr.mcounteren_tm <= '0'; |
csr.mcounteren_ir <= '0'; |
2494,7 → 2451,7
cnt_event_nxt(hpmcnt_event_cir_c) <= '1' when (execute_engine.state = EXECUTE) and (execute_engine.is_ci = '1') else '0'; -- retired compressed instruction |
cnt_event_nxt(hpmcnt_event_wait_if_c) <= '1' when (fetch_engine.state = IFETCH_ISSUE) and (fetch_engine.state_prev = IFETCH_ISSUE) else '0'; -- instruction fetch memory wait cycle |
cnt_event_nxt(hpmcnt_event_wait_ii_c) <= '1' when (execute_engine.state = DISPATCH) and (execute_engine.state_prev = DISPATCH) else '0'; -- instruction issue wait cycle |
cnt_event_nxt(hpmcnt_event_wait_mc_c) <= '1' when (execute_engine.state = ALU_WAIT) and (execute_engine.state_prev = ALU_WAIT) else '0'; -- multi-cycle alu-operation wait cycle |
cnt_event_nxt(hpmcnt_event_wait_mc_c) <= '1' when (execute_engine.state = ALU_WAIT) else '0'; -- multi-cycle alu-operation wait cycle |
|
cnt_event_nxt(hpmcnt_event_load_c) <= '1' when (execute_engine.state = LOADSTORE_1) and (ctrl(ctrl_bus_rd_c) = '1') else '0'; -- load operation |
cnt_event_nxt(hpmcnt_event_store_c) <= '1' when (execute_engine.state = LOADSTORE_1) and (ctrl(ctrl_bus_wr_c) = '1') else '0'; -- store operation |
2514,9 → 2471,8
variable csr_addr_v : std_ulogic_vector(11 downto 0); |
begin |
if rising_edge(clk_i) then |
csr.re <= csr.re_nxt; -- read access? |
csr.rdata <= (others => '0'); -- default output |
if (CPU_EXTENSION_RISCV_Zicsr = true) and (csr.re = '1') then |
if (CPU_EXTENSION_RISCV_Zicsr = true) then |
csr_addr_v(11 downto 10) := csr.addr(11 downto 10); |
csr_addr_v(09 downto 08) := (others => csr.addr(8)); -- !!! WARNING: MACHINE (11) and USER (00) registers ONLY !!! |
csr_addr_v(07 downto 00) := csr.addr(07 downto 00); |
2538,7 → 2494,6
csr.rdata(07) <= csr.mstatus_mpie; -- MPIE |
csr.rdata(11) <= csr.mstatus_mpp(0); -- MPP: machine previous privilege mode low |
csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high |
csr.rdata(21) <= csr.mstatus_tw; -- TW: WFI timeout wait |
when csr_misa_c => -- misa (r/-): ISA and extensions |
csr.rdata(00) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_A); -- A CPU extension |
csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension |
2797,7 → 2752,7
when csr_marchid_c => csr.rdata(4 downto 0) <= "10011"; -- marchid (r/-): arch ID - official RISC-V open-source arch ID |
when csr_mimpid_c => csr.rdata <= hw_version_c; -- mimpid (r/-): implementation ID -- NEORV32 hardware version |
when csr_mhartid_c => csr.rdata <= std_ulogic_vector(to_unsigned(HW_THREAD_ID, 32)); -- mhartid (r/-): hardware thread ID |
-- when csr_mconfigptr_c => NULL; -- mconfigptr (r/-): machine configuration pointer register, implemented but not assigned yet |
-- when csr_mconfigptr_c => NULL; -- mconfigptr (r/-): machine configuration pointer register, implemented but always zero |
|
-- debug mode CSRs -- |
-- -------------------------------------------------------------------- |
2808,7 → 2763,7
-- undefined/unavailable -- |
-- -------------------------------------------------------------------- |
when others => |
NULL; -- not implemented, read as zero if read access is granted |
NULL; -- not implemented, read as zero |
|
end case; |
end if; |
/neorv32_cpu_decompressor.vhd
116,26 → 116,24
|
when "000" => -- Illegal_instruction, C.ADDI4SPN |
-- ---------------------------------------------------------------------------------------------------------- |
if (ci_instr16_i(12 downto 2) = "00000000000") then -- "official illegal instruction" |
ci_illegal_o <= '1'; |
else |
-- C.ADDI4SPN |
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c; |
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "00010"; -- stack pointer |
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c); |
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c; |
ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c) <= (others => '0'); -- zero extend |
ci_instr32_o(instr_imm12_lsb_c + 0) <= '0'; |
ci_instr32_o(instr_imm12_lsb_c + 1) <= '0'; |
ci_instr32_o(instr_imm12_lsb_c + 2) <= ci_instr16_i(6); |
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5); |
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(11); |
ci_instr32_o(instr_imm12_lsb_c + 5) <= ci_instr16_i(12); |
ci_instr32_o(instr_imm12_lsb_c + 6) <= ci_instr16_i(7); |
ci_instr32_o(instr_imm12_lsb_c + 7) <= ci_instr16_i(8); |
ci_instr32_o(instr_imm12_lsb_c + 8) <= ci_instr16_i(9); |
ci_instr32_o(instr_imm12_lsb_c + 9) <= ci_instr16_i(10); |
end if; |
-- C.ADDI4SPN |
ci_instr32_o(instr_opcode_msb_c downto instr_opcode_lsb_c) <= opcode_alui_c; |
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "00010"; -- stack pointer |
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c); |
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_subadd_c; |
ci_instr32_o(instr_imm12_msb_c downto instr_imm12_lsb_c) <= (others => '0'); -- zero extend |
ci_instr32_o(instr_imm12_lsb_c + 0) <= '0'; |
ci_instr32_o(instr_imm12_lsb_c + 1) <= '0'; |
ci_instr32_o(instr_imm12_lsb_c + 2) <= ci_instr16_i(6); |
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5); |
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(11); |
ci_instr32_o(instr_imm12_lsb_c + 5) <= ci_instr16_i(12); |
ci_instr32_o(instr_imm12_lsb_c + 6) <= ci_instr16_i(7); |
ci_instr32_o(instr_imm12_lsb_c + 7) <= ci_instr16_i(8); |
ci_instr32_o(instr_imm12_lsb_c + 8) <= ci_instr16_i(9); |
ci_instr32_o(instr_imm12_lsb_c + 9) <= ci_instr16_i(10); |
-- |
ci_illegal_o <= not or_reduce_f(ci_instr16_i(12 downto 2)); -- 12:2 = "00000000000" is official illegal instruction |
|
when "010" | "011" => -- C.LW / C.FLW |
-- ---------------------------------------------------------------------------------------------------------- |
173,6 → 171,7
|
when others => -- undefined |
-- ---------------------------------------------------------------------------------------------------------- |
ci_instr32_o <= (others => '-'); |
ci_illegal_o <= '1'; |
|
end case; |
233,9 → 232,6
ci_instr32_o(instr_imm12_lsb_c + 3) <= ci_instr16_i(5); |
ci_instr32_o(instr_imm12_lsb_c + 4) <= ci_instr16_i(6); |
ci_instr32_o(instr_imm12_lsb_c + 5) <= ci_instr16_i(12); |
if (ci_instr16_i(ci_rd_5_msb_c downto ci_rd_5_lsb_c) = "00000") then -- HINT |
ci_illegal_o <= '1'; |
end if; |
|
when "011" => -- C.LUI / C.ADDI16SP |
-- ---------------------------------------------------------------------------------------------------------- |
347,6 → 343,7
|
when others => -- undefined |
-- ---------------------------------------------------------------------------------------------------------- |
ci_instr32_o <= (others => '-'); |
ci_illegal_o <= '1'; |
|
end case; |
439,6 → 436,7
|
when others => -- undefined |
-- ---------------------------------------------------------------------------------------------------------- |
ci_instr32_o <= (others => '-'); |
ci_illegal_o <= '1'; |
|
end case; |
445,7 → 443,8
|
when others => -- not a compressed instruction |
-- ---------------------------------------------------------------------------------------------------------- |
NULL; |
ci_instr32_o <= (others => '-'); |
ci_illegal_o <= '0'; |
|
end case; |
end process decompressor; |
/neorv32_cpu_regfile.vhd
4,12 → 4,12
-- # General purpose data register file. 32 entries (= 1024 bit) for normal mode (RV32I), # |
-- # 16 entries (= 512 bit) for embedded mode (RV32E) when RISC-V "E" extension is enabled. # |
-- # # |
-- # Register zero (r0/x0) is a "normal" physical reg that has to be initialized to zero by the # |
-- # CPU control system. For normal operations register zero cannot be written. # |
-- # Register zero (r0/x0) is a "normal" physical register that has to be initialized to zero by # |
-- # the early boot code. Register zero is always set to zero when written. # |
-- # # |
-- # The register file uses synchronous read accesses and a *single* (multiplexed) address port # |
-- # for writing and reading rs1 and a single read-only port for rs2. Therefore, the whole # |
-- # register file can be mapped to a single true dual-port block RAM. # |
-- # for writing and reading rd/rs1 and a single read-only port for rs2. Therefore, the whole # |
-- # register file can be mapped to a single true-dual-port block RAM. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
62,8 → 62,7
alu_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU result |
-- data output -- |
rs1_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operand 1 |
rs2_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operand 2 |
cmp_o : out std_ulogic_vector(1 downto 0) -- comparator status |
rs2_o : out std_ulogic_vector(data_width_c-1 downto 0) -- operand 2 |
); |
end neorv32_cpu_regfile; |
|
81,10 → 80,6
signal opb_addr : std_ulogic_vector(4 downto 0); -- rs2 address |
signal rs1, rs2 : std_ulogic_vector(data_width_c-1 downto 0); -- read data |
|
-- comparator -- |
signal cmp_opx : std_ulogic_vector(data_width_c downto 0); |
signal cmp_opy : std_ulogic_vector(data_width_c downto 0); |
|
begin |
|
-- Data Input Mux ------------------------------------------------------------------------- |
137,13 → 132,4
rs2_o <= rs2; |
|
|
-- Comparator Unit (for conditional branches) --------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
cmp_opx <= (rs1(rs1'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs1; |
cmp_opy <= (rs2(rs2'left) and (not ctrl_i(ctrl_alu_unsigned_c))) & rs2; |
|
cmp_o(cmp_equal_c) <= '1' when (rs1 = rs2) else '0'; |
cmp_o(cmp_less_c) <= '1' when (signed(cmp_opx) < signed(cmp_opy)) else '0'; |
|
|
end neorv32_cpu_regfile_rtl; |
/neorv32_fifo.vhd
52,6 → 52,7
rstn_i : in std_ulogic; -- async reset, low-active |
clear_i : in std_ulogic; -- sync reset, high-active |
level_o : out std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- fill level |
half_o : out std_ulogic; -- FIFO is at least half full |
-- write port -- |
wdata_i : in std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- write data |
we_i : in std_ulogic; -- write enable |
83,6 → 84,8
end record; |
signal fifo : fifo_t; |
|
signal level_diff : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
93,8 → 96,8
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
fifo.re <= re_i when (FIFO_SAFE = false) else (re_i and fifo.avail); |
fifo.we <= we_i when (FIFO_SAFE = false) else (we_i and fifo.free); |
fifo.re <= re_i when (FIFO_SAFE = false) else (re_i and fifo.avail); -- read only if data available |
fifo.we <= we_i when (FIFO_SAFE = false) else (we_i and fifo.free); -- write only if space left |
|
|
-- FIFO Control --------------------------------------------------------------------------- |
126,7 → 129,8
fifo.empty <= '1' when (fifo.r_pnt(fifo.r_pnt'left) = fifo.w_pnt(fifo.w_pnt'left)) and (fifo.match = '1') else '0'; |
fifo.free <= not fifo.full; |
fifo.avail <= not fifo.empty; |
fifo.level <= std_ulogic_vector(to_unsigned(FIFO_DEPTH, fifo.level'length)) when (fifo.full = '1') else std_ulogic_vector(unsigned(fifo.w_pnt) - unsigned(fifo.r_pnt)); |
level_diff <= std_ulogic_vector(unsigned(fifo.w_pnt) - unsigned(fifo.r_pnt)); |
fifo.level <= std_ulogic_vector(to_unsigned(FIFO_DEPTH, fifo.level'length)) when (fifo.full = '1') else level_diff; |
|
-- status output -- |
level_o <= fifo.level; |
133,7 → 137,17
free_o <= fifo.free; |
avail_o <= fifo.avail; |
|
fifo_half_level: |
if (FIFO_DEPTH > 1) generate |
half_o <= level_diff(level_diff'left-1) or fifo.full; |
end generate; |
|
fifo_half_level_simple: |
if (FIFO_DEPTH = 1) generate |
half_o <= fifo.full; |
end generate; |
|
|
-- FIFO Memory ---------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
fifo_memory_write: process(clk_i) |
161,12 → 175,10
fifo_memory_read: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (fifo.re = '1') then |
if (FIFO_DEPTH = 1) then |
rdata_o <= fifo.datas; |
else |
rdata_o <= fifo.data(to_integer(unsigned(fifo.r_pnt(fifo.r_pnt'left-1 downto 0)))); |
end if; |
if (FIFO_DEPTH = 1) then |
rdata_o <= fifo.datas; |
else |
rdata_o <= fifo.data(to_integer(unsigned(fifo.r_pnt(fifo.r_pnt'left-1 downto 0)))); |
end if; |
end if; |
end process fifo_memory_read; |
/neorv32_mtime.vhd
169,7 → 169,7
cmp_sync: process(clk_i) |
begin |
if rising_edge(clk_i) then |
cmp_lo_ge_ff <= cmp_lo_ge; |
cmp_lo_ge_ff <= cmp_lo_ge; -- there is one cycle delay between low (earlier) and high (later) word |
irq_o <= cmp_hi_gt or (cmp_hi_eq and cmp_lo_ge_ff); |
end if; |
end process cmp_sync; |
/neorv32_neoled.vhd
13,8 → 13,7
-- # configured using the ctrl_t_0h_*_c and ctrl_t_1h_*_c bits, respectively. 32-bit transfers # |
-- # (for RGBW modules) and 24-bit transfers (for RGB modules) are supported via ctrl_mode__c. # |
-- # # |
-- # The device features a TX buffer (FIFO) with <FIFO_DEPTH> entries. An IRQ is triggered if the # |
-- # FIFO falls below "half-full" fill level. # |
-- # The device features a TX buffer (FIFO) with <FIFO_DEPTH> entries with configurable interrupt. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
90,41 → 89,42
signal rden : std_ulogic; -- read enable |
|
-- Control register bits -- |
constant ctrl_enable_c : natural := 0; -- r/w: module enable |
constant ctrl_mode_c : natural := 1; -- r/w: 0 = 24-bit RGB mode, 1 = 32-bit RGBW mode |
constant ctrl_strobe_c : natural := 2; -- r/w: 0 = send normal data, 1 = send LED strobe command (RESET) on data write |
constant ctrl_enable_c : natural := 0; -- r/w: module enable |
constant ctrl_mode_c : natural := 1; -- r/w: 0 = 24-bit RGB mode, 1 = 32-bit RGBW mode |
constant ctrl_strobe_c : natural := 2; -- r/w: 0 = send normal data, 1 = send LED strobe command (RESET) on data write |
-- |
constant ctrl_clksel0_c : natural := 3; -- r/w: prescaler select bit 0 |
constant ctrl_clksel1_c : natural := 4; -- r/w: prescaler select bit 1 |
constant ctrl_clksel2_c : natural := 5; -- r/w: prescaler select bit 2 |
constant ctrl_clksel0_c : natural := 3; -- r/w: prescaler select bit 0 |
constant ctrl_clksel1_c : natural := 4; -- r/w: prescaler select bit 1 |
constant ctrl_clksel2_c : natural := 5; -- r/w: prescaler select bit 2 |
-- |
constant ctrl_bufs_0_c : natural := 6; -- r/-: log2(FIFO_DEPTH) bit 0 |
constant ctrl_bufs_1_c : natural := 7; -- r/-: log2(FIFO_DEPTH) bit 1 |
constant ctrl_bufs_2_c : natural := 8; -- r/-: log2(FIFO_DEPTH) bit 2 |
constant ctrl_bufs_3_c : natural := 9; -- r/-: log2(FIFO_DEPTH) bit 3 |
constant ctrl_bufs_0_c : natural := 6; -- r/-: log2(FIFO_DEPTH) bit 0 |
constant ctrl_bufs_1_c : natural := 7; -- r/-: log2(FIFO_DEPTH) bit 1 |
constant ctrl_bufs_2_c : natural := 8; -- r/-: log2(FIFO_DEPTH) bit 2 |
constant ctrl_bufs_3_c : natural := 9; -- r/-: log2(FIFO_DEPTH) bit 3 |
-- |
constant ctrl_t_tot_0_c : natural := 10; -- r/w: pulse-clock ticks per total period bit 0 |
constant ctrl_t_tot_1_c : natural := 11; -- r/w: pulse-clock ticks per total period bit 1 |
constant ctrl_t_tot_2_c : natural := 12; -- r/w: pulse-clock ticks per total period bit 2 |
constant ctrl_t_tot_3_c : natural := 13; -- r/w: pulse-clock ticks per total period bit 3 |
constant ctrl_t_tot_4_c : natural := 14; -- r/w: pulse-clock ticks per total period bit 4 |
constant ctrl_t_tot_0_c : natural := 10; -- r/w: pulse-clock ticks per total period bit 0 |
constant ctrl_t_tot_1_c : natural := 11; -- r/w: pulse-clock ticks per total period bit 1 |
constant ctrl_t_tot_2_c : natural := 12; -- r/w: pulse-clock ticks per total period bit 2 |
constant ctrl_t_tot_3_c : natural := 13; -- r/w: pulse-clock ticks per total period bit 3 |
constant ctrl_t_tot_4_c : natural := 14; -- r/w: pulse-clock ticks per total period bit 4 |
-- |
constant ctrl_t_0h_0_c : natural := 15; -- r/w: pulse-clock ticks per ZERO high-time bit 0 |
constant ctrl_t_0h_1_c : natural := 16; -- r/w: pulse-clock ticks per ZERO high-time bit 1 |
constant ctrl_t_0h_2_c : natural := 17; -- r/w: pulse-clock ticks per ZERO high-time bit 2 |
constant ctrl_t_0h_3_c : natural := 18; -- r/w: pulse-clock ticks per ZERO high-time bit 3 |
constant ctrl_t_0h_4_c : natural := 19; -- r/w: pulse-clock ticks per ZERO high-time bit 4 |
constant ctrl_t_0h_0_c : natural := 15; -- r/w: pulse-clock ticks per ZERO high-time bit 0 |
constant ctrl_t_0h_1_c : natural := 16; -- r/w: pulse-clock ticks per ZERO high-time bit 1 |
constant ctrl_t_0h_2_c : natural := 17; -- r/w: pulse-clock ticks per ZERO high-time bit 2 |
constant ctrl_t_0h_3_c : natural := 18; -- r/w: pulse-clock ticks per ZERO high-time bit 3 |
constant ctrl_t_0h_4_c : natural := 19; -- r/w: pulse-clock ticks per ZERO high-time bit 4 |
-- |
constant ctrl_t_1h_0_c : natural := 20; -- r/w: pulse-clock ticks per ONE high-time bit 0 |
constant ctrl_t_1h_1_c : natural := 21; -- r/w: pulse-clock ticks per ONE high-time bit 1 |
constant ctrl_t_1h_2_c : natural := 22; -- r/w: pulse-clock ticks per ONE high-time bit 2 |
constant ctrl_t_1h_3_c : natural := 23; -- r/w: pulse-clock ticks per ONE high-time bit 3 |
constant ctrl_t_1h_4_c : natural := 24; -- r/w: pulse-clock ticks per ONE high-time bit 4 |
constant ctrl_t_1h_0_c : natural := 20; -- r/w: pulse-clock ticks per ONE high-time bit 0 |
constant ctrl_t_1h_1_c : natural := 21; -- r/w: pulse-clock ticks per ONE high-time bit 1 |
constant ctrl_t_1h_2_c : natural := 22; -- r/w: pulse-clock ticks per ONE high-time bit 2 |
constant ctrl_t_1h_3_c : natural := 23; -- r/w: pulse-clock ticks per ONE high-time bit 3 |
constant ctrl_t_1h_4_c : natural := 24; -- r/w: pulse-clock ticks per ONE high-time bit 4 |
-- |
constant ctrl_tx_empty_c : natural := 28; -- r/-: TX FIFO is empty |
constant ctrl_tx_half_c : natural := 29; -- r/-: TX FIFO is at least half-full |
constant ctrl_tx_full_c : natural := 30; -- r/-: TX FIFO is full |
constant ctrl_tx_busy_c : natural := 31; -- r/-: serial TX engine busy when set |
constant ctrl_irq_conf_c : natural := 27; -- r/w: interrupt config: 1=IRQ when buffer is empty, 0=IRQ when buffer is half-empty |
constant ctrl_tx_empty_c : natural := 28; -- r/-: TX FIFO is empty |
constant ctrl_tx_half_c : natural := 29; -- r/-: TX FIFO is at least half-full |
constant ctrl_tx_full_c : natural := 30; -- r/-: TX FIFO is full |
constant ctrl_tx_busy_c : natural := 31; -- r/-: serial TX engine busy when set |
|
-- control register -- |
type ctrl_t is record |
132,6 → 132,7
mode : std_ulogic; |
strobe : std_ulogic; |
clk_prsc : std_ulogic_vector(2 downto 0); |
irq_conf : std_ulogic; |
-- pulse config -- |
t_total : std_ulogic_vector(4 downto 0); |
t0_high : std_ulogic_vector(4 downto 0); |
141,16 → 142,14
|
-- transmission buffer -- |
type tx_buffer_t is record |
we : std_ulogic; -- write enable |
re : std_ulogic; -- read enable |
clear : std_ulogic; -- sync reset, high-active |
level : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); |
wdata : std_ulogic_vector(31+2 downto 0); -- write data (excluding mode) |
rdata : std_ulogic_vector(31+2 downto 0); -- read data (including mode) |
avail : std_ulogic; -- data available? |
free : std_ulogic; -- free entry available? |
half : std_ulogic; -- half full |
half_ff : std_ulogic; |
we : std_ulogic; -- write enable |
re : std_ulogic; -- read enable |
clear : std_ulogic; -- sync reset, high-active |
wdata : std_ulogic_vector(31+2 downto 0); -- write data (excluding mode) |
rdata : std_ulogic_vector(31+2 downto 0); -- read data (including mode) |
avail : std_ulogic; -- data available? |
free : std_ulogic; -- free entry available? |
half : std_ulogic; -- half full |
end record; |
signal tx_buffer : tx_buffer_t; |
|
204,6 → 203,7
ctrl.mode <= data_i(ctrl_mode_c); |
ctrl.strobe <= data_i(ctrl_strobe_c); |
ctrl.clk_prsc <= data_i(ctrl_clksel2_c downto ctrl_clksel0_c); |
ctrl.irq_conf <= data_i(ctrl_irq_conf_c); |
ctrl.t_total <= data_i(ctrl_t_tot_4_c downto ctrl_t_tot_0_c); |
ctrl.t0_high <= data_i(ctrl_t_0h_4_c downto ctrl_t_0h_0_c); |
ctrl.t1_high <= data_i(ctrl_t_1h_4_c downto ctrl_t_1h_0_c); |
216,6 → 216,7
data_o(ctrl_mode_c) <= ctrl.mode; |
data_o(ctrl_strobe_c) <= ctrl.strobe; |
data_o(ctrl_clksel2_c downto ctrl_clksel0_c) <= ctrl.clk_prsc; |
data_o(ctrl_irq_conf_c) <= ctrl.irq_conf or bool_to_ulogic_f(boolean(FIFO_DEPTH = 1)); -- tie to one if FIFO_DEPTH is 1 |
data_o(ctrl_bufs_3_c downto ctrl_bufs_0_c) <= std_ulogic_vector(to_unsigned(index_size_f(FIFO_DEPTH), 4)); |
data_o(ctrl_t_tot_4_c downto ctrl_t_tot_0_c) <= ctrl.t_total; |
data_o(ctrl_t_0h_4_c downto ctrl_t_0h_0_c) <= ctrl.t0_high; |
243,8 → 244,19
irq_generator: process(clk_i) |
begin |
if rising_edge(clk_i) then |
tx_buffer.half_ff <= tx_buffer.half; |
irq_o <= ctrl.enable and tx_buffer.half and (not tx_buffer.half_ff); -- FIFO _becomes_ half-full |
if (ctrl.enable = '0') then |
irq_o <= '0'; -- no interrupt if unit is disabled |
else |
if (FIFO_DEPTH = 1) then |
irq_o <= tx_buffer.free; -- fire IRQ if FIFO is empty |
else |
if (ctrl.irq_conf = '0') then -- fire IRQ if FIFO is less than half-full |
irq_o <= not tx_buffer.half; |
else -- fire IRQ if FIFO is empty |
irq_o <= tx_buffer.free; |
end if; |
end if; |
end if; |
end if; |
end process irq_generator; |
|
263,7 → 275,8
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => tx_buffer.clear, -- sync reset, high-active |
level_o => tx_buffer.level, -- fill level |
level_o => open, -- fill level |
half_o => tx_buffer.half, -- FIFO is at least half full |
-- write port -- |
wdata_i => tx_buffer.wdata, -- write data |
we_i => tx_buffer.we, -- write enable |
274,8 → 287,8
avail_o => tx_buffer.avail -- data available when set |
); |
|
-- FIFO half-full? -- |
tx_buffer.half <= '1' when (unsigned(tx_buffer.level) >= to_unsigned(cond_sel_natural_f(boolean(FIFO_DEPTH > 1), FIFO_DEPTH/2, 1), tx_buffer.level'length)) else '0'; |
-- try to get new TX data -- |
tx_buffer.re <= '1' when (serial.state = S_IDLE) else '0'; |
|
|
-- Serial TX Engine ----------------------------------------------------------------------- |
322,16 → 335,17
serial.sreg <= serial.sreg(serial.sreg'left-1 downto 0) & '0'; -- shift left by one position (MSB-first) |
serial.bit_cnt <= std_ulogic_vector(unsigned(serial.bit_cnt) - 1); |
serial.pulse_cnt <= (others => '0'); |
if (serial.next_bit = '0') then -- send zero-bit |
serial.t_high <= ctrl.t0_high; |
else -- send one-bit |
serial.t_high <= ctrl.t1_high; |
end if; |
if (serial.bit_cnt = "000000") then -- all done? |
serial.state <= S_IDLE; |
else -- check current data MSB |
if (serial.next_bit = '0') then -- send zero-bit |
serial.t_high <= ctrl.t0_high; |
else -- send one-bit |
serial.t_high <= ctrl.t1_high; |
end if; |
serial.tx_out <= '0'; |
serial.state <= S_IDLE; |
else -- send current data MSB |
serial.tx_out <= '1'; |
serial.state <= S_PULSE; -- transmit single pulse |
serial.tx_out <= '1'; |
end if; |
|
when S_PULSE => -- send pulse with specific duty cycle |
381,11 → 395,8
-- SREG's TX data: bit 23 for RGB mode (24-bit), bit 31 for RGBW mode (32-bit) -- |
serial.next_bit <= serial.sreg(23) when (serial.mode = '0') else serial.sreg(31); |
|
-- get new TX data -- |
tx_buffer.re <= '1' when (serial.state = S_IDLE) and (tx_buffer.avail = '1') else '0'; |
|
-- TX engine status -- |
serial.busy <= '0' when (serial.state = S_IDLE) or (ctrl.enable = '0') else '1'; |
serial.busy <= '0' when (serial.state = S_IDLE) else '1'; |
|
|
end neorv32_neoled_rtl; |
/neorv32_package.vhd
64,7 → 64,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"01060100"; -- no touchy! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060202"; -- no touchy! |
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off! |
|
-- External Interface Types --------------------------------------------------------------- |
949,7 → 949,11
IO_GPIO_EN : boolean := false; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := false; -- implement machine system timer (MTIME)? |
IO_UART0_EN : boolean := false; -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART0_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two, min 1 |
IO_UART0_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two, min 1 |
IO_UART1_EN : boolean := false; -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_UART1_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two, min 1 |
IO_UART1_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two, min 1 |
IO_SPI_EN : boolean := false; -- implement serial peripheral interface (SPI)? |
IO_TWI_EN : boolean := false; -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH : natural := 0; -- number of PWM channels to implement (0..60); 0 = disabled |
1200,8 → 1204,7
alu_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU result |
-- data output -- |
rs1_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operand 1 |
rs2_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operand 2 |
cmp_o : out std_ulogic_vector(1 downto 0) -- comparator status |
rs2_o : out std_ulogic_vector(data_width_c-1 downto 0) -- operand 2 |
); |
end component; |
|
1229,8 → 1232,8
pc2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC |
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
csr_i : in std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data |
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status |
-- data output -- |
cmp_o : out std_ulogic_vector(1 downto 0); -- comparator status |
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- ALU result |
add_o : out std_ulogic_vector(data_width_c-1 downto 0); -- address computation result |
fpu_flags_o : out std_ulogic_vector(4 downto 0); -- FPU exception flags |
1621,7 → 1624,9
-- ------------------------------------------------------------------------------------------- |
component neorv32_uart |
generic ( |
UART_PRIMARY : boolean -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_PRIMARY : boolean; -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_RX_FIFO : natural; -- RX fifo depth, has to be a power of two, min 1 |
UART_TX_FIFO : natural -- TX fifo depth, has to be a power of two, min 1 |
); |
port ( |
-- host access -- |
1801,8 → 1806,6
-- clock generator -- |
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); -- "clock" inputs |
-- CPU state -- |
sleep_i : in std_ulogic; -- set if cpu is in sleep mode |
-- interrupt -- |
irq_o : out std_ulogic; -- interrupt request |
-- custom io (conduit) -- |
1970,6 → 1973,7
rstn_i : in std_ulogic; -- async reset, low-active |
clear_i : in std_ulogic; -- sync reset, high-active |
level_o : out std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- fill level |
half_o : out std_ulogic; -- FIFO is at least half full |
-- write port -- |
wdata_i : in std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- write data |
we_i : in std_ulogic; -- write enable |
2132,11 → 2136,9
variable tmp_v : std_ulogic; |
begin |
tmp_v := '0'; |
if (a'low < a'high) then -- not null range? |
for i in a'low to a'high loop |
tmp_v := tmp_v or a(i); |
end loop; -- i |
end if; |
for i in a'range loop |
tmp_v := tmp_v or a(i); |
end loop; -- i |
return tmp_v; |
end function or_reduce_f; |
|
2146,11 → 2148,9
variable tmp_v : std_ulogic; |
begin |
tmp_v := '1'; |
if (a'low < a'high) then -- not null range? |
for i in a'low to a'high loop |
tmp_v := tmp_v and a(i); |
end loop; -- i |
end if; |
for i in a'range loop |
tmp_v := tmp_v and a(i); |
end loop; -- i |
return tmp_v; |
end function and_reduce_f; |
|
2160,11 → 2160,9
variable tmp_v : std_ulogic; |
begin |
tmp_v := '0'; |
if (a'low < a'high) then -- not null range? |
for i in a'low to a'high loop |
tmp_v := tmp_v xor a(i); |
end loop; -- i |
end if; |
for i in a'range loop |
tmp_v := tmp_v xor a(i); |
end loop; -- i |
return tmp_v; |
end function xor_reduce_f; |
|
/neorv32_slink.vhd
95,17 → 95,30
-- |
constant ctrl_en_c : natural := 31; -- r/w: global enable |
|
-- interrupt configuration register bits -- |
constant irq_rx_en_lsb_c : natural := 0; -- r/w: enable RX interrupt for link 0..7 |
constant irq_rx_en_msb_c : natural := 7; |
-- |
constant irq_rx_mode_lsb_c : natural := 8; -- r/w: RX IRQ mode: 0=FIFO at least half-full; 1=FIFO not empty |
constant irq_rx_mode_msb_c : natural := 15; |
-- |
constant irq_tx_en_lsb_c : natural := 16; -- r/w: enable TX interrupt for link 0..7 |
constant irq_tx_en_msb_c : natural := 23; |
-- |
constant irq_tx_mode_lsb_c : natural := 24; -- r/w: TX IRQ mode: 0=FIFO less than half-full; 1=FIFO not full |
constant irq_tx_mode_msb_c : natural := 31; |
|
-- status register bits -- |
constant status_rx_avail_lsb_c : natural := 0; -- r/-: set if TX link 0..7 is ready to send |
constant status_rx_avail_lsb_c : natural := 0; -- r/-: set if RX link 0..7 FIFO is NOT empty |
constant status_rx_avail_msb_c : natural := 7; |
-- |
constant status_tx_free_lsb_c : natural := 8; -- r/-: set if RX link 0..7 data available |
constant status_tx_free_lsb_c : natural := 8; -- r/-: set if TX link 0..7 FIFO is NOT full |
constant status_tx_free_msb_c : natural := 15; |
-- |
constant status_rx_half_lsb_c : natural := 16; -- r/-: set if TX link 0..7 FIFO fill-level is >= half-full |
constant status_rx_half_lsb_c : natural := 16; -- r/-: set if RX link 0..7 FIFO fill-level is >= half-full |
constant status_rx_half_msb_c : natural := 23; |
-- |
constant status_tx_half_lsb_c : natural := 24; -- r/-: set if RX link 0..7 FIFO fill-level is > half-full |
constant status_tx_half_lsb_c : natural := 24; -- r/-: set if TX link 0..7 FIFO fill-level is > half-full |
constant status_tx_half_msb_c : natural := 31; |
|
-- bus access control -- |
117,34 → 130,24
-- control register -- |
signal enable : std_ulogic; -- global enable |
|
-- IRQ configuration register -- |
signal irq_rx_en : std_ulogic_vector(7 downto 0); |
signal irq_rx_mode : std_ulogic_vector(7 downto 0); |
signal irq_tx_en : std_ulogic_vector(7 downto 0); |
signal irq_tx_mode : std_ulogic_vector(7 downto 0); |
|
-- stream link fifo interface -- |
type fifo_data_t is array (0 to 7) of std_ulogic_vector(31 downto 0); |
type fifo_rx_level_t is array (0 to 7) of std_ulogic_vector(index_size_f(SLINK_RX_FIFO) downto 0); |
type fifo_tx_level_t is array (0 to 7) of std_ulogic_vector(index_size_f(SLINK_TX_FIFO) downto 0); |
signal rx_fifo_rdata : fifo_data_t; |
signal rx_fifo_level : fifo_rx_level_t; |
signal tx_fifo_level : fifo_tx_level_t; |
signal fifo_clear : std_ulogic; |
signal link_sel : std_ulogic_vector(7 downto 0); |
signal tx_fifo_we, rx_fifo_re : std_ulogic_vector(7 downto 0); |
signal rx_fifo_avail, rx_fifo_avail_ff : std_ulogic_vector(7 downto 0); |
signal tx_fifo_free, tx_fifo_free_ff : std_ulogic_vector(7 downto 0); |
signal rx_fifo_half, rx_fifo_half_ff : std_ulogic_vector(7 downto 0); |
signal tx_fifo_half, tx_fifo_half_ff : std_ulogic_vector(7 downto 0); |
signal rx_fifo_rdata : fifo_data_t; |
signal fifo_clear : std_ulogic; |
signal link_sel : std_ulogic_vector(7 downto 0); |
signal tx_fifo_we : std_ulogic_vector(7 downto 0); |
signal rx_fifo_re : std_ulogic_vector(7 downto 0); |
signal rx_fifo_avail : std_ulogic_vector(7 downto 0); |
signal tx_fifo_free : std_ulogic_vector(7 downto 0); |
signal rx_fifo_half : std_ulogic_vector(7 downto 0); |
signal tx_fifo_half : std_ulogic_vector(7 downto 0); |
|
-- interrupt controller -- |
type irq_t is record |
rx_pending : std_ulogic; |
rx_pending_ff : std_ulogic; |
rx_fire : std_ulogic; |
tx_pending : std_ulogic; |
tx_pending_ff : std_ulogic; |
tx_fire : std_ulogic; |
wr_ack : std_ulogic; |
rd_ack : std_ulogic; |
end record; |
signal irq : irq_t; |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
174,15 → 177,22
begin |
if rising_edge(clk_i) then |
-- write access -- |
irq.wr_ack <= '0'; |
ack_write <= '0'; |
ack_write <= '0'; |
if (acc_en = '1') and (wren_i = '1') then |
if (addr(5) = '0') then -- control/status |
if (addr(4) = '0') then -- control register |
if (addr(5) = '0') then -- control/status/irq |
if (addr(4 downto 3) = "00") then -- control register |
enable <= data_i(ctrl_en_c); |
else -- status register |
irq.wr_ack <= '1'; |
end if; |
if (addr(4 downto 3) = "01") then -- IRQ configuration register |
for i in 0 to SLINK_NUM_RX-1 loop |
irq_rx_en(i) <= data_i(i + irq_rx_en_lsb_c); |
irq_rx_mode(i) <= data_i(i + irq_rx_mode_lsb_c); |
end loop; |
for i in 0 to SLINK_NUM_TX-1 loop |
irq_tx_en(i) <= data_i(i + irq_tx_en_lsb_c); |
irq_tx_mode(i) <= data_i(i + irq_tx_mode_lsb_c); |
end loop; |
end if; |
ack_write <= '1'; |
else -- TX links |
ack_write <= or_reduce_f(link_sel and tx_fifo_free); |
190,25 → 200,35
end if; |
|
-- read access -- |
irq.rd_ack <= '0'; |
data_o <= (others => '0'); |
ack_read <= '0'; |
data_o <= (others => '0'); |
ack_read <= '0'; |
if (acc_en = '1') and (rden_i = '1') then |
if (addr(5) = '0') then -- control/status registers |
ack_read <= '1'; |
if (addr(4) = '0') then -- control register |
data_o(ctrl_rx_num_msb_c downto ctrl_rx_num_lsb_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_RX, 4)); |
data_o(ctrl_tx_num_msb_c downto ctrl_tx_num_lsb_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_TX, 4)); |
data_o(ctrl_rx_size_msb_c downto ctrl_rx_size_lsb_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_RX_FIFO), 4)); |
data_o(ctrl_tx_size_msb_c downto ctrl_tx_size_lsb_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_TX_FIFO), 4)); |
data_o(ctrl_en_c) <= enable; |
else -- fifo status register |
data_o(status_rx_avail_msb_c downto status_rx_avail_lsb_c) <= rx_fifo_avail; |
data_o(status_tx_free_msb_c downto status_tx_free_lsb_c) <= tx_fifo_free; |
data_o(status_rx_half_msb_c downto status_rx_half_lsb_c) <= rx_fifo_half; |
data_o(status_tx_half_msb_c downto status_tx_half_lsb_c) <= tx_fifo_half; |
irq.rd_ack <= '1'; |
end if; |
case addr(4 downto 3) is |
when "00" => -- control register |
data_o(ctrl_rx_num_msb_c downto ctrl_rx_num_lsb_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_RX, 4)); |
data_o(ctrl_tx_num_msb_c downto ctrl_tx_num_lsb_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_TX, 4)); |
data_o(ctrl_rx_size_msb_c downto ctrl_rx_size_lsb_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_RX_FIFO), 4)); |
data_o(ctrl_tx_size_msb_c downto ctrl_tx_size_lsb_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_TX_FIFO), 4)); |
data_o(ctrl_en_c) <= enable; |
when "01" => -- IRQ configuration register |
for i in 0 to SLINK_NUM_RX-1 loop |
data_o(irq_rx_en_lsb_c + i) <= irq_rx_en(i); |
data_o(irq_rx_mode_lsb_c + i) <= irq_rx_mode(i) or bool_to_ulogic_f(boolean(SLINK_RX_FIFO = 1)); -- tie to one if SLINK_RX_FIFO is 1 |
end loop; |
for i in 0 to SLINK_NUM_TX-1 loop |
data_o(irq_tx_en_lsb_c + i) <= irq_tx_en(i); |
data_o(irq_tx_mode_lsb_c + i) <= irq_tx_mode(i) or bool_to_ulogic_f(boolean(SLINK_TX_FIFO = 1)); -- tie to one if SLINK_TX_FIFO is 1 |
end loop; |
when "10" | "11" => -- fifo status register |
data_o(status_rx_avail_msb_c downto status_rx_avail_lsb_c) <= rx_fifo_avail; |
data_o(status_tx_free_msb_c downto status_tx_free_lsb_c) <= tx_fifo_free; |
data_o(status_rx_half_msb_c downto status_rx_half_lsb_c) <= rx_fifo_half; |
data_o(status_tx_half_msb_c downto status_tx_half_lsb_c) <= tx_fifo_half; |
when others => |
data_o <= (others => '0'); |
end case; |
else -- RX links |
data_o <= rx_fifo_rdata(to_integer(unsigned(addr(4 downto 2)))); |
ack_read <= or_reduce_f(link_sel and rx_fifo_avail); |
224,75 → 244,52
fifo_clear <= not enable; |
|
|
-- FIFO Level Monitoring ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
level_monitor: process(rx_fifo_level, tx_fifo_level) |
begin |
-- RX FIFO -- |
rx_fifo_half <= (others => '0'); |
for i in 0 to SLINK_NUM_RX-1 loop |
if (unsigned(rx_fifo_level(i)) >= to_unsigned(cond_sel_natural_f(boolean(SLINK_RX_FIFO > 1), SLINK_RX_FIFO/2, 1), rx_fifo_level(i)'length)) then |
rx_fifo_half(i) <= '1'; |
end if; |
end loop; |
-- TX FIFO -- |
tx_fifo_half <= (others => '0'); |
for i in 0 to SLINK_NUM_TX-1 loop |
if (unsigned(tx_fifo_level(i)) >= to_unsigned(cond_sel_natural_f(boolean(SLINK_TX_FIFO > 1), SLINK_TX_FIFO/2, 1), tx_fifo_level(i)'length)) then |
tx_fifo_half(i) <= '1'; |
end if; |
end loop; |
end process level_monitor; |
|
|
-- Interrupt Generator -------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
irq_arbiter: process(clk_i) |
variable rx_tmp_v : std_ulogic_vector(SLINK_NUM_RX-1 downto 0); |
variable tx_tmp_v : std_ulogic_vector(SLINK_NUM_TX-1 downto 0); |
begin |
if rising_edge(clk_i) then |
if (enable = '0') then |
irq.rx_pending <= '0'; |
irq.tx_pending <= '0'; |
if (enable = '0') then -- no interrupts if unit is disabled |
irq_rx_o <= '0'; |
irq_tx_o <= '0'; |
else |
-- RX IRQ -- |
if (irq.rx_pending = '0') then |
irq.rx_pending <= irq.rx_fire; |
elsif (irq.rd_ack = '1') or (irq.wr_ack = '1') then |
irq.rx_pending <= '0'; |
|
-- RX interrupt -- |
if (SLINK_RX_FIFO = 1) then |
irq_rx_o <= or_reduce_f(irq_rx_en and rx_fifo_avail); -- fire if any RX_FIFO is not empty |
else |
rx_tmp_v := (others => '0'); |
for i in 0 to SLINK_NUM_RX-1 loop |
if (irq_rx_mode(i) = '0') then -- fire if any RX_FIFO is at least half-full |
rx_tmp_v(i) := rx_fifo_half(i); |
else -- fire if any RX_FIFO is not empty (= data available) |
rx_tmp_v(i) := rx_fifo_avail(i); |
end if; |
end loop; |
irq_rx_o <= or_reduce_f(irq_rx_en and rx_tmp_v); |
end if; |
-- TX IRQ -- |
if (irq.tx_pending = '0') then |
irq.tx_pending <= irq.tx_fire; |
elsif (irq.rd_ack = '1') or (irq.wr_ack = '1') then |
irq.tx_pending <= '0'; |
|
-- TX interrupt -- |
if (SLINK_TX_FIFO = 1) then |
irq_tx_o <= or_reduce_f(irq_tx_en and tx_fifo_free); -- fire if any TX_FIFO is not full |
else |
tx_tmp_v := (others => '0'); |
for i in 0 to SLINK_NUM_TX-1 loop |
if (irq_tx_mode(i) = '0') then -- fire if any RX_FIFO is less than half-full |
tx_tmp_v(i) := not rx_fifo_half(i); |
else -- fire if any RX_FIFO is not full (= free buffer space available) |
tx_tmp_v(i) := tx_fifo_free(i); |
end if; |
end loop; |
irq_tx_o <= or_reduce_f(irq_tx_en and tx_tmp_v); |
end if; |
end if; |
-- CPU IRQs -- |
irq.rx_pending_ff <= irq.rx_pending; |
irq.tx_pending_ff <= irq.tx_pending; |
irq_rx_o <= irq.rx_pending and (not irq.rx_pending_ff); |
irq_tx_o <= irq.tx_pending and (not irq.tx_pending_ff); |
end if; |
end process irq_arbiter; |
|
-- status buffer -- |
irq_generator_sync: process(clk_i) |
begin |
if rising_edge(clk_i) then |
rx_fifo_avail_ff <= rx_fifo_avail; |
rx_fifo_half_ff <= rx_fifo_half; |
tx_fifo_free_ff <= tx_fifo_free; |
tx_fifo_half_ff <= tx_fifo_half; |
end if; |
end process irq_generator_sync; |
|
-- IRQ event detector -- |
-- RX interrupt: fire if any RX_FIFO gets full / fire if any RX_FIFO.level becomes half-full |
irq.rx_fire <= or_reduce_f(rx_fifo_avail and (not rx_fifo_avail_ff)) when (SLINK_RX_FIFO = 1) else or_reduce_f(rx_fifo_half and (not rx_fifo_half_ff)); |
-- TX interrupt: fire if any TX_FIFO gets empty / fire if any TX_FIFO.level falls below half-full level |
irq.tx_fire <= or_reduce_f(tx_fifo_free and (not tx_fifo_free_ff)) when (SLINK_TX_FIFO = 1) else or_reduce_f((not tx_fifo_half) and tx_fifo_half_ff); |
|
|
-- Link Select ---------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
link_select: process(addr) |
325,8 → 322,8
generic map ( |
FIFO_DEPTH => SLINK_TX_FIFO, -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH => 32, -- size of data elements in fifo |
FIFO_RSYNC => false, -- false = async read; true = sync read |
FIFO_SAFE => true -- true = allow read/write only if entry available |
FIFO_RSYNC => false, -- async read |
FIFO_SAFE => true -- safe access |
) |
port map ( |
-- control -- |
333,7 → 330,8
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => fifo_clear, -- sync reset, high-active |
level_o => tx_fifo_level(i), -- fill level |
level_o => open, -- fill level |
half_o => tx_fifo_half(i), -- FIFO is at least half full |
-- write port -- |
wdata_i => data_i, -- write data |
we_i => tx_fifo_we(i), -- write enable |
351,7 → 349,7
tx_fifo_free(i) <= '0'; |
slink_tx_dat_o(i) <= (others => '0'); |
slink_tx_val_o(i) <= '0'; |
tx_fifo_level(i) <= (others => '0'); |
tx_fifo_half(i) <= '0'; |
end generate; |
|
|
363,8 → 361,8
generic map ( |
FIFO_DEPTH => SLINK_RX_FIFO, -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH => 32, -- size of data elements in fifo |
FIFO_RSYNC => false, -- false = async read; true = sync read |
FIFO_SAFE => true -- true = allow read/write only if entry available |
FIFO_RSYNC => false, -- async read |
FIFO_SAFE => true -- safe access |
) |
port map ( |
-- control -- |
371,7 → 369,8
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => fifo_clear, -- sync reset, high-active |
level_o => rx_fifo_level(i), -- fill level |
level_o => open, -- fill level |
half_o => rx_fifo_half(i), -- FIFO is at least half full |
-- write port -- |
wdata_i => slink_rx_dat_i(i), -- write data |
we_i => slink_rx_val_i(i), -- write enable |
389,7 → 388,7
rx_fifo_avail(i) <= '0'; |
slink_rx_rdy_o(i) <= '0'; |
rx_fifo_rdata(i) <= (others => '0'); |
rx_fifo_level(i) <= (others => '0'); |
rx_fifo_half(i) <= '0'; |
end generate; |
|
|
/neorv32_spi.vhd
72,25 → 72,28
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit |
constant lo_abb_c : natural := index_size_f(spi_size_c); -- low address boundary bit |
|
-- control reg bits -- |
constant ctrl_spi_cs0_c : natural := 0; -- r/w: spi CS 0 |
constant ctrl_spi_cs1_c : natural := 1; -- r/w: spi CS 1 |
constant ctrl_spi_cs2_c : natural := 2; -- r/w: spi CS 2 |
constant ctrl_spi_cs3_c : natural := 3; -- r/w: spi CS 3 |
constant ctrl_spi_cs4_c : natural := 4; -- r/w: spi CS 4 |
constant ctrl_spi_cs5_c : natural := 5; -- r/w: spi CS 5 |
constant ctrl_spi_cs6_c : natural := 6; -- r/w: spi CS 6 |
constant ctrl_spi_cs7_c : natural := 7; -- r/w: spi CS 7 |
-- control register -- |
constant ctrl_spi_cs0_c : natural := 0; -- r/w: spi CS 0 |
constant ctrl_spi_cs1_c : natural := 1; -- r/w: spi CS 1 |
constant ctrl_spi_cs2_c : natural := 2; -- r/w: spi CS 2 |
constant ctrl_spi_cs3_c : natural := 3; -- r/w: spi CS 3 |
constant ctrl_spi_cs4_c : natural := 4; -- r/w: spi CS 4 |
constant ctrl_spi_cs5_c : natural := 5; -- r/w: spi CS 5 |
constant ctrl_spi_cs6_c : natural := 6; -- r/w: spi CS 6 |
constant ctrl_spi_cs7_c : natural := 7; -- r/w: spi CS 7 |
-- |
constant ctrl_spi_en_c : natural := 8; -- r/w: spi enable |
constant ctrl_spi_cpha_c : natural := 9; -- r/w: spi clock phase |
constant ctrl_spi_prsc0_c : natural := 10; -- r/w: spi prescaler select bit 0 |
constant ctrl_spi_prsc1_c : natural := 11; -- r/w: spi prescaler select bit 1 |
constant ctrl_spi_prsc2_c : natural := 12; -- r/w: spi prescaler select bit 2 |
constant ctrl_spi_size0_c : natural := 13; -- r/w: data size (00: 8-bit, 01: 16-bit) |
constant ctrl_spi_size1_c : natural := 14; -- r/w: data size (10: 24-bit, 11: 32-bit) |
constant ctrl_spi_en_c : natural := 8; -- r/w: spi enable |
constant ctrl_spi_cpha_c : natural := 9; -- r/w: spi clock phase |
constant ctrl_spi_prsc0_c : natural := 10; -- r/w: spi prescaler select bit 0 |
constant ctrl_spi_prsc1_c : natural := 11; -- r/w: spi prescaler select bit 1 |
constant ctrl_spi_prsc2_c : natural := 12; -- r/w: spi prescaler select bit 2 |
constant ctrl_spi_size0_c : natural := 13; -- r/w: data size (00: 8-bit, 01: 16-bit) |
constant ctrl_spi_size1_c : natural := 14; -- r/w: data size (10: 24-bit, 11: 32-bit) |
constant ctrl_spi_cpol_c : natural := 15; -- r/w: spi clock polarity |
-- |
constant ctrl_spi_busy_c : natural := 31; -- r/-: spi transceiver is busy |
constant ctrl_spi_busy_c : natural := 31; -- r/-: spi transceiver is busy |
-- |
signal ctrl : std_ulogic_vector(15 downto 0); |
|
-- access control -- |
signal acc_en : std_ulogic; -- module access enable |
98,25 → 101,21
signal wren : std_ulogic; -- word write enable |
signal rden : std_ulogic; -- read enable |
|
-- accessible regs -- |
signal ctrl : std_ulogic_vector(14 downto 0); |
signal tx_data_reg : std_ulogic_vector(31 downto 0); |
signal rx_data : std_ulogic_vector(31 downto 0); |
|
-- clock generator -- |
signal spi_clk : std_ulogic; |
signal spi_clk_en : std_ulogic; |
|
-- spi transceiver -- |
signal spi_start : std_ulogic; |
signal spi_busy : std_ulogic; |
signal spi_state0 : std_ulogic; |
signal spi_state1 : std_ulogic; |
signal spi_rtx_sreg : std_ulogic_vector(31 downto 0); |
signal spi_rx_data : std_ulogic_vector(31 downto 0); |
signal spi_bitcnt : std_ulogic_vector(05 downto 0); |
signal spi_bitcnt_max : std_ulogic_vector(05 downto 0); |
signal spi_sdi_ff0 : std_ulogic; |
signal spi_sdi_ff1 : std_ulogic; |
type rtx_engine_t is record |
busy : std_ulogic; |
state0 : std_ulogic; |
state1 : std_ulogic; |
rtx_sreg : std_ulogic_vector(31 downto 0); |
bitcnt : std_ulogic_vector(05 downto 0); |
bytecnt : std_ulogic_vector(02 downto 0); |
sdi_ff0 : std_ulogic; |
sdi_ff1 : std_ulogic; |
end record; |
signal rtx_engine : rtx_engine_t; |
|
begin |
|
133,60 → 132,85
rw_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
ack_o <= acc_en and (rden_i or wren_i); |
-- bus access acknowledge -- |
ack_o <= rden or wren; |
|
-- write access -- |
spi_start <= '0'; |
if (wren = '1') then |
if (addr = spi_ctrl_addr_c) then -- control |
ctrl <= data_i(ctrl'left downto 0); |
if (addr = spi_ctrl_addr_c) then -- control register |
ctrl(ctrl_spi_cs0_c) <= data_i(ctrl_spi_cs0_c); |
ctrl(ctrl_spi_cs1_c) <= data_i(ctrl_spi_cs1_c); |
ctrl(ctrl_spi_cs2_c) <= data_i(ctrl_spi_cs2_c); |
ctrl(ctrl_spi_cs3_c) <= data_i(ctrl_spi_cs3_c); |
ctrl(ctrl_spi_cs4_c) <= data_i(ctrl_spi_cs4_c); |
ctrl(ctrl_spi_cs5_c) <= data_i(ctrl_spi_cs5_c); |
ctrl(ctrl_spi_cs6_c) <= data_i(ctrl_spi_cs6_c); |
ctrl(ctrl_spi_cs7_c) <= data_i(ctrl_spi_cs7_c); |
-- |
ctrl(ctrl_spi_en_c) <= data_i(ctrl_spi_en_c); |
ctrl(ctrl_spi_cpha_c) <= data_i(ctrl_spi_cpha_c); |
ctrl(ctrl_spi_prsc0_c) <= data_i(ctrl_spi_prsc0_c); |
ctrl(ctrl_spi_prsc1_c) <= data_i(ctrl_spi_prsc1_c); |
ctrl(ctrl_spi_prsc2_c) <= data_i(ctrl_spi_prsc2_c); |
ctrl(ctrl_spi_size0_c) <= data_i(ctrl_spi_size0_c); |
ctrl(ctrl_spi_size1_c) <= data_i(ctrl_spi_size1_c); |
ctrl(ctrl_spi_cpol_c) <= data_i(ctrl_spi_cpol_c); |
end if; |
if (addr = spi_rtx_addr_c) then -- tx data |
tx_data_reg <= data_i; |
spi_start <= '1'; |
end if; |
end if; |
|
-- read access -- |
data_o <= (others => '0'); |
if (rden = '1') then |
if (addr = spi_ctrl_addr_c) then |
data_o(ctrl_spi_cs0_c) <= ctrl(ctrl_spi_cs0_c); |
data_o(ctrl_spi_cs1_c) <= ctrl(ctrl_spi_cs1_c); |
data_o(ctrl_spi_cs2_c) <= ctrl(ctrl_spi_cs2_c); |
data_o(ctrl_spi_cs3_c) <= ctrl(ctrl_spi_cs3_c); |
data_o(ctrl_spi_cs4_c) <= ctrl(ctrl_spi_cs4_c); |
data_o(ctrl_spi_cs5_c) <= ctrl(ctrl_spi_cs5_c); |
data_o(ctrl_spi_cs6_c) <= ctrl(ctrl_spi_cs6_c); |
data_o(ctrl_spi_cs7_c) <= ctrl(ctrl_spi_cs7_c); |
if (addr = spi_ctrl_addr_c) then -- control register |
data_o(ctrl_spi_cs0_c) <= ctrl(ctrl_spi_cs0_c); |
data_o(ctrl_spi_cs1_c) <= ctrl(ctrl_spi_cs1_c); |
data_o(ctrl_spi_cs2_c) <= ctrl(ctrl_spi_cs2_c); |
data_o(ctrl_spi_cs3_c) <= ctrl(ctrl_spi_cs3_c); |
data_o(ctrl_spi_cs4_c) <= ctrl(ctrl_spi_cs4_c); |
data_o(ctrl_spi_cs5_c) <= ctrl(ctrl_spi_cs5_c); |
data_o(ctrl_spi_cs6_c) <= ctrl(ctrl_spi_cs6_c); |
data_o(ctrl_spi_cs7_c) <= ctrl(ctrl_spi_cs7_c); |
-- |
data_o(ctrl_spi_en_c) <= ctrl(ctrl_spi_en_c); |
data_o(ctrl_spi_cpha_c) <= ctrl(ctrl_spi_cpha_c); |
data_o(ctrl_spi_prsc0_c) <= ctrl(ctrl_spi_prsc0_c); |
data_o(ctrl_spi_prsc1_c) <= ctrl(ctrl_spi_prsc1_c); |
data_o(ctrl_spi_prsc2_c) <= ctrl(ctrl_spi_prsc2_c); |
data_o(ctrl_spi_size0_c) <= ctrl(ctrl_spi_size0_c); |
data_o(ctrl_spi_size1_c) <= ctrl(ctrl_spi_size1_c); |
data_o(ctrl_spi_en_c) <= ctrl(ctrl_spi_en_c); |
data_o(ctrl_spi_cpha_c) <= ctrl(ctrl_spi_cpha_c); |
data_o(ctrl_spi_prsc0_c) <= ctrl(ctrl_spi_prsc0_c); |
data_o(ctrl_spi_prsc1_c) <= ctrl(ctrl_spi_prsc1_c); |
data_o(ctrl_spi_prsc2_c) <= ctrl(ctrl_spi_prsc2_c); |
data_o(ctrl_spi_size0_c) <= ctrl(ctrl_spi_size0_c); |
data_o(ctrl_spi_size1_c) <= ctrl(ctrl_spi_size1_c); |
data_o(ctrl_spi_cpol_c) <= ctrl(ctrl_spi_cpol_c); |
-- |
data_o(ctrl_spi_busy_c) <= spi_busy; |
else -- spi_rtx_addr_c |
data_o <= rx_data; |
data_o(ctrl_spi_busy_c) <= rtx_engine.busy; |
else -- data register (spi_rtx_addr_c) |
data_o <= rtx_engine.rtx_sreg; |
end if; |
end if; |
end if; |
end process rw_access; |
|
-- direct chip-select (CS) (output is low-active) -- |
-- direct chip-select (CS), output is low-active -- |
spi_csn_o(7 downto 0) <= not ctrl(ctrl_spi_cs7_c downto ctrl_spi_cs0_c); |
|
|
-- Transmission Data Size ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
data_size: process(ctrl) |
begin |
case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is |
when "00" => rtx_engine.bytecnt <= "001"; -- 1-byte mode |
when "01" => rtx_engine.bytecnt <= "010"; -- 2-byte mode |
when "10" => rtx_engine.bytecnt <= "011"; -- 3-byte mode |
when others => rtx_engine.bytecnt <= "100"; -- 4-byte mode |
end case; |
end process data_size; |
|
|
-- Clock Selection ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
-- clock generator enable -- |
clkgen_en_o <= ctrl(ctrl_spi_en_c); |
clkgen_en_o <= ctrl(ctrl_spi_en_c); -- clock generator enable |
spi_clk_en <= clkgen_i(to_integer(unsigned(ctrl(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c)))); -- clock select |
|
-- spi clock select -- |
spi_clk <= clkgen_i(to_integer(unsigned(ctrl(ctrl_spi_prsc2_c downto ctrl_spi_prsc0_c)))); |
|
|
-- SPI Transceiver ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
spi_rtx_unit: process(clk_i) |
193,61 → 217,60
begin |
if rising_edge(clk_i) then |
-- input (sdi) synchronizer -- |
spi_sdi_ff0 <= spi_sdi_i; |
spi_sdi_ff1 <= spi_sdi_ff0; |
rtx_engine.sdi_ff0 <= spi_sdi_i; |
rtx_engine.sdi_ff1 <= rtx_engine.sdi_ff0; |
|
-- serial engine -- |
irq_o <= '0'; |
if (spi_state0 = '0') or (ctrl(ctrl_spi_en_c) = '0') then -- idle or disabled |
if (rtx_engine.state0 = '0') or (ctrl(ctrl_spi_en_c) = '0') then -- idle or disabled |
-- -------------------------------------------------------------- |
spi_bitcnt <= (others => '0'); |
spi_state1 <= '0'; |
spi_sdo_o <= '0'; |
spi_sck_o <= '0'; |
spi_sck_o <= ctrl(ctrl_spi_cpol_c); |
rtx_engine.bitcnt <= (others => '0'); |
rtx_engine.state1 <= '0'; |
if (ctrl(ctrl_spi_en_c) = '0') then -- disabled |
spi_busy <= '0'; |
elsif (spi_start = '1') then -- start new transmission |
spi_rtx_sreg <= tx_data_reg; |
spi_busy <= '1'; |
rtx_engine.busy <= '0'; |
elsif (wren = '1') and (addr = spi_rtx_addr_c) then -- start new transmission |
rtx_engine.rtx_sreg <= data_i; |
rtx_engine.busy <= '1'; |
end if; |
spi_state0 <= spi_busy and spi_clk; -- start with next new clock pulse |
rtx_engine.state0 <= rtx_engine.busy and spi_clk_en; -- start with next new clock pulse |
|
else -- transmission in progress |
-- -------------------------------------------------------------- |
if (spi_state1 = '0') then -- first half of transmission |
|
if (rtx_engine.state1 = '0') then -- first half of bit transmission |
-- -------------------------------------------------------------- |
spi_sck_o <= ctrl(ctrl_spi_cpha_c); |
|
spi_sck_o <= ctrl(ctrl_spi_cpha_c) xor ctrl(ctrl_spi_cpol_c); |
-- |
case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is |
when "00" => spi_sdo_o <= spi_rtx_sreg(07); -- 8-bit mode |
when "01" => spi_sdo_o <= spi_rtx_sreg(15); -- 16-bit mode |
when "10" => spi_sdo_o <= spi_rtx_sreg(23); -- 24-bit mode |
when others => spi_sdo_o <= spi_rtx_sreg(31); -- 32-bit mode |
when "00" => spi_sdo_o <= rtx_engine.rtx_sreg(07); -- 8-bit mode |
when "01" => spi_sdo_o <= rtx_engine.rtx_sreg(15); -- 16-bit mode |
when "10" => spi_sdo_o <= rtx_engine.rtx_sreg(23); -- 24-bit mode |
when others => spi_sdo_o <= rtx_engine.rtx_sreg(31); -- 32-bit mode |
end case; |
|
if (spi_clk = '1') then |
spi_state1 <= '1'; |
-- |
if (spi_clk_en = '1') then |
if (ctrl(ctrl_spi_cpha_c) = '0') then |
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; |
rtx_engine.rtx_sreg <= rtx_engine.rtx_sreg(30 downto 0) & rtx_engine.sdi_ff1; |
end if; |
spi_bitcnt <= std_ulogic_vector(unsigned(spi_bitcnt) + 1); |
rtx_engine.bitcnt <= std_ulogic_vector(unsigned(rtx_engine.bitcnt) + 1); |
rtx_engine.state1 <= '1'; |
end if; |
|
else -- second half of transmission |
else -- second half of bit transmission |
-- -------------------------------------------------------------- |
spi_sck_o <= not ctrl(ctrl_spi_cpha_c); |
|
if (spi_clk = '1') then |
spi_state1 <= '0'; |
spi_sck_o <= ctrl(ctrl_spi_cpha_c) xnor ctrl(ctrl_spi_cpol_c); |
-- |
if (spi_clk_en = '1') then |
if (ctrl(ctrl_spi_cpha_c) = '1') then |
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; |
rtx_engine.rtx_sreg <= rtx_engine.rtx_sreg(30 downto 0) & rtx_engine.sdi_ff1; |
end if; |
if (spi_bitcnt = spi_bitcnt_max) then |
spi_state0 <= '0'; |
spi_busy <= '0'; |
irq_o <= '1'; |
if (rtx_engine.bitcnt(5 downto 3) = rtx_engine.bytecnt) then |
rtx_engine.state0 <= '0'; |
rtx_engine.busy <= '0'; |
end if; |
rtx_engine.state1 <= '0'; |
end if; |
|
end if; |
end if; |
end if; |
254,30 → 277,9
end process spi_rtx_unit; |
|
|
-- RTX Data size ------------------------------------------------------------------------ |
-- Interrupt ------------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
data_size: process(ctrl) |
begin |
case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is |
when "00" => spi_bitcnt_max <= "001000"; -- 8-bit mode |
when "01" => spi_bitcnt_max <= "010000"; -- 16-bit mode |
when "10" => spi_bitcnt_max <= "011000"; -- 24-bit mode |
when others => spi_bitcnt_max <= "100000"; -- 32-bit mode |
end case; |
end process data_size; |
irq_o <= ctrl(ctrl_spi_en_c) and (not rtx_engine.busy); -- fire IRQ if transceiver idle |
|
|
-- RX-Data Masking ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
rx_mapping: process(ctrl, spi_rtx_sreg) |
begin |
case ctrl(ctrl_spi_size1_c downto ctrl_spi_size0_c) is |
when "00" => rx_data <= x"000000" & spi_rtx_sreg(07 downto 0); -- 8-bit mode |
when "01" => rx_data <= x"0000" & spi_rtx_sreg(15 downto 0); -- 16-bit mode |
when "10" => rx_data <= x"00" & spi_rtx_sreg(23 downto 0); -- 24-bit mode |
when others => rx_data <= spi_rtx_sreg(31 downto 0); -- 32-bit mode |
end case; |
end process rx_mapping; |
|
|
end neorv32_spi_rtl; |
/neorv32_top.vhd
120,7 → 120,11
IO_GPIO_EN : boolean := false; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := false; -- implement machine system timer (MTIME)? |
IO_UART0_EN : boolean := false; -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART0_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two, min 1 |
IO_UART0_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two, min 1 |
IO_UART1_EN : boolean := false; -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_UART1_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two, min 1 |
IO_UART1_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two, min 1 |
IO_SPI_EN : boolean := false; -- implement serial peripheral interface (SPI)? |
IO_TWI_EN : boolean := false; -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH : natural := 0; -- number of PWM channels to implement (0..60); 0 = disabled |
330,7 → 334,6
|
-- misc -- |
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME |
signal cpu_sleep : std_ulogic; -- CPU is in sleep mode when set |
signal bus_keeper_err : std_ulogic; -- bus keeper: bus access timeout |
|
begin |
479,7 → 482,7
-- global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => sys_rstn, -- global reset, low-active, async |
sleep_o => cpu_sleep, -- cpu is in sleep mode when set |
sleep_o => open, -- cpu is in sleep mode when set |
-- instruction bus interface -- |
i_bus_addr_o => cpu_i.addr, -- bus access address |
i_bus_rdata_i => cpu_i.rdata, -- bus read data |
868,8 → 871,6
-- clock generator -- |
clkgen_en_o => cfs_cg_en, -- enable clock generator |
clkgen_i => clk_gen, -- "clock" inputs |
-- CPU state -- |
sleep_i => cpu_sleep, -- set if cpu is in sleep mode |
-- interrupt -- |
irq_o => cfs_irq, -- interrupt request |
-- custom io (conduit) -- |
1006,7 → 1007,9
if (IO_UART0_EN = true) generate |
neorv32_uart0_inst: neorv32_uart |
generic map ( |
UART_PRIMARY => true -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_PRIMARY => true, -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_RX_FIFO => IO_UART0_RX_FIFO, -- RX fifo depth, has to be a power of two, min 1 |
UART_TX_FIFO => IO_UART0_TX_FIFO -- TX fifo depth, has to be a power of two, min 1 |
) |
port map ( |
-- host access -- |
1050,7 → 1053,9
if (IO_UART1_EN = true) generate |
neorv32_uart1_inst: neorv32_uart |
generic map ( |
UART_PRIMARY => false -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_PRIMARY => false, -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_RX_FIFO => IO_UART1_RX_FIFO, -- RX fifo depth, has to be a power of two, min 1 |
UART_TX_FIFO => IO_UART1_TX_FIFO -- TX fifo depth, has to be a power of two, min 1 |
) |
port map ( |
-- host access -- |
1156,8 → 1161,8
neorv32_twi_inst_false: |
if (IO_TWI_EN = false) generate |
resp_bus(RESP_TWI) <= resp_bus_entry_terminate_c; |
-- twi_sda_io <= 'Z'; -- FIXME? |
-- twi_scl_io <= 'Z'; -- FIXME? |
twi_sda_io <= 'Z'; |
twi_scl_io <= 'Z'; |
twi_cg_en <= '0'; |
twi_irq <= '0'; |
end generate; |
/neorv32_twi.vhd
190,8 → 190,14
twi_scl_i_ff0 <= twi_scl_i; |
twi_scl_i_ff1 <= twi_scl_i_ff0; |
|
-- interrupt -- |
if (arbiter = "100") then -- fire IRQ if enabled transceiver is idle |
irq_o <= '1'; |
else |
irq_o <= '0'; |
end if; |
|
-- defaults -- |
irq_o <= '0'; |
arbiter(2) <= ctrl(ctrl_twi_en_c); -- still activated? |
|
-- serial engine -- |
257,7 → 263,6
|
if (twi_bitcnt = "1010") then -- 8 data bits + 1 bit for ACK + 1 tick delay |
arbiter(1 downto 0) <= "00"; -- go back to IDLE |
irq_o <= '1'; -- fire IRQ |
end if; |
|
when others => -- "0--" OFFLINE: TWI deactivated |
/neorv32_uart.vhd
2,21 → 2,22
-- # << NEORV32 - Universal Asynchronous Receiver and Transmitter (UART0/1) >> # |
-- # ********************************************************************************************* # |
-- # Frame configuration: 1 start bit, 8 bit data, parity bit (none/even/odd), 1 stop bit, # |
-- # programmable BAUD rate via clock pre-scaler and 12-bit BAUD value config register. RX engine # |
-- # a simple 2-entry data buffer (for double-buffering). # |
-- # Interrupts: UART_RX_available, UART_TX_done # |
-- # programmable BAUD rate via clock pre-scaler and 12-bit BAUD value configuration register, # |
-- # optional configurable RX and TX FIFOs. # |
-- # # |
-- # Interrupts: Configurable RX and TX interrupt (both triggered by specific FIFO fill-levels) # |
-- # # |
-- # Support for RTS("RTR")/CTS hardware flow control: # |
-- # * uart_rts_o = 0: RX is ready to receive a new char, enabled via CTRL.ctrl_uart_rts_en_c # |
-- # * uart_cts_i = 0: TX is allowed to send a new char, enabled via CTRL.ctrl_uart_cts_en_c # |
-- # * uart_rts_o = 0: RX is ready to receive a new char, enabled via CTRL.ctrl_rts_en_c # |
-- # * uart_cts_i = 0: TX is allowed to send a new char, enabled via CTRL.ctrl_cts_en_c # |
-- # # |
-- # UART0 / UART1: # |
-- # This module is used for implementing UART0 and UART1. The UART_PRIMARY generic configures the # |
-- # interface register addresses and simulation output setting for UART0 (UART_PRIMARY = true) # |
-- # or UART1 (UART_PRIMARY = false). # |
-- # interface register addresses and simulation outputs for UART0 (UART_PRIMARY = true) or UART1 # |
-- # (UART_PRIMARY = false). # |
-- # # |
-- # SIMULATION MODE: # |
-- # When the simulation mode is enabled (setting the ctrl.ctrl_uart_sim_en_c bit) any write # |
-- # When the simulation mode is enabled (setting the ctrl.ctrl_sim_en_c bit) any write # |
-- # access to the TX register will not trigger any UART activity. Instead, the written data is # |
-- # output to the simulation environment. The lowest 8 bits of the written data are printed as # |
-- # ASCII char to the simulator console. # |
62,11 → 63,13
|
library neorv32; |
use neorv32.neorv32_package.all; |
use std.textio.all; -- obviously only for simulation |
use std.textio.all; |
|
entity neorv32_uart is |
generic ( |
UART_PRIMARY : boolean -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_PRIMARY : boolean; -- true = primary UART (UART0), false = secondary UART (UART1) |
UART_RX_FIFO : natural; -- RX fifo depth, has to be a power of two, min 1 |
UART_TX_FIFO : natural -- TX fifo depth, has to be a power of two, min 1 |
); |
port ( |
-- host access -- |
108,46 → 111,54
constant sim_screen_output_en_c : boolean := true; -- output lowest byte as char to simulator console when enabled |
constant sim_text_output_en_c : boolean := true; -- output lowest byte as char to text file when enabled |
constant sim_data_output_en_c : boolean := true; -- dump 32-word to file when enabled |
constant sim_uart_text_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.text.out", "neorv32.uart1.sim_mode.text.out"); |
constant sim_uart_data_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.data.out", "neorv32.uart1.sim_mode.data.out"); |
|
-- simulation output file configuration -- |
constant sim_uart_text_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.text.out", "neorv32.uart1.sim_mode.text.out"); |
constant sim_uart_data_file_c : string := cond_sel_string_f(UART_PRIMARY, "neorv32.uart0.sim_mode.data.out", "neorv32.uart1.sim_mode.data.out"); |
|
-- control register -- |
signal ctrl : std_ulogic_vector(31 downto 0); |
|
-- control register bits -- |
constant ctrl_uart_baud00_c : natural := 0; -- r/w: UART baud config bit 0 |
constant ctrl_uart_baud01_c : natural := 1; -- r/w: UART baud config bit 1 |
constant ctrl_uart_baud02_c : natural := 2; -- r/w: UART baud config bit 2 |
constant ctrl_uart_baud03_c : natural := 3; -- r/w: UART baud config bit 3 |
constant ctrl_uart_baud04_c : natural := 4; -- r/w: UART baud config bit 4 |
constant ctrl_uart_baud05_c : natural := 5; -- r/w: UART baud config bit 5 |
constant ctrl_uart_baud06_c : natural := 6; -- r/w: UART baud config bit 6 |
constant ctrl_uart_baud07_c : natural := 7; -- r/w: UART baud config bit 7 |
constant ctrl_uart_baud08_c : natural := 8; -- r/w: UART baud config bit 8 |
constant ctrl_uart_baud09_c : natural := 9; -- r/w: UART baud config bit 9 |
constant ctrl_uart_baud10_c : natural := 10; -- r/w: UART baud config bit 10 |
constant ctrl_uart_baud11_c : natural := 11; -- r/w: UART baud config bit 11 |
constant ctrl_uart_sim_en_c : natural := 12; -- r/w: UART <<SIMULATION MODE>> enable |
constant ctrl_baud00_c : natural := 0; -- r/w: baud config bit 0 |
constant ctrl_baud01_c : natural := 1; -- r/w: baud config bit 1 |
constant ctrl_baud02_c : natural := 2; -- r/w: baud config bit 2 |
constant ctrl_baud03_c : natural := 3; -- r/w: baud config bit 3 |
constant ctrl_baud04_c : natural := 4; -- r/w: baud config bit 4 |
constant ctrl_baud05_c : natural := 5; -- r/w: baud config bit 5 |
constant ctrl_baud06_c : natural := 6; -- r/w: baud config bit 6 |
constant ctrl_baud07_c : natural := 7; -- r/w: baud config bit 7 |
constant ctrl_baud08_c : natural := 8; -- r/w: baud config bit 8 |
constant ctrl_baud09_c : natural := 9; -- r/w: baud config bit 9 |
constant ctrl_baud10_c : natural := 10; -- r/w: baud config bit 10 |
constant ctrl_baud11_c : natural := 11; -- r/w: baud config bit 11 |
constant ctrl_sim_en_c : natural := 12; -- r/w: UART <<SIMULATION MODE>> enable |
constant ctrl_rx_empty_c : natural := 13; -- r/-: RX FIFO is empty |
constant ctrl_rx_half_c : natural := 14; -- r/-: RX FIFO is at least half-full |
constant ctrl_rx_full_c : natural := 15; -- r/-: RX FIFO is full |
constant ctrl_tx_empty_c : natural := 16; -- r/-: TX FIFO is empty |
constant ctrl_tx_half_c : natural := 17; -- r/-: TX FIFO is at least half-full |
constant ctrl_tx_full_c : natural := 18; -- r/-: TX FIFO is full |
-- ... |
constant ctrl_uart_rts_en_c : natural := 20; -- r/w: enable hardware flow control: assert rts_o if ready to receive |
constant ctrl_uart_cts_en_c : natural := 21; -- r/w: enable hardware flow control: send only if cts_i is asserted |
constant ctrl_uart_pmode0_c : natural := 22; -- r/w: Parity config (0=even; 1=odd) |
constant ctrl_uart_pmode1_c : natural := 23; -- r/w: Enable parity bit |
constant ctrl_uart_prsc0_c : natural := 24; -- r/w: UART baud prsc bit 0 |
constant ctrl_uart_prsc1_c : natural := 25; -- r/w: UART baud prsc bit 1 |
constant ctrl_uart_prsc2_c : natural := 26; -- r/w: UART baud prsc bit 2 |
constant ctrl_uart_cts_c : natural := 27; -- r/-: current state of CTS input |
constant ctrl_uart_en_c : natural := 28; -- r/w: UART enable |
-- ... |
constant ctrl_uart_tx_busy_c : natural := 31; -- r/-: UART transmitter is busy |
constant ctrl_rts_en_c : natural := 20; -- r/w: enable hardware flow control: assert rts_o if ready to receive |
constant ctrl_cts_en_c : natural := 21; -- r/w: enable hardware flow control: send only if cts_i is asserted |
constant ctrl_pmode0_c : natural := 22; -- r/w: Parity config (0=even; 1=odd) |
constant ctrl_pmode1_c : natural := 23; -- r/w: Enable parity bit |
constant ctrl_prsc0_c : natural := 24; -- r/w: baud prsc bit 0 |
constant ctrl_prsc1_c : natural := 25; -- r/w: baud prsc bit 1 |
constant ctrl_prsc2_c : natural := 26; -- r/w: baud prsc bit 2 |
constant ctrl_cts_c : natural := 27; -- r/-: current state of CTS input |
constant ctrl_en_c : natural := 28; -- r/w: UART enable |
constant ctrl_rx_irq_c : natural := 29; -- r/w: RX IRQ mode: 1=FIFO at least half-full; 0=FIFO not empty |
constant ctrl_tx_irq_c : natural := 30; -- r/w: TX IRQ mode: 1=FIFO less than half-full; 0=FIFO not full |
constant ctrl_tx_busy_c : natural := 31; -- r/-: UART transmitter is busy |
|
-- data register flags -- |
constant data_rx_perr_c : natural := 28; -- r/-: Rx parity error |
constant data_rx_ferr_c : natural := 29; -- r/-: Rx frame error |
constant data_rx_overr_c : natural := 30; -- r/-: Rx data overrun |
constant data_rx_avail_c : natural := 31; -- r/-: Rx data available |
constant data_lsb_c : natural := 0; -- r/-: received char LSB |
constant data_msb_c : natural := 7; -- r/-: received char MSB |
-- ... |
constant data_rx_perr_c : natural := 28; -- r/-: RX parity error |
constant data_rx_ferr_c : natural := 29; -- r/-: RX frame error |
constant data_rx_overr_c : natural := 30; -- r/-: RX data overrun |
constant data_rx_avail_c : natural := 31; -- r/-: RX data available |
|
-- access control -- |
signal acc_en : std_ulogic; -- module access enable |
165,41 → 176,67
signal uart_cts_ff : std_ulogic_vector(1 downto 0); |
signal uart_rts : std_ulogic; |
|
-- uart tx unit -- |
type uart_tx_t is record |
busy : std_ulogic; |
done : std_ulogic; |
bitcnt : std_ulogic_vector(03 downto 0); |
sreg : std_ulogic_vector(10 downto 0); |
baud_cnt : std_ulogic_vector(11 downto 0); |
tx_granted : std_ulogic; -- allowed to start sending when 1 |
cts : std_ulogic; -- allow new transmission when 1 |
-- UART transmitter -- |
type tx_state_t is (S_TX_IDLE, S_TX_GET, S_TX_CHECK, S_TX_TRANSMIT, S_TX_SIM); |
type tx_engine_t is record |
state : tx_state_t; |
busy : std_ulogic; |
bitcnt : std_ulogic_vector(03 downto 0); |
sreg : std_ulogic_vector(10 downto 0); |
baud_cnt : std_ulogic_vector(11 downto 0); |
cts : std_ulogic; -- allow new transmission when 1 |
end record; |
signal uart_tx : uart_tx_t; |
signal tx_engine : tx_engine_t; |
|
-- uart rx unit -- |
type ry_data_buf_t is array (0 to 1) of std_ulogic_vector(07 downto 0); |
type uart_rx_t is record |
-- UART receiver -- |
type rx_state_t is (S_RX_IDLE, S_RX_RECEIVE); |
type rx_engine_t is record |
state : rx_state_t; |
sync : std_ulogic_vector(04 downto 0); |
busy : std_ulogic; |
busy_ff : std_ulogic; |
bitcnt : std_ulogic_vector(03 downto 0); |
sreg : std_ulogic_vector(09 downto 0); |
baud_cnt : std_ulogic_vector(11 downto 0); |
overr : std_ulogic; |
rtr : std_ulogic; -- ready to receive when 1 |
-- |
avail : std_ulogic_vector(02 downto 0); |
data : ry_data_buf_t; |
data_rd : std_ulogic_vector(07 downto 0); |
ferr : std_ulogic_vector(01 downto 0); -- frame error (stop bit not set) |
ferr_rd : std_ulogic; |
perr : std_ulogic_vector(01 downto 0); -- parity error |
perr_rd : std_ulogic; |
end record; |
signal uart_rx : uart_rx_t; |
signal rx_engine : rx_engine_t; |
|
-- TX FIFO -- |
type tx_buffer_t is record |
we : std_ulogic; -- write enable |
re : std_ulogic; -- read enable |
clear : std_ulogic; -- sync reset, high-active |
wdata : std_ulogic_vector(31 downto 0); -- write data |
rdata : std_ulogic_vector(31 downto 0); -- read data |
avail : std_ulogic; -- data available? |
free : std_ulogic; -- free entry available? |
half : std_ulogic; -- half full |
end record; |
signal tx_buffer : tx_buffer_t; |
|
-- RX FIFO -- |
type rx_buffer_t is record |
we : std_ulogic; -- write enable |
re : std_ulogic; -- read enable |
clear : std_ulogic; -- sync reset, high-active |
wdata : std_ulogic_vector(9 downto 0); -- write data |
rdata : std_ulogic_vector(9 downto 0); -- read data |
avail : std_ulogic; -- data available? |
free : std_ulogic; -- free entry available? |
half : std_ulogic; -- half full |
end record; |
signal rx_buffer : rx_buffer_t; |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert not (is_power_of_two_f(UART_RX_FIFO) = false) report "NEORV32 PROCESSOR CONFIG ERROR: UART" & |
cond_sel_string_f(UART_PRIMARY, "0", "1") & " <UART_RX_FIFO> has to be a power of two." severity error; |
assert not (is_power_of_two_f(UART_TX_FIFO) = false) report "NEORV32 PROCESSOR CONFIG ERROR: UART" & |
cond_sel_string_f(UART_PRIMARY, "0", "1") & " <UART_TX_FIFO> has to be a power of two." severity error; |
|
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = uart_id_base_c(hi_abb_c downto lo_abb_c)) else '0'; |
213,39 → 250,52
rw_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
ack_o <= acc_en and (rden_i or wren_i); |
-- bus access acknowledge -- |
ack_o <= wr_en or rd_en; |
|
-- write access -- |
if (wr_en = '1') then |
if (addr = uart_id_ctrl_addr_c) then |
ctrl <= (others => '0'); |
ctrl(ctrl_uart_baud11_c downto ctrl_uart_baud00_c) <= data_i(ctrl_uart_baud11_c downto ctrl_uart_baud00_c); |
ctrl(ctrl_uart_sim_en_c) <= data_i(ctrl_uart_sim_en_c); |
ctrl(ctrl_uart_pmode1_c downto ctrl_uart_pmode0_c) <= data_i(ctrl_uart_pmode1_c downto ctrl_uart_pmode0_c); |
ctrl(ctrl_uart_prsc2_c downto ctrl_uart_prsc0_c) <= data_i(ctrl_uart_prsc2_c downto ctrl_uart_prsc0_c); |
ctrl(ctrl_uart_rts_en_c) <= data_i(ctrl_uart_rts_en_c); |
ctrl(ctrl_uart_cts_en_c) <= data_i(ctrl_uart_cts_en_c); |
ctrl(ctrl_uart_en_c) <= data_i(ctrl_uart_en_c); |
ctrl(ctrl_baud11_c downto ctrl_baud00_c) <= data_i(ctrl_baud11_c downto ctrl_baud00_c); |
ctrl(ctrl_sim_en_c) <= data_i(ctrl_sim_en_c); |
ctrl(ctrl_pmode1_c downto ctrl_pmode0_c) <= data_i(ctrl_pmode1_c downto ctrl_pmode0_c); |
ctrl(ctrl_prsc2_c downto ctrl_prsc0_c) <= data_i(ctrl_prsc2_c downto ctrl_prsc0_c); |
ctrl(ctrl_rts_en_c) <= data_i(ctrl_rts_en_c); |
ctrl(ctrl_cts_en_c) <= data_i(ctrl_cts_en_c); |
ctrl(ctrl_rx_irq_c) <= data_i(ctrl_rx_irq_c); |
ctrl(ctrl_tx_irq_c) <= data_i(ctrl_tx_irq_c); |
ctrl(ctrl_en_c) <= data_i(ctrl_en_c); |
end if; |
end if; |
|
-- read access -- |
data_o <= (others => '0'); |
if (rd_en = '1') then |
if (addr = uart_id_ctrl_addr_c) then |
data_o(ctrl_uart_baud11_c downto ctrl_uart_baud00_c) <= ctrl(ctrl_uart_baud11_c downto ctrl_uart_baud00_c); |
data_o(ctrl_uart_sim_en_c) <= ctrl(ctrl_uart_sim_en_c); |
data_o(ctrl_uart_pmode1_c downto ctrl_uart_pmode0_c) <= ctrl(ctrl_uart_pmode1_c downto ctrl_uart_pmode0_c); |
data_o(ctrl_uart_prsc2_c downto ctrl_uart_prsc0_c) <= ctrl(ctrl_uart_prsc2_c downto ctrl_uart_prsc0_c); |
data_o(ctrl_uart_rts_en_c) <= ctrl(ctrl_uart_rts_en_c); |
data_o(ctrl_uart_cts_en_c) <= ctrl(ctrl_uart_cts_en_c); |
data_o(ctrl_uart_en_c) <= ctrl(ctrl_uart_en_c); |
data_o(ctrl_uart_tx_busy_c) <= uart_tx.busy; |
data_o(ctrl_uart_cts_c) <= uart_cts_ff(1); |
data_o(ctrl_baud11_c downto ctrl_baud00_c) <= ctrl(ctrl_baud11_c downto ctrl_baud00_c); |
data_o(ctrl_sim_en_c) <= ctrl(ctrl_sim_en_c); |
data_o(ctrl_pmode1_c downto ctrl_pmode0_c) <= ctrl(ctrl_pmode1_c downto ctrl_pmode0_c); |
data_o(ctrl_prsc2_c downto ctrl_prsc0_c) <= ctrl(ctrl_prsc2_c downto ctrl_prsc0_c); |
data_o(ctrl_rts_en_c) <= ctrl(ctrl_rts_en_c); |
data_o(ctrl_cts_en_c) <= ctrl(ctrl_cts_en_c); |
data_o(ctrl_rx_empty_c) <= not rx_buffer.avail; |
data_o(ctrl_rx_half_c) <= rx_buffer.half; |
data_o(ctrl_rx_full_c) <= not rx_buffer.free; |
data_o(ctrl_tx_empty_c) <= not tx_buffer.avail; |
data_o(ctrl_tx_half_c) <= tx_buffer.half; |
data_o(ctrl_tx_full_c) <= not tx_buffer.free; |
data_o(ctrl_en_c) <= ctrl(ctrl_en_c); |
data_o(ctrl_rx_irq_c) <= ctrl(ctrl_rx_irq_c) and bool_to_ulogic_f(boolean(UART_RX_FIFO > 1)); -- tie to zero if UART_RX_FIFO = 1 |
data_o(ctrl_tx_irq_c) <= ctrl(ctrl_tx_irq_c) and bool_to_ulogic_f(boolean(UART_TX_FIFO > 1)); -- tie to zero if UART_TX_FIFO = 1 |
data_o(ctrl_tx_busy_c) <= tx_engine.busy; |
data_o(ctrl_cts_c) <= uart_cts_ff(1); |
else -- uart_id_rtx_addr_c |
data_o(data_rx_avail_c) <= or_reduce_f(uart_rx.avail); |
data_o(data_rx_overr_c) <= and_reduce_f(uart_rx.avail); |
data_o(data_rx_ferr_c) <= uart_rx.ferr_rd; |
data_o(data_rx_perr_c) <= uart_rx.perr_rd; |
data_o(7 downto 0) <= uart_rx.data_rd; |
data_o(data_msb_c downto data_lsb_c) <= rx_buffer.rdata(7 downto 0); |
data_o(data_rx_perr_c) <= rx_buffer.rdata(8); |
data_o(data_rx_ferr_c) <= rx_buffer.rdata(9); |
data_o(data_rx_overr_c) <= rx_engine.overr; |
data_o(data_rx_avail_c) <= rx_buffer.avail; -- data available (valid?) |
end if; |
end if; |
end if; |
254,134 → 304,229
-- number of bits to be sampled -- |
-- if parity flag is ENABLED: 11 bit -> "1011" (1 start bit + 8 data bits + 1 parity bit + 1 stop bit) |
-- if parity flag is DISABLED: 10 bit -> "1010" (1 start bit + 8 data bits + 1 stop bit) |
num_bits <= "1011" when (ctrl(ctrl_uart_pmode1_c) = '1') else "1010"; |
num_bits <= "1011" when (ctrl(ctrl_pmode1_c) = '1') else "1010"; |
|
|
-- Clock Selection ------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
-- clock enable -- |
clkgen_en_o <= ctrl(ctrl_uart_en_c); |
clkgen_en_o <= ctrl(ctrl_en_c); |
|
-- uart clock select -- |
uart_clk <= clkgen_i(to_integer(unsigned(ctrl(ctrl_uart_prsc2_c downto ctrl_uart_prsc0_c)))); |
uart_clk <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c)))); |
|
|
-- UART Transmitter ----------------------------------------------------------------------- |
-- TX FIFO -------------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
uart_tx_unit: process(clk_i) |
tx_engine_fifo_inst: neorv32_fifo |
generic map ( |
FIFO_DEPTH => UART_TX_FIFO, -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH => 32, -- size of data elements in fifo (32-bit only for simulation) |
FIFO_RSYNC => false, -- async read |
FIFO_SAFE => true -- safe access |
) |
port map ( |
-- control -- |
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => tx_buffer.clear, -- sync reset, high-active |
level_o => open, |
half_o => tx_buffer.half, -- FIFO at least half-full |
-- write port -- |
wdata_i => tx_buffer.wdata, -- write data |
we_i => tx_buffer.we, -- write enable |
free_o => tx_buffer.free, -- at least one entry is free when set |
-- read port -- |
re_i => tx_buffer.re, -- read enable |
rdata_o => tx_buffer.rdata, -- read data |
avail_o => tx_buffer.avail -- data available when set |
); |
|
-- control -- |
tx_buffer.clear <= not ctrl(ctrl_en_c); |
|
-- write access -- |
tx_buffer.we <= '1' when (wr_en = '1') and (addr = uart_id_rtx_addr_c) else '0'; |
tx_buffer.wdata <= data_i; |
|
|
-- UART Transmitter Engine ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
uart_tx_engine: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- serial engine -- |
uart_tx.done <= '0'; |
if (uart_tx.busy = '0') or (ctrl(ctrl_uart_en_c) = '0') or (ctrl(ctrl_uart_sim_en_c) = '1') then -- idle or disabled or in SIM mode |
uart_tx.busy <= '0'; |
uart_tx.baud_cnt <= ctrl(ctrl_uart_baud11_c downto ctrl_uart_baud00_c); |
uart_tx.bitcnt <= num_bits; |
uart_tx.sreg(0) <= '1'; |
if (wr_en = '1') and (ctrl(ctrl_uart_en_c) = '1') and (addr = uart_id_rtx_addr_c) and (ctrl(ctrl_uart_sim_en_c) = '0') then -- write trigger and not in SIM mode |
if (ctrl(ctrl_uart_pmode1_c) = '1') then -- add parity flag |
uart_tx.sreg <= '1' & (xor_reduce_f(data_i(7 downto 0)) xor ctrl(ctrl_uart_pmode0_c)) & data_i(7 downto 0) & '0'; -- stopbit & parity bit & data & startbit |
else |
uart_tx.sreg <= '1' & '1' & data_i(7 downto 0) & '0'; -- (dummy fill-bit &) stopbit & data & startbit |
end if; |
uart_tx.busy <= '1'; |
end if; |
elsif (uart_clk = '1') and (uart_tx.tx_granted = '1') then |
if (uart_tx.baud_cnt = x"000") then |
uart_tx.baud_cnt <= ctrl(ctrl_uart_baud11_c downto ctrl_uart_baud00_c); |
uart_tx.bitcnt <= std_ulogic_vector(unsigned(uart_tx.bitcnt) - 1); |
uart_tx.sreg <= '1' & uart_tx.sreg(uart_tx.sreg'left downto 1); |
else |
uart_tx.baud_cnt <= std_ulogic_vector(unsigned(uart_tx.baud_cnt) - 1); |
end if; |
if (uart_tx.bitcnt = "0000") then |
uart_tx.busy <= '0'; -- done |
uart_tx.done <= '1'; |
end if; |
-- defaults -- |
uart_txd_o <= '1'; -- keep TX line idle (=high) if waiting for permission to start sending (->CTS) |
tx_buffer.re <= '0'; |
|
-- FSM -- |
if (ctrl(ctrl_en_c) = '0') then -- disabled |
tx_engine.state <= S_TX_IDLE; |
else |
case tx_engine.state is |
|
when S_TX_IDLE => -- wait for new data to send |
-- ------------------------------------------------------------ |
if (tx_buffer.avail = '1') then -- new data available |
if (ctrl(ctrl_sim_en_c) = '0') then -- normal mode |
tx_engine.state <= S_TX_GET; |
else -- simulation mode |
tx_engine.state <= S_TX_SIM; |
end if; |
tx_buffer.re <= '1'; |
end if; |
|
when S_TX_GET => -- get new data from buffer and prepare transmission |
-- ------------------------------------------------------------ |
tx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c); |
tx_engine.bitcnt <= num_bits; |
if (ctrl(ctrl_pmode1_c) = '1') then -- add parity flag |
-- stop bit & parity bit & data (8-bit) & start bit |
tx_engine.sreg <= '1' & (xor_reduce_f(tx_buffer.rdata(7 downto 0)) xor ctrl(ctrl_pmode0_c)) & tx_buffer.rdata(7 downto 0) & '0'; |
else |
-- (dummy fill-bit &) stop bit & data (8-bit) & start bit |
tx_engine.sreg <= '1' & '1' & tx_buffer.rdata(7 downto 0) & '0'; |
end if; |
tx_engine.state <= S_TX_CHECK; |
|
when S_TX_CHECK => -- check if allowed to send |
-- ------------------------------------------------------------ |
if (tx_engine.cts = '1') then -- clear to send |
tx_engine.state <= S_TX_TRANSMIT; |
end if; |
|
when S_TX_TRANSMIT => -- transmit data |
-- ------------------------------------------------------------ |
if (uart_clk = '1') then |
if (tx_engine.baud_cnt = x"000") then |
tx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c); |
tx_engine.bitcnt <= std_ulogic_vector(unsigned(tx_engine.bitcnt) - 1); |
tx_engine.sreg <= '1' & tx_engine.sreg(tx_engine.sreg'left downto 1); |
else |
tx_engine.baud_cnt <= std_ulogic_vector(unsigned(tx_engine.baud_cnt) - 1); |
end if; |
end if; |
uart_txd_o <= tx_engine.sreg(0); |
if (tx_engine.bitcnt = "0000") then -- all bits send? |
tx_engine.state <= S_TX_IDLE; |
end if; |
|
when S_TX_SIM => -- simulation mode output |
-- ------------------------------------------------------------ |
tx_engine.state <= S_TX_IDLE; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
tx_engine.state <= S_TX_IDLE; |
|
end case; |
end if; |
-- transmission granted -- |
if (ctrl(ctrl_uart_en_c) = '0') then -- disabled |
uart_tx.tx_granted <= '0'; |
elsif (uart_tx.done = '1') then |
uart_tx.tx_granted <= '0'; |
elsif (uart_tx.cts = '1') then |
uart_tx.tx_granted <= '1'; |
end if; |
-- transmitter output -- |
uart_txd_o <= uart_tx.sreg(0) or (not uart_tx.tx_granted); -- keep TX line idle (=high) if waiting for permission to start sending (->CTS) |
end if; |
end process uart_tx_unit; |
end process uart_tx_engine; |
|
-- transmitter busy -- |
tx_engine.busy <= '0' when (tx_engine.state = S_TX_IDLE) else '1'; |
|
-- UART Receiver -------------------------------------------------------------------------- |
|
-- UART Receiver Engine ------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
uart_rx_unit: process(clk_i) |
uart_rx_engine: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- input synchronizer -- |
uart_rx.sync <= uart_rxd_i & uart_rx.sync(4 downto 1); |
rx_engine.sync <= uart_rxd_i & rx_engine.sync(4 downto 1); |
|
-- serial engine -- |
if (uart_rx.busy = '0') or (ctrl(ctrl_uart_en_c) = '0') or (ctrl(ctrl_uart_sim_en_c) = '1') then -- idle or disabled or in SIM mode |
uart_rx.busy <= '0'; |
uart_rx.baud_cnt <= '0' & ctrl(ctrl_uart_baud11_c downto ctrl_uart_baud01_c); -- half baud delay at the beginning to sample in the middle of each bit |
uart_rx.bitcnt <= num_bits; |
if (ctrl(ctrl_uart_en_c) = '0') then -- to ensure defined state when reading |
uart_rx.perr <= (others => '0'); |
uart_rx.ferr <= (others => '0'); |
uart_rx.data <= (others => (others => '0')); |
elsif (uart_rx.sync(2 downto 0) = "001") then -- start bit? (falling edge) |
uart_rx.busy <= '1'; |
-- FSM -- |
if (ctrl(ctrl_en_c) = '0') then -- disabled |
rx_engine.overr <= '0'; |
rx_engine.state <= S_RX_IDLE; |
else |
case rx_engine.state is |
|
when S_RX_IDLE => -- idle; prepare receive |
-- ------------------------------------------------------------ |
rx_engine.baud_cnt <= '0' & ctrl(ctrl_baud11_c downto ctrl_baud01_c); -- half baud delay at the beginning to sample in the middle of each bit |
rx_engine.bitcnt <= num_bits; |
if (rx_engine.sync(2 downto 0) = "001") then -- start bit? (falling edge) |
rx_engine.state <= S_RX_RECEIVE; |
end if; |
|
when S_RX_RECEIVE => -- receive data |
-- ------------------------------------------------------------ |
if (uart_clk = '1') then |
if (rx_engine.baud_cnt = x"000") then |
rx_engine.baud_cnt <= ctrl(ctrl_baud11_c downto ctrl_baud00_c); |
rx_engine.bitcnt <= std_ulogic_vector(unsigned(rx_engine.bitcnt) - 1); |
rx_engine.sreg <= rx_engine.sync(0) & rx_engine.sreg(rx_engine.sreg'left downto 1); |
else |
rx_engine.baud_cnt <= std_ulogic_vector(unsigned(rx_engine.baud_cnt) - 1); |
end if; |
end if; |
if (rx_engine.bitcnt = "0000") then -- all bits received? |
rx_engine.state <= S_RX_IDLE; |
end if; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
rx_engine.state <= S_RX_IDLE; |
|
end case; |
|
-- overrun flag -- |
if (rd_en = '1') and (addr = uart_id_rtx_addr_c) then -- clear when reading data register |
rx_engine.overr <= '1'; |
elsif (rx_buffer.we = '1') and (rx_buffer.free = '0') then -- write to full FIFO |
rx_engine.overr <= '0'; |
end if; |
elsif (uart_clk = '1') then |
if (uart_rx.baud_cnt = x"000") then |
uart_rx.baud_cnt <= ctrl(ctrl_uart_baud11_c downto ctrl_uart_baud00_c); |
uart_rx.bitcnt <= std_ulogic_vector(unsigned(uart_rx.bitcnt) - 1); |
uart_rx.sreg <= uart_rx.sync(0) & uart_rx.sreg(uart_rx.sreg'left downto 1); |
else |
uart_rx.baud_cnt <= std_ulogic_vector(unsigned(uart_rx.baud_cnt) - 1); |
end if; |
if (uart_rx.bitcnt = "0000") then |
uart_rx.busy <= '0'; -- done |
-- data buffer (double buffering) -- |
uart_rx.perr(0) <= ctrl(ctrl_uart_pmode1_c) and (xor_reduce_f(uart_rx.sreg(8 downto 0)) xor ctrl(ctrl_uart_pmode0_c)); |
uart_rx.ferr(0) <= not uart_rx.sreg(9); -- check stop bit (error if not set) |
if (ctrl(ctrl_uart_pmode1_c) = '1') then -- add parity flag |
uart_rx.data(0) <= uart_rx.sreg(7 downto 0); |
else |
uart_rx.data(0) <= uart_rx.sreg(8 downto 1); |
end if; |
uart_rx.perr(1) <= uart_rx.perr(0); |
uart_rx.ferr(1) <= uart_rx.ferr(0); |
uart_rx.data(1) <= uart_rx.data(0); |
end if; |
end if; |
|
-- RX available flag -- |
uart_rx.busy_ff <= uart_rx.busy; |
if (ctrl(ctrl_uart_en_c) = '0') then -- disabled |
uart_rx.avail <= "000"; |
elsif ((uart_rx.avail(0) = '1') or (uart_rx.avail(1) = '1')) and (rd_en = '1') and (addr = uart_id_rtx_addr_c) then -- RX read access |
uart_rx.avail <= '0' & '0' & uart_rx.avail(1); |
elsif (uart_rx.busy_ff = '1') and (uart_rx.busy = '0') then -- RX done |
uart_rx.avail <= uart_rx.avail(1 downto 0) & '1'; |
end if; |
end if; |
end process uart_rx_unit; |
end process uart_rx_engine; |
|
-- Receiver double-buffering - buffer read -- |
uart_rx.perr_rd <= uart_rx.perr(1) when (uart_rx.avail(1) = '1') else uart_rx.perr(0); |
uart_rx.ferr_rd <= uart_rx.ferr(1) when (uart_rx.avail(1) = '1') else uart_rx.ferr(0); |
uart_rx.data_rd <= uart_rx.data(1) when (uart_rx.avail(1) = '1') else uart_rx.data(0); |
|
-- RX engine ready for a new char? -- |
uart_rx.rtr <= '1' when (uart_rx.avail(2 downto 0) = "000") and (uart_rx.busy = '0') and (uart_rx.busy_ff = '0') and (ctrl(ctrl_uart_en_c) = '1') else '0'; |
rx_engine.rtr <= '1' when (rx_engine.state = S_RX_IDLE) and (ctrl(ctrl_en_c) = '1') else '0'; |
|
|
-- RX FIFO -------------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
rx_engine_fifo_inst: neorv32_fifo |
generic map ( |
FIFO_DEPTH => UART_RX_FIFO, -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH => 10, -- size of data elements in fifo |
FIFO_RSYNC => false, -- async read |
FIFO_SAFE => true -- safe access |
) |
port map ( |
-- control -- |
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => rx_buffer.clear, -- sync reset, high-active |
level_o => open, |
half_o => rx_buffer.half, -- FIFO at least half-full |
-- write port -- |
wdata_i => rx_buffer.wdata, -- write data |
we_i => rx_buffer.we, -- write enable |
free_o => rx_buffer.free, -- at least one entry is free when set |
-- read port -- |
re_i => rx_buffer.re, -- read enable |
rdata_o => rx_buffer.rdata, -- read data |
avail_o => rx_buffer.avail -- data available when set |
); |
|
-- control -- |
rx_buffer.clear <= not ctrl(ctrl_en_c); |
|
-- read/write access -- |
rx_buffer.wdata(7 downto 0) <= rx_engine.sreg(7 downto 0) when (ctrl(ctrl_pmode1_c) = '1') else rx_engine.sreg(8 downto 1); -- RX data |
rx_buffer.wdata(8) <= ctrl(ctrl_pmode1_c) and (xor_reduce_f(rx_engine.sreg(8 downto 0)) xor ctrl(ctrl_pmode0_c)); -- parity error flag |
rx_buffer.wdata(9) <= not rx_engine.sreg(9); -- frame error flag: check stop bit (error if not set) |
rx_buffer.we <= '1' when (rx_engine.bitcnt = "0000") and (rx_engine.state = S_RX_RECEIVE) else '0'; -- RX complete |
rx_buffer.re <= '1' when (rd_en = '1') and (addr = uart_id_rtx_addr_c) else '0'; |
|
|
-- Hardware Flow Control ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
uart_tx.cts <= (not uart_cts_ff(1)) when (ctrl(ctrl_uart_cts_en_c) = '1') else '1'; -- input is low-active, internal signal is high-active |
uart_rts <= (not uart_rx.rtr) when (ctrl(ctrl_uart_rts_en_c) = '1') else '0'; -- output is low-active |
tx_engine.cts <= (not uart_cts_ff(1)) when (ctrl(ctrl_cts_en_c) = '1') else '1'; -- input is low-active, internal signal is high-active |
uart_rts <= (not rx_engine.rtr) when (ctrl(ctrl_rts_en_c) = '1') else '0'; -- output is low-active |
|
-- flow-control input/output synchronizer -- |
flow_control_buffer: process(clk_i) |
395,13 → 540,40
|
-- Interrupts ----------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- UART RX data available |
irq_rxd_o <= uart_rx.busy_ff and (not uart_rx.busy); |
-- UART TX complete |
irq_txd_o <= uart_tx.done; |
irq_generator: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (ctrl(ctrl_en_c) = '0') then -- no interrupts when disabled |
irq_txd_o <= '0'; |
irq_rxd_o <= '0'; |
else |
-- TX interrupt -- |
if (UART_TX_FIFO = 1) then |
irq_txd_o <= tx_buffer.free; -- fire IRQ if FIFO is not full |
else |
if (ctrl(ctrl_tx_irq_c) = '1') then |
irq_txd_o <= not tx_buffer.half; -- fire IRQ if FIFO is less than half-full |
else |
irq_txd_o <= tx_buffer.free; -- fire IRQ if FIFO is not full |
end if; |
end if; |
|
-- RX interrupt -- |
if (UART_RX_FIFO = 1) then |
irq_rxd_o <= rx_buffer.avail; -- fire IRQ if FIFO is not empty |
else |
if (ctrl(ctrl_rx_irq_c) = '1') then |
irq_rxd_o <= rx_buffer.half; -- fire IRQ if FIFO is at least half-full |
else |
irq_rxd_o <= rx_buffer.avail; -- fire IRQ is FIFO is not empty |
end if; |
end if; |
end if; |
end if; |
end process irq_generator; |
|
-- SIMULATION Output ---------------------------------------------------------------------- |
|
-- SIMULATION Transmitter ----------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- pragma translate_off |
-- synthesis translate_off |
415,42 → 587,40
variable line_data_v : line; |
begin |
if rising_edge(clk_i) then |
if (ctrl(ctrl_uart_en_c) = '1') and (ctrl(ctrl_uart_sim_en_c) = '1') then -- UART enabled and simulation output selected? |
if (wr_en = '1') and (addr = uart_id_rtx_addr_c) then -- write access to tx register |
if (tx_engine.state = S_TX_SIM) then -- UART simulation mode |
|
-- print lowest byte to ASCII char -- |
char_v := to_integer(unsigned(data_i(7 downto 0))); |
if (char_v >= 128) then -- out of range? |
char_v := 0; |
end if; |
-- print lowest byte as ASCII char -- |
char_v := to_integer(unsigned(tx_buffer.rdata(7 downto 0))); |
if (char_v >= 128) then -- out of range? |
char_v := 0; |
end if; |
|
if (char_v /= 10) and (char_v /= 13) then -- skip line breaks - they are issued via "writeline" |
if (sim_screen_output_en_c = true) then |
write(line_screen_v, character'val(char_v)); |
end if; |
if (sim_text_output_en_c = true) then |
write(line_text_v, character'val(char_v)); |
end if; |
if (char_v /= 10) and (char_v /= 13) then -- skip line breaks - they are issued via "writeline" |
if (sim_screen_output_en_c = true) then |
write(line_screen_v, character'val(char_v)); |
end if; |
|
if (char_v = 10) then -- line break: write to screen and text file |
if (sim_screen_output_en_c = true) then |
writeline(output, line_screen_v); |
end if; |
if (sim_text_output_en_c = true) then |
writeline(file_uart_text_out, line_text_v); |
end if; |
if (sim_text_output_en_c = true) then |
write(line_text_v, character'val(char_v)); |
end if; |
end if; |
|
-- dump raw data as 8 hex char text to file -- |
if (sim_data_output_en_c = true) then |
for x in 7 downto 0 loop |
write(line_data_v, to_hexchar_f(data_i(3+x*4 downto 0+x*4))); -- write in hex form |
end loop; -- x |
writeline(file_uart_data_out, line_data_v); |
if (char_v = 10) then -- line break: write to screen and text file |
if (sim_screen_output_en_c = true) then |
writeline(output, line_screen_v); |
end if; |
if (sim_text_output_en_c = true) then |
writeline(file_uart_text_out, line_text_v); |
end if; |
end if; |
|
-- dump raw data as 8 hex chars to file -- |
if (sim_data_output_en_c = true) then |
for x in 7 downto 0 loop |
write(line_data_v, to_hexchar_f(tx_buffer.rdata(3+x*4 downto 0+x*4))); -- write in hex form |
end loop; -- x |
writeline(file_uart_data_out, line_data_v); |
end if; |
|
end if; |
end if; |
end process sim_output; |
/neorv32_wdt.vhd
112,6 → 112,14
-- internal reset (sync, low-active) -- |
signal rstn_sync : std_ulogic; |
|
-- cpu interrupt -- |
type cpu_irq_t is record |
pending : std_ulogic; |
set : std_ulogic; |
clr : std_ulogic; |
end record; |
signal cpu_irq : cpu_irq_t; |
|
begin |
|
-- Access Control ------------------------------------------------------------------------- |
132,7 → 140,10
ctrl_reg.mode <= '0'; -- trigger interrupt on WDT overflow |
ctrl_reg.clk_sel <= (others => '1'); -- slowest clock source |
ctrl_reg.lock <= '0'; |
cpu_irq.clr <= '-'; |
elsif rising_edge(clk_i) then |
-- acknowledge interrupt when resetting WDT -- |
cpu_irq.clr <= ctrl_reg.reset; |
if (rstn_sync = '0') then -- internal reset |
ctrl_reg.reset <= '0'; |
ctrl_reg.enforce <= '0'; |
178,10 → 189,33
end process wdt_counter; |
|
-- action trigger -- |
irq_o <= ctrl_reg.enable and (wdt_cnt(wdt_cnt'left) or ctrl_reg.enforce) and (not ctrl_reg.mode); -- mode 0: IRQ |
hw_rst <= ctrl_reg.enable and (wdt_cnt(wdt_cnt'left) or ctrl_reg.enforce) and ( ctrl_reg.mode); -- mode 1: RESET |
cpu_irq.set <= ctrl_reg.enable and (wdt_cnt(wdt_cnt'left) or ctrl_reg.enforce) and (not ctrl_reg.mode); -- mode 0: IRQ |
hw_rst <= ctrl_reg.enable and (wdt_cnt(wdt_cnt'left) or ctrl_reg.enforce) and ( ctrl_reg.mode); -- mode 1: RESET |
|
|
-- Interrupt ------------------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
irq_gen: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (ctrl_reg.enable = '0') then |
cpu_irq.pending <= '0'; |
else |
if (cpu_irq.set = '1') then |
cpu_irq.pending <= '1'; |
elsif(cpu_irq.clr = '1') then |
cpu_irq.pending <= '0'; |
else |
cpu_irq.pending <= cpu_irq.pending; |
end if; |
end if; |
end if; |
end process irq_gen; |
|
-- CPU IRQ -- |
irq_o <= cpu_irq.pending; |
|
|
-- Reset Generator & Action Cause Indicator ----------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
reset_generator: process(rstn_i, clk_i) |
/neorv32_xirq.vhd
212,12 → 212,10
irq_arbiter: process(clk_i) |
begin |
if rising_edge(clk_i) then |
cpu_irq_o <= '0'; |
if (irq_run = '0') then -- no active IRQ |
if (irq_fire = '1') then |
cpu_irq_o <= '1'; |
irq_run <= '1'; |
irq_src <= irq_src_nxt; |
irq_run <= '1'; |
irq_src <= irq_src_nxt; |
end if; |
else -- active IRQ, wait for CPU to acknowledge |
if (host_ack = '1') then |
227,5 → 225,8
end if; |
end process irq_arbiter; |
|
-- interrupt request -- |
cpu_irq_o <= irq_run; |
|
|
end neorv32_xirq_rtl; |