OpenCores
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;

powered by: WebSVN 2.1.0

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