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
- from Rev 60 to Rev 61
- ↔ Reverse comparison
Rev 60 → Rev 61
/top_templates/neorv32_top_stdlogic.vhd
File deleted
/top_templates/README.md
File deleted
/top_templates/neorv32_test_setup.vhd
File deleted
/top_templates/neorv32_top_axi4lite.vhd
File deleted
/core/neorv32_nco.vhd
File deleted
/core/neorv32_application_image.vhd
1,1076 → 1,815
-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32 |
-- Auto-generated memory init file (for APPLICATION) from source file <blink_led/main.bin> |
-- Size: 3196 bytes |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
package neorv32_application_image is |
|
type application_init_image_t is array (0 to 1062) of std_ulogic_vector(31 downto 0); |
constant application_init_image : application_init_image_t := ( |
constant application_init_image : mem32_t := ( |
00000000 => x"00000013", |
00000001 => x"00000093", |
00000002 => x"00000113", |
00000003 => x"00000193", |
00000004 => x"00000213", |
00000005 => x"00000293", |
00000006 => x"00000313", |
00000007 => x"00000393", |
00000008 => x"00000713", |
00000009 => x"00000793", |
00000010 => x"80002117", |
00000011 => x"fd410113", |
00000012 => x"ffc17113", |
00000013 => x"00010413", |
00000014 => x"80000197", |
00000015 => x"7c818193", |
00000016 => x"00000517", |
00000017 => x"0fc50513", |
00000018 => x"30551073", |
00000019 => x"34151073", |
00000020 => x"34301073", |
00000021 => x"34201073", |
00000022 => x"30001073", |
00000023 => x"30401073", |
00000024 => x"30601073", |
00000025 => x"ffa00593", |
00000026 => x"32059073", |
00000027 => x"b0001073", |
00000028 => x"b8001073", |
00000029 => x"b0201073", |
00000030 => x"b8201073", |
00000031 => x"00000813", |
00000032 => x"00000893", |
00000033 => x"00000913", |
00000034 => x"00000993", |
00000035 => x"00000a13", |
00000036 => x"00000a93", |
00000037 => x"00000b13", |
00000038 => x"00000b93", |
00000039 => x"00000c13", |
00000040 => x"00000c93", |
00000041 => x"00000d13", |
00000042 => x"00000d93", |
00000043 => x"00000e13", |
00000044 => x"00000e93", |
00000045 => x"00000f13", |
00000046 => x"00000f93", |
00000047 => x"00000417", |
00000048 => x"d4440413", |
00000049 => x"00000497", |
00000050 => x"f3c48493", |
00000051 => x"00042023", |
00000052 => x"00440413", |
00000053 => x"fe941ce3", |
00000054 => x"80000597", |
00000055 => x"f2858593", |
00000056 => x"87818613", |
00000057 => x"00c5d863", |
00000058 => x"00058023", |
00000059 => x"00158593", |
00000060 => x"ff5ff06f", |
00000061 => x"00001597", |
00000062 => x"fa458593", |
00000063 => x"80000617", |
00000064 => x"f0460613", |
00000065 => x"80000697", |
00000066 => x"efc68693", |
00000067 => x"00d65c63", |
00000068 => x"00058703", |
00000069 => x"00e60023", |
00000070 => x"00158593", |
00000071 => x"00160613", |
00000072 => x"fedff06f", |
00000073 => x"00000513", |
00000074 => x"00000593", |
00000075 => x"05c000ef", |
00000076 => x"30047073", |
00000077 => x"10500073", |
00000078 => x"ffdff06f", |
00000079 => x"ff810113", |
00000080 => x"00812023", |
00000081 => x"00912223", |
00000082 => x"34202473", |
00000083 => x"02044663", |
00000084 => x"34102473", |
00000085 => x"00041483", |
00000086 => x"0034f493", |
00000087 => x"00240413", |
00000088 => x"34141073", |
00000089 => x"00300413", |
00000090 => x"00941863", |
00000091 => x"34102473", |
00000092 => x"00240413", |
00000093 => x"34141073", |
00000094 => x"00012403", |
00000095 => x"00412483", |
00000096 => x"00810113", |
00000097 => x"30200073", |
00000098 => x"00005537", |
00000099 => x"ff010113", |
00000100 => x"00000613", |
00000101 => x"00000593", |
00000102 => x"b0050513", |
00000103 => x"00112623", |
00000104 => x"248000ef", |
00000105 => x"1d9000ef", |
00000106 => x"02050063", |
00000107 => x"129000ef", |
00000108 => x"00000513", |
00000109 => x"17d000ef", |
00000001 => x"80002117", |
00000002 => x"ff810113", |
00000003 => x"80000197", |
00000004 => x"7f418193", |
00000005 => x"00000517", |
00000006 => x"12050513", |
00000007 => x"30551073", |
00000008 => x"34151073", |
00000009 => x"30001073", |
00000010 => x"30401073", |
00000011 => x"30601073", |
00000012 => x"ffa00593", |
00000013 => x"32059073", |
00000014 => x"b0001073", |
00000015 => x"b8001073", |
00000016 => x"b0201073", |
00000017 => x"b8201073", |
00000018 => x"00000093", |
00000019 => x"00000213", |
00000020 => x"00000293", |
00000021 => x"00000313", |
00000022 => x"00000393", |
00000023 => x"00000713", |
00000024 => x"00000793", |
00000025 => x"00000813", |
00000026 => x"00000893", |
00000027 => x"00000913", |
00000028 => x"00000993", |
00000029 => x"00000a13", |
00000030 => x"00000a93", |
00000031 => x"00000b13", |
00000032 => x"00000b93", |
00000033 => x"00000c13", |
00000034 => x"00000c93", |
00000035 => x"00000d13", |
00000036 => x"00000d93", |
00000037 => x"00000e13", |
00000038 => x"00000e93", |
00000039 => x"00000f13", |
00000040 => x"00000f93", |
00000041 => x"00000417", |
00000042 => x"d5c40413", |
00000043 => x"00000497", |
00000044 => x"f5448493", |
00000045 => x"00042023", |
00000046 => x"00440413", |
00000047 => x"fe941ce3", |
00000048 => x"80000597", |
00000049 => x"f4058593", |
00000050 => x"87818613", |
00000051 => x"00c5d863", |
00000052 => x"00058023", |
00000053 => x"00158593", |
00000054 => x"ff5ff06f", |
00000055 => x"00001597", |
00000056 => x"ba058593", |
00000057 => x"80000617", |
00000058 => x"f1c60613", |
00000059 => x"80000697", |
00000060 => x"f1468693", |
00000061 => x"00d65c63", |
00000062 => x"00058703", |
00000063 => x"00e60023", |
00000064 => x"00158593", |
00000065 => x"00160613", |
00000066 => x"fedff06f", |
00000067 => x"00000513", |
00000068 => x"00000593", |
00000069 => x"06c000ef", |
00000070 => x"34051073", |
00000071 => x"00000093", |
00000072 => x"00008463", |
00000073 => x"000080e7", |
00000074 => x"30047073", |
00000075 => x"10500073", |
00000076 => x"ffdff06f", |
00000077 => x"ff810113", |
00000078 => x"00812023", |
00000079 => x"00912223", |
00000080 => x"34202473", |
00000081 => x"02044663", |
00000082 => x"34102473", |
00000083 => x"00041483", |
00000084 => x"0034f493", |
00000085 => x"00240413", |
00000086 => x"34141073", |
00000087 => x"00300413", |
00000088 => x"00941863", |
00000089 => x"34102473", |
00000090 => x"00240413", |
00000091 => x"34141073", |
00000092 => x"00012403", |
00000093 => x"00412483", |
00000094 => x"00810113", |
00000095 => x"30200073", |
00000096 => x"00005537", |
00000097 => x"ff010113", |
00000098 => x"00000613", |
00000099 => x"00000593", |
00000100 => x"b0050513", |
00000101 => x"00112623", |
00000102 => x"118000ef", |
00000103 => x"694000ef", |
00000104 => x"00050c63", |
00000105 => x"644000ef", |
00000106 => x"00001537", |
00000107 => x"9d850513", |
00000108 => x"170000ef", |
00000109 => x"020000ef", |
00000110 => x"00001537", |
00000111 => x"d2050513", |
00000112 => x"298000ef", |
00000113 => x"020000ef", |
00000114 => x"00001537", |
00000115 => x"cfc50513", |
00000116 => x"288000ef", |
00000117 => x"00c12083", |
00000111 => x"9b450513", |
00000112 => x"160000ef", |
00000113 => x"00c12083", |
00000114 => x"00100513", |
00000115 => x"01010113", |
00000116 => x"00008067", |
00000117 => x"ff010113", |
00000118 => x"00000513", |
00000119 => x"01010113", |
00000120 => x"00008067", |
00000121 => x"ff010113", |
00000122 => x"00000513", |
00000123 => x"00812423", |
00000124 => x"00112623", |
00000125 => x"00000413", |
00000126 => x"195000ef", |
00000127 => x"0ff47513", |
00000128 => x"18d000ef", |
00000129 => x"0c800513", |
00000130 => x"420000ef", |
00000131 => x"00140413", |
00000132 => x"fedff06f", |
00000133 => x"fd010113", |
00000134 => x"02812423", |
00000135 => x"02912223", |
00000136 => x"03212023", |
00000137 => x"01312e23", |
00000138 => x"01412c23", |
00000139 => x"02112623", |
00000140 => x"01512a23", |
00000141 => x"00001a37", |
00000142 => x"00050493", |
00000143 => x"00058413", |
00000144 => x"00058523", |
00000145 => x"00000993", |
00000146 => x"00410913", |
00000147 => x"d3ca0a13", |
00000148 => x"00a00593", |
00000149 => x"00048513", |
00000150 => x"241000ef", |
00000151 => x"00aa0533", |
00000152 => x"00054783", |
00000153 => x"01390ab3", |
00000154 => x"00048513", |
00000155 => x"00fa8023", |
00000156 => x"00a00593", |
00000157 => x"1dd000ef", |
00000158 => x"00198993", |
00000159 => x"00a00793", |
00000160 => x"00050493", |
00000161 => x"fcf996e3", |
00000162 => x"00090693", |
00000163 => x"00900713", |
00000164 => x"03000613", |
00000165 => x"0096c583", |
00000166 => x"00070793", |
00000167 => x"fff70713", |
00000168 => x"01071713", |
00000169 => x"01075713", |
00000170 => x"00c59a63", |
00000171 => x"000684a3", |
00000172 => x"fff68693", |
00000173 => x"fe0710e3", |
00000174 => x"00000793", |
00000175 => x"00f907b3", |
00000176 => x"00000593", |
00000177 => x"0007c703", |
00000178 => x"00070c63", |
00000179 => x"00158693", |
00000180 => x"00b405b3", |
00000181 => x"00e58023", |
00000182 => x"01069593", |
00000183 => x"0105d593", |
00000184 => x"fff78713", |
00000185 => x"02f91863", |
00000186 => x"00b40433", |
00000187 => x"00040023", |
00000188 => x"02c12083", |
00000189 => x"02812403", |
00000190 => x"02412483", |
00000191 => x"02012903", |
00000192 => x"01c12983", |
00000193 => x"01812a03", |
00000194 => x"01412a83", |
00000195 => x"03010113", |
00000196 => x"00008067", |
00000197 => x"00070793", |
00000198 => x"fadff06f", |
00000199 => x"00001637", |
00000200 => x"00758693", |
00000201 => x"00000713", |
00000202 => x"d4860613", |
00000203 => x"02000813", |
00000204 => x"00e557b3", |
00000205 => x"00f7f793", |
00000206 => x"00f607b3", |
00000207 => x"0007c783", |
00000208 => x"00470713", |
00000209 => x"fff68693", |
00000210 => x"00f680a3", |
00000211 => x"ff0712e3", |
00000212 => x"00058423", |
00000213 => x"00008067", |
00000214 => x"fa002023", |
00000215 => x"fe002703", |
00000216 => x"00151513", |
00000217 => x"00000793", |
00000218 => x"04a77463", |
00000219 => x"000016b7", |
00000220 => x"00000713", |
00000221 => x"ffe68693", |
00000222 => x"04f6e663", |
00000223 => x"00367613", |
00000224 => x"0035f593", |
00000225 => x"fff78793", |
00000226 => x"01461613", |
00000227 => x"00c7e7b3", |
00000228 => x"01659593", |
00000229 => x"01871713", |
00000230 => x"00b7e7b3", |
00000231 => x"00e7e7b3", |
00000232 => x"10000737", |
00000233 => x"00e7e7b3", |
00000234 => x"faf02023", |
00000235 => x"00008067", |
00000236 => x"00178793", |
00000237 => x"01079793", |
00000238 => x"40a70733", |
00000239 => x"0107d793", |
00000240 => x"fa9ff06f", |
00000241 => x"ffe70513", |
00000242 => x"0fd57513", |
00000243 => x"00051a63", |
00000244 => x"0037d793", |
00000245 => x"00170713", |
00000246 => x"0ff77713", |
00000247 => x"f9dff06f", |
00000248 => x"0017d793", |
00000249 => x"ff1ff06f", |
00000250 => x"f71ff06f", |
00000251 => x"fa002783", |
00000252 => x"fe07cee3", |
00000253 => x"faa02223", |
00000254 => x"00008067", |
00000255 => x"ff1ff06f", |
00000256 => x"ff010113", |
00000257 => x"00812423", |
00000258 => x"01212023", |
00000259 => x"00112623", |
00000260 => x"00912223", |
00000261 => x"00050413", |
00000262 => x"00a00913", |
00000263 => x"00044483", |
00000264 => x"00140413", |
00000265 => x"00049e63", |
00000266 => x"00c12083", |
00000267 => x"00812403", |
00000268 => x"00412483", |
00000269 => x"00012903", |
00000270 => x"01010113", |
00000271 => x"00008067", |
00000272 => x"01249663", |
00000273 => x"00d00513", |
00000274 => x"fa5ff0ef", |
00000275 => x"00048513", |
00000276 => x"f9dff0ef", |
00000277 => x"fc9ff06f", |
00000278 => x"fa9ff06f", |
00000279 => x"fa010113", |
00000280 => x"04f12a23", |
00000281 => x"04410793", |
00000282 => x"02812c23", |
00000283 => x"03212823", |
00000284 => x"03412423", |
00000285 => x"03512223", |
00000286 => x"03612023", |
00000287 => x"01712e23", |
00000288 => x"01812c23", |
00000289 => x"01912a23", |
00000290 => x"02112e23", |
00000291 => x"02912a23", |
00000292 => x"03312623", |
00000293 => x"00050413", |
00000294 => x"04b12223", |
00000295 => x"04c12423", |
00000296 => x"04d12623", |
00000297 => x"04e12823", |
00000298 => x"05012c23", |
00000299 => x"05112e23", |
00000300 => x"00f12023", |
00000301 => x"02500a13", |
00000302 => x"00a00a93", |
00000303 => x"07300913", |
00000304 => x"07500b13", |
00000305 => x"07800b93", |
00000306 => x"06300c13", |
00000307 => x"06900c93", |
00000308 => x"00044483", |
00000309 => x"02049c63", |
00000310 => x"03c12083", |
00000311 => x"03812403", |
00000312 => x"03412483", |
00000313 => x"03012903", |
00000314 => x"02c12983", |
00000315 => x"02812a03", |
00000316 => x"02412a83", |
00000317 => x"02012b03", |
00000318 => x"01c12b83", |
00000319 => x"01812c03", |
00000320 => x"01412c83", |
00000321 => x"06010113", |
00000322 => x"00008067", |
00000323 => x"0d449863", |
00000324 => x"00240993", |
00000325 => x"00144403", |
00000326 => x"05240263", |
00000327 => x"00896e63", |
00000328 => x"05840c63", |
00000329 => x"07940663", |
00000330 => x"02500513", |
00000331 => x"ec1ff0ef", |
00000332 => x"00040513", |
00000333 => x"0540006f", |
00000334 => x"09640663", |
00000335 => x"ff7416e3", |
00000336 => x"00012783", |
00000337 => x"00410593", |
00000338 => x"0007a503", |
00000339 => x"00478713", |
00000340 => x"00e12023", |
00000341 => x"dc9ff0ef", |
00000342 => x"0640006f", |
00000343 => x"00012783", |
00000344 => x"0007a503", |
00000345 => x"00478713", |
00000346 => x"00e12023", |
00000347 => x"e95ff0ef", |
00000348 => x"00098413", |
00000349 => x"f5dff06f", |
00000350 => x"00012783", |
00000351 => x"0007c503", |
00000352 => x"00478713", |
00000353 => x"00e12023", |
00000354 => x"e65ff0ef", |
00000355 => x"fe5ff06f", |
00000356 => x"00012783", |
00000357 => x"0007a403", |
00000358 => x"00478713", |
00000359 => x"00e12023", |
00000360 => x"00045863", |
00000361 => x"02d00513", |
00000362 => x"40800433", |
00000363 => x"e41ff0ef", |
00000364 => x"00410593", |
00000365 => x"00040513", |
00000366 => x"c5dff0ef", |
00000367 => x"00410513", |
00000368 => x"fadff06f", |
00000369 => x"00012783", |
00000370 => x"00410593", |
00000371 => x"00478713", |
00000372 => x"0007a503", |
00000373 => x"00e12023", |
00000374 => x"fe1ff06f", |
00000375 => x"01549663", |
00000376 => x"00d00513", |
00000377 => x"e09ff0ef", |
00000378 => x"00140993", |
00000379 => x"00048513", |
00000380 => x"f99ff06f", |
00000381 => x"fd010113", |
00000382 => x"00112623", |
00000383 => x"00b12a23", |
00000384 => x"00c12c23", |
00000385 => x"00d12e23", |
00000386 => x"02e12023", |
00000387 => x"02f12223", |
00000388 => x"03012423", |
00000389 => x"03112623", |
00000390 => x"e45ff0ef", |
00000391 => x"00c12083", |
00000392 => x"03010113", |
00000393 => x"00008067", |
00000394 => x"fe010113", |
00000395 => x"00112e23", |
00000396 => x"00050613", |
00000397 => x"00055863", |
00000398 => x"40a00633", |
00000399 => x"01061613", |
00000400 => x"41065613", |
00000401 => x"fe002503", |
00000402 => x"3e800593", |
00000403 => x"00c12623", |
00000404 => x"600000ef", |
00000405 => x"00c12603", |
00000406 => x"00000593", |
00000407 => x"41f65693", |
00000408 => x"558000ef", |
00000409 => x"01c59593", |
00000410 => x"00455513", |
00000411 => x"00a5e533", |
00000412 => x"00050a63", |
00000413 => x"00050863", |
00000414 => x"fff50513", |
00000415 => x"00000013", |
00000416 => x"ff1ff06f", |
00000417 => x"01c12083", |
00000418 => x"02010113", |
00000419 => x"00008067", |
00000420 => x"fc010113", |
00000421 => x"02112e23", |
00000422 => x"02512c23", |
00000423 => x"02612a23", |
00000424 => x"02712823", |
00000425 => x"02a12623", |
00000426 => x"02b12423", |
00000427 => x"02c12223", |
00000428 => x"02d12023", |
00000429 => x"00e12e23", |
00000430 => x"00f12c23", |
00000431 => x"01012a23", |
00000432 => x"01112823", |
00000433 => x"01c12623", |
00000434 => x"01d12423", |
00000435 => x"01e12223", |
00000436 => x"01f12023", |
00000437 => x"34102773", |
00000438 => x"34071073", |
00000439 => x"342027f3", |
00000440 => x"0807ca63", |
00000441 => x"00071683", |
00000442 => x"00300593", |
00000443 => x"0036f693", |
00000444 => x"00270613", |
00000445 => x"00b69463", |
00000446 => x"00470613", |
00000447 => x"34161073", |
00000448 => x"00b00713", |
00000449 => x"04f77c63", |
00000450 => x"000017b7", |
00000451 => x"90c78793", |
00000452 => x"000780e7", |
00000453 => x"03c12083", |
00000454 => x"03812283", |
00000455 => x"03412303", |
00000456 => x"03012383", |
00000457 => x"02c12503", |
00000458 => x"02812583", |
00000459 => x"02412603", |
00000460 => x"02012683", |
00000461 => x"01c12703", |
00000462 => x"01812783", |
00000463 => x"01412803", |
00000464 => x"01012883", |
00000465 => x"00c12e03", |
00000466 => x"00812e83", |
00000467 => x"00412f03", |
00000468 => x"00012f83", |
00000469 => x"04010113", |
00000470 => x"30200073", |
00000471 => x"00001737", |
00000472 => x"00279793", |
00000473 => x"d5c70713", |
00000474 => x"00e787b3", |
00000475 => x"0007a783", |
00000476 => x"00078067", |
00000477 => x"80000737", |
00000478 => x"00e787b3", |
00000479 => x"01f00713", |
00000480 => x"f8f764e3", |
00000481 => x"00001737", |
00000482 => x"00279793", |
00000483 => x"d8c70713", |
00000484 => x"00e787b3", |
00000485 => x"0007a783", |
00000486 => x"00078067", |
00000487 => x"800007b7", |
00000488 => x"0007a783", |
00000489 => x"f6dff06f", |
00000490 => x"800007b7", |
00000491 => x"0047a783", |
00000492 => x"f61ff06f", |
00000493 => x"800007b7", |
00000494 => x"0087a783", |
00000495 => x"f55ff06f", |
00000119 => x"00000593", |
00000120 => x"00112623", |
00000121 => x"00812423", |
00000122 => x"658000ef", |
00000123 => x"00000513", |
00000124 => x"00150413", |
00000125 => x"00000593", |
00000126 => x"0ff57513", |
00000127 => x"644000ef", |
00000128 => x"0c800513", |
00000129 => x"120000ef", |
00000130 => x"00040513", |
00000131 => x"fe5ff06f", |
00000132 => x"fe802503", |
00000133 => x"01255513", |
00000134 => x"00157513", |
00000135 => x"00008067", |
00000136 => x"fa002023", |
00000137 => x"fe002703", |
00000138 => x"00151513", |
00000139 => x"00000793", |
00000140 => x"04a77463", |
00000141 => x"000016b7", |
00000142 => x"00000713", |
00000143 => x"ffe68693", |
00000144 => x"04f6e663", |
00000145 => x"00367613", |
00000146 => x"0035f593", |
00000147 => x"fff78793", |
00000148 => x"01461613", |
00000149 => x"00c7e7b3", |
00000150 => x"01659593", |
00000151 => x"01871713", |
00000152 => x"00b7e7b3", |
00000153 => x"00e7e7b3", |
00000154 => x"10000737", |
00000155 => x"00e7e7b3", |
00000156 => x"faf02023", |
00000157 => x"00008067", |
00000158 => x"00178793", |
00000159 => x"01079793", |
00000160 => x"40a70733", |
00000161 => x"0107d793", |
00000162 => x"fa9ff06f", |
00000163 => x"ffe70513", |
00000164 => x"0fd57513", |
00000165 => x"00051a63", |
00000166 => x"0037d793", |
00000167 => x"00170713", |
00000168 => x"0ff77713", |
00000169 => x"f9dff06f", |
00000170 => x"0017d793", |
00000171 => x"ff1ff06f", |
00000172 => x"f71ff06f", |
00000173 => x"fa002783", |
00000174 => x"fe07cee3", |
00000175 => x"faa02223", |
00000176 => x"00008067", |
00000177 => x"ff1ff06f", |
00000178 => x"ff010113", |
00000179 => x"00812423", |
00000180 => x"01212023", |
00000181 => x"00112623", |
00000182 => x"00912223", |
00000183 => x"00050413", |
00000184 => x"00a00913", |
00000185 => x"00044483", |
00000186 => x"00140413", |
00000187 => x"00049e63", |
00000188 => x"00c12083", |
00000189 => x"00812403", |
00000190 => x"00412483", |
00000191 => x"00012903", |
00000192 => x"01010113", |
00000193 => x"00008067", |
00000194 => x"01249663", |
00000195 => x"00d00513", |
00000196 => x"fa5ff0ef", |
00000197 => x"00048513", |
00000198 => x"f9dff0ef", |
00000199 => x"fc9ff06f", |
00000200 => x"fa9ff06f", |
00000201 => x"fe010113", |
00000202 => x"00112e23", |
00000203 => x"00050613", |
00000204 => x"00055863", |
00000205 => x"40a00633", |
00000206 => x"01061613", |
00000207 => x"41065613", |
00000208 => x"fe002503", |
00000209 => x"3e800593", |
00000210 => x"00c12623", |
00000211 => x"5bc000ef", |
00000212 => x"00c12603", |
00000213 => x"00000593", |
00000214 => x"41f65693", |
00000215 => x"514000ef", |
00000216 => x"01c59593", |
00000217 => x"00455513", |
00000218 => x"00a5e533", |
00000219 => x"00050a63", |
00000220 => x"00050863", |
00000221 => x"fff50513", |
00000222 => x"00000013", |
00000223 => x"ff1ff06f", |
00000224 => x"01c12083", |
00000225 => x"02010113", |
00000226 => x"00008067", |
00000227 => x"00000000", |
00000228 => x"fc010113", |
00000229 => x"02112e23", |
00000230 => x"02512c23", |
00000231 => x"02612a23", |
00000232 => x"02712823", |
00000233 => x"02a12623", |
00000234 => x"02b12423", |
00000235 => x"02c12223", |
00000236 => x"02d12023", |
00000237 => x"00e12e23", |
00000238 => x"00f12c23", |
00000239 => x"01012a23", |
00000240 => x"01112823", |
00000241 => x"01c12623", |
00000242 => x"01d12423", |
00000243 => x"01e12223", |
00000244 => x"01f12023", |
00000245 => x"34102773", |
00000246 => x"34071073", |
00000247 => x"342027f3", |
00000248 => x"0807c863", |
00000249 => x"00071683", |
00000250 => x"00300593", |
00000251 => x"0036f693", |
00000252 => x"00270613", |
00000253 => x"00b69463", |
00000254 => x"00470613", |
00000255 => x"34161073", |
00000256 => x"00b00713", |
00000257 => x"04f77a63", |
00000258 => x"60800793", |
00000259 => x"000780e7", |
00000260 => x"03c12083", |
00000261 => x"03812283", |
00000262 => x"03412303", |
00000263 => x"03012383", |
00000264 => x"02c12503", |
00000265 => x"02812583", |
00000266 => x"02412603", |
00000267 => x"02012683", |
00000268 => x"01c12703", |
00000269 => x"01812783", |
00000270 => x"01412803", |
00000271 => x"01012883", |
00000272 => x"00c12e03", |
00000273 => x"00812e83", |
00000274 => x"00412f03", |
00000275 => x"00012f83", |
00000276 => x"04010113", |
00000277 => x"30200073", |
00000278 => x"00001737", |
00000279 => x"00279793", |
00000280 => x"9f470713", |
00000281 => x"00e787b3", |
00000282 => x"0007a783", |
00000283 => x"00078067", |
00000284 => x"80000737", |
00000285 => x"00e787b3", |
00000286 => x"01f00713", |
00000287 => x"f8f766e3", |
00000288 => x"00001737", |
00000289 => x"00279793", |
00000290 => x"a2470713", |
00000291 => x"00e787b3", |
00000292 => x"0007a783", |
00000293 => x"00078067", |
00000294 => x"800007b7", |
00000295 => x"0007a783", |
00000296 => x"f6dff06f", |
00000297 => x"800007b7", |
00000298 => x"0047a783", |
00000299 => x"f61ff06f", |
00000300 => x"800007b7", |
00000301 => x"0087a783", |
00000302 => x"f55ff06f", |
00000303 => x"800007b7", |
00000304 => x"00c7a783", |
00000305 => x"f49ff06f", |
00000306 => x"8101a783", |
00000307 => x"f41ff06f", |
00000308 => x"8141a783", |
00000309 => x"f39ff06f", |
00000310 => x"8181a783", |
00000311 => x"f31ff06f", |
00000312 => x"81c1a783", |
00000313 => x"f29ff06f", |
00000314 => x"8201a783", |
00000315 => x"f21ff06f", |
00000316 => x"8241a783", |
00000317 => x"f19ff06f", |
00000318 => x"8281a783", |
00000319 => x"f11ff06f", |
00000320 => x"82c1a783", |
00000321 => x"f09ff06f", |
00000322 => x"8301a783", |
00000323 => x"f01ff06f", |
00000324 => x"8341a783", |
00000325 => x"ef9ff06f", |
00000326 => x"8381a783", |
00000327 => x"ef1ff06f", |
00000328 => x"83c1a783", |
00000329 => x"ee9ff06f", |
00000330 => x"8401a783", |
00000331 => x"ee1ff06f", |
00000332 => x"8441a783", |
00000333 => x"ed9ff06f", |
00000334 => x"8481a783", |
00000335 => x"ed1ff06f", |
00000336 => x"84c1a783", |
00000337 => x"ec9ff06f", |
00000338 => x"8501a783", |
00000339 => x"ec1ff06f", |
00000340 => x"8541a783", |
00000341 => x"eb9ff06f", |
00000342 => x"8581a783", |
00000343 => x"eb1ff06f", |
00000344 => x"85c1a783", |
00000345 => x"ea9ff06f", |
00000346 => x"8601a783", |
00000347 => x"ea1ff06f", |
00000348 => x"8641a783", |
00000349 => x"e99ff06f", |
00000350 => x"8681a783", |
00000351 => x"e91ff06f", |
00000352 => x"86c1a783", |
00000353 => x"e89ff06f", |
00000354 => x"8701a783", |
00000355 => x"e81ff06f", |
00000356 => x"8741a783", |
00000357 => x"e79ff06f", |
00000358 => x"fe010113", |
00000359 => x"01212823", |
00000360 => x"00050913", |
00000361 => x"00001537", |
00000362 => x"00912a23", |
00000363 => x"aa450513", |
00000364 => x"000014b7", |
00000365 => x"00812c23", |
00000366 => x"01312623", |
00000367 => x"00112e23", |
00000368 => x"01c00413", |
00000369 => x"d05ff0ef", |
00000370 => x"c6c48493", |
00000371 => x"ffc00993", |
00000372 => x"008957b3", |
00000373 => x"00f7f793", |
00000374 => x"00f487b3", |
00000375 => x"0007c503", |
00000376 => x"ffc40413", |
00000377 => x"cd1ff0ef", |
00000378 => x"ff3414e3", |
00000379 => x"01c12083", |
00000380 => x"01812403", |
00000381 => x"01412483", |
00000382 => x"01012903", |
00000383 => x"00c12983", |
00000384 => x"02010113", |
00000385 => x"00008067", |
00000386 => x"ff010113", |
00000387 => x"00112623", |
00000388 => x"00812423", |
00000389 => x"00912223", |
00000390 => x"bf9ff0ef", |
00000391 => x"18050463", |
00000392 => x"00001537", |
00000393 => x"aa850513", |
00000394 => x"cf9ff0ef", |
00000395 => x"34202473", |
00000396 => x"00900713", |
00000397 => x"00f47793", |
00000398 => x"03078493", |
00000399 => x"00f77463", |
00000400 => x"05778493", |
00000401 => x"00b00793", |
00000402 => x"0087ee63", |
00000403 => x"00001737", |
00000404 => x"00241793", |
00000405 => x"c3c70713", |
00000406 => x"00e787b3", |
00000407 => x"0007a783", |
00000408 => x"00078067", |
00000409 => x"800007b7", |
00000410 => x"00b78713", |
00000411 => x"12e40663", |
00000412 => x"02876663", |
00000413 => x"00378713", |
00000414 => x"10e40463", |
00000415 => x"00778793", |
00000416 => x"10f40663", |
00000417 => x"00001537", |
00000418 => x"c0850513", |
00000419 => x"c95ff0ef", |
00000420 => x"00040513", |
00000421 => x"f05ff0ef", |
00000422 => x"0380006f", |
00000423 => x"ff07c793", |
00000424 => x"00f407b3", |
00000425 => x"00f00713", |
00000426 => x"fcf76ee3", |
00000427 => x"00001537", |
00000428 => x"bf850513", |
00000429 => x"c6dff0ef", |
00000430 => x"00048513", |
00000431 => x"c09ff0ef", |
00000432 => x"0100006f", |
00000433 => x"00001537", |
00000434 => x"ab050513", |
00000435 => x"c55ff0ef", |
00000436 => x"00001537", |
00000437 => x"c2050513", |
00000438 => x"c49ff0ef", |
00000439 => x"34002573", |
00000440 => x"eb9ff0ef", |
00000441 => x"00001537", |
00000442 => x"c2850513", |
00000443 => x"c35ff0ef", |
00000444 => x"34302573", |
00000445 => x"ea5ff0ef", |
00000446 => x"00812403", |
00000447 => x"00c12083", |
00000448 => x"00412483", |
00000449 => x"00001537", |
00000450 => x"c3450513", |
00000451 => x"01010113", |
00000452 => x"c11ff06f", |
00000453 => x"00001537", |
00000454 => x"ad050513", |
00000455 => x"fb1ff06f", |
00000456 => x"00001537", |
00000457 => x"aec50513", |
00000458 => x"fa5ff06f", |
00000459 => x"00001537", |
00000460 => x"b0050513", |
00000461 => x"f99ff06f", |
00000462 => x"00001537", |
00000463 => x"b0c50513", |
00000464 => x"f8dff06f", |
00000465 => x"00001537", |
00000466 => x"b2450513", |
00000467 => x"f81ff06f", |
00000468 => x"00001537", |
00000469 => x"b3850513", |
00000470 => x"f75ff06f", |
00000471 => x"00001537", |
00000472 => x"b5450513", |
00000473 => x"f69ff06f", |
00000474 => x"00001537", |
00000475 => x"b6850513", |
00000476 => x"f5dff06f", |
00000477 => x"00001537", |
00000478 => x"b8850513", |
00000479 => x"f51ff06f", |
00000480 => x"00001537", |
00000481 => x"ba850513", |
00000482 => x"f45ff06f", |
00000483 => x"00001537", |
00000484 => x"bc450513", |
00000485 => x"f39ff06f", |
00000486 => x"00001537", |
00000487 => x"bdc50513", |
00000488 => x"f2dff06f", |
00000489 => x"00c12083", |
00000490 => x"00812403", |
00000491 => x"00412483", |
00000492 => x"01010113", |
00000493 => x"00008067", |
00000494 => x"01f00793", |
00000495 => x"02a7e263", |
00000496 => x"800007b7", |
00000497 => x"00c7a783", |
00000498 => x"f49ff06f", |
00000499 => x"8101a783", |
00000500 => x"f41ff06f", |
00000501 => x"8141a783", |
00000502 => x"f39ff06f", |
00000503 => x"8181a783", |
00000504 => x"f31ff06f", |
00000505 => x"81c1a783", |
00000506 => x"f29ff06f", |
00000507 => x"8201a783", |
00000508 => x"f21ff06f", |
00000509 => x"8241a783", |
00000510 => x"f19ff06f", |
00000511 => x"8281a783", |
00000512 => x"f11ff06f", |
00000513 => x"82c1a783", |
00000514 => x"f09ff06f", |
00000515 => x"8301a783", |
00000516 => x"f01ff06f", |
00000517 => x"8341a783", |
00000518 => x"ef9ff06f", |
00000519 => x"8381a783", |
00000520 => x"ef1ff06f", |
00000521 => x"83c1a783", |
00000522 => x"ee9ff06f", |
00000523 => x"8401a783", |
00000524 => x"ee1ff06f", |
00000525 => x"8441a783", |
00000526 => x"ed9ff06f", |
00000527 => x"8481a783", |
00000528 => x"ed1ff06f", |
00000529 => x"84c1a783", |
00000530 => x"ec9ff06f", |
00000531 => x"8501a783", |
00000532 => x"ec1ff06f", |
00000533 => x"8541a783", |
00000534 => x"eb9ff06f", |
00000535 => x"8581a783", |
00000536 => x"eb1ff06f", |
00000537 => x"85c1a783", |
00000538 => x"ea9ff06f", |
00000539 => x"8601a783", |
00000540 => x"ea1ff06f", |
00000541 => x"8641a783", |
00000542 => x"e99ff06f", |
00000543 => x"8681a783", |
00000544 => x"e91ff06f", |
00000545 => x"86c1a783", |
00000546 => x"e89ff06f", |
00000547 => x"8701a783", |
00000548 => x"e81ff06f", |
00000549 => x"8741a783", |
00000550 => x"e79ff06f", |
00000551 => x"fe010113", |
00000552 => x"01212823", |
00000553 => x"00050913", |
00000554 => x"00001537", |
00000555 => x"00912a23", |
00000556 => x"e0c50513", |
00000557 => x"000014b7", |
00000558 => x"00812c23", |
00000559 => x"01312623", |
00000560 => x"00112e23", |
00000561 => x"01c00413", |
00000562 => x"b91ff0ef", |
00000563 => x"08848493", |
00000564 => x"ffc00993", |
00000565 => x"008957b3", |
00000566 => x"00f7f793", |
00000567 => x"00f487b3", |
00000568 => x"0007c503", |
00000569 => x"ffc40413", |
00000570 => x"b15ff0ef", |
00000571 => x"ff3414e3", |
00000572 => x"01c12083", |
00000573 => x"01812403", |
00000574 => x"01412483", |
00000575 => x"01012903", |
00000576 => x"00c12983", |
00000577 => x"02010113", |
00000578 => x"00008067", |
00000579 => x"00001537", |
00000580 => x"ff010113", |
00000581 => x"e1050513", |
00000582 => x"00112623", |
00000583 => x"00812423", |
00000584 => x"00912223", |
00000585 => x"b35ff0ef", |
00000586 => x"34202473", |
00000587 => x"00900713", |
00000588 => x"00f47793", |
00000589 => x"05778493", |
00000590 => x"00f76463", |
00000591 => x"03078493", |
00000592 => x"00b00793", |
00000593 => x"0087ee63", |
00000594 => x"00001737", |
00000595 => x"00241793", |
00000596 => x"f9c70713", |
00000597 => x"00e787b3", |
00000598 => x"0007a783", |
00000599 => x"00078067", |
00000600 => x"800007b7", |
00000601 => x"00b78713", |
00000602 => x"12e40663", |
00000603 => x"02876663", |
00000604 => x"00378713", |
00000605 => x"10e40463", |
00000606 => x"00778793", |
00000607 => x"10f40663", |
00000608 => x"00001537", |
00000609 => x"f7050513", |
00000610 => x"ad1ff0ef", |
00000611 => x"00040513", |
00000612 => x"f0dff0ef", |
00000613 => x"0380006f", |
00000614 => x"ff07c793", |
00000615 => x"00f407b3", |
00000616 => x"00f00713", |
00000617 => x"fcf76ee3", |
00000618 => x"00001537", |
00000619 => x"f6050513", |
00000620 => x"aa9ff0ef", |
00000621 => x"00048513", |
00000622 => x"a45ff0ef", |
00000623 => x"0100006f", |
00000624 => x"00001537", |
00000625 => x"e1850513", |
00000626 => x"a91ff0ef", |
00000627 => x"00001537", |
00000628 => x"f8850513", |
00000629 => x"a85ff0ef", |
00000630 => x"34002573", |
00000631 => x"ec1ff0ef", |
00000632 => x"00001537", |
00000633 => x"f9050513", |
00000634 => x"a71ff0ef", |
00000635 => x"34302573", |
00000636 => x"eadff0ef", |
00000637 => x"00812403", |
00000638 => x"00c12083", |
00000639 => x"00412483", |
00000640 => x"00001537", |
00000641 => x"ff850513", |
00000642 => x"01010113", |
00000643 => x"a4dff06f", |
00000644 => x"00001537", |
00000645 => x"e3850513", |
00000646 => x"fb1ff06f", |
00000647 => x"00001537", |
00000648 => x"e5450513", |
00000649 => x"fa5ff06f", |
00000650 => x"00001537", |
00000651 => x"e6850513", |
00000652 => x"f99ff06f", |
00000653 => x"00001537", |
00000654 => x"e7450513", |
00000655 => x"f8dff06f", |
00000656 => x"00001537", |
00000657 => x"e8c50513", |
00000658 => x"f81ff06f", |
00000659 => x"00001537", |
00000660 => x"ea050513", |
00000661 => x"f75ff06f", |
00000662 => x"00001537", |
00000663 => x"ebc50513", |
00000664 => x"f69ff06f", |
00000665 => x"00001537", |
00000666 => x"ed050513", |
00000667 => x"f5dff06f", |
00000668 => x"00001537", |
00000669 => x"ef050513", |
00000670 => x"f51ff06f", |
00000671 => x"00001537", |
00000672 => x"f1050513", |
00000673 => x"f45ff06f", |
00000674 => x"00001537", |
00000675 => x"f2c50513", |
00000676 => x"f39ff06f", |
00000677 => x"00001537", |
00000678 => x"f4450513", |
00000679 => x"f2dff06f", |
00000680 => x"01f00793", |
00000681 => x"02a7e463", |
00000682 => x"800007b7", |
00000683 => x"00078793", |
00000684 => x"00251513", |
00000685 => x"00a78533", |
00000686 => x"000017b7", |
00000687 => x"90c78793", |
00000688 => x"00f52023", |
00000689 => x"00000513", |
00000690 => x"00008067", |
00000691 => x"00100513", |
00000692 => x"00008067", |
00000693 => x"ff010113", |
00000694 => x"00112623", |
00000695 => x"00812423", |
00000696 => x"00912223", |
00000697 => x"301027f3", |
00000698 => x"00079863", |
00000699 => x"00001537", |
00000700 => x"fcc50513", |
00000701 => x"965ff0ef", |
00000702 => x"69000793", |
00000703 => x"30579073", |
00000704 => x"00000413", |
00000705 => x"01e00493", |
00000706 => x"00040513", |
00000707 => x"00140413", |
00000708 => x"0ff47413", |
00000709 => x"f8dff0ef", |
00000710 => x"fe9418e3", |
00000711 => x"00c12083", |
00000712 => x"00812403", |
00000713 => x"00412483", |
00000714 => x"01010113", |
00000715 => x"00008067", |
00000716 => x"ff010113", |
00000717 => x"00112623", |
00000718 => x"00812423", |
00000719 => x"30102673", |
00000720 => x"400005b7", |
00000721 => x"10058593", |
00000722 => x"00b677b3", |
00000723 => x"00000413", |
00000724 => x"00b78c63", |
00000725 => x"00100413", |
00000726 => x"00051863", |
00000727 => x"00001537", |
00000728 => x"00050513", |
00000729 => x"a91ff0ef", |
00000730 => x"00c12083", |
00000731 => x"00040513", |
00000732 => x"00812403", |
00000733 => x"01010113", |
00000734 => x"00008067", |
00000735 => x"fe802503", |
00000736 => x"01055513", |
00000737 => x"00157513", |
00000738 => x"00008067", |
00000739 => x"f8a02223", |
00000740 => x"00008067", |
00000741 => x"00050613", |
00000742 => x"00000513", |
00000743 => x"0015f693", |
00000744 => x"00068463", |
00000745 => x"00c50533", |
00000746 => x"0015d593", |
00000747 => x"00161613", |
00000748 => x"fe0596e3", |
00000749 => x"00008067", |
00000750 => x"00050313", |
00000751 => x"ff010113", |
00000752 => x"00060513", |
00000753 => x"00068893", |
00000754 => x"00112623", |
00000755 => x"00030613", |
00000756 => x"00050693", |
00000757 => x"00000713", |
00000758 => x"00000793", |
00000759 => x"00000813", |
00000760 => x"0016fe13", |
00000761 => x"00171e93", |
00000762 => x"000e0c63", |
00000763 => x"01060e33", |
00000764 => x"010e3833", |
00000765 => x"00e787b3", |
00000766 => x"00f807b3", |
00000767 => x"000e0813", |
00000768 => x"01f65713", |
00000769 => x"0016d693", |
00000770 => x"00eee733", |
00000771 => x"00161613", |
00000772 => x"fc0698e3", |
00000773 => x"00058663", |
00000774 => x"f7dff0ef", |
00000775 => x"00a787b3", |
00000776 => x"00088a63", |
00000777 => x"00030513", |
00000778 => x"00088593", |
00000779 => x"f69ff0ef", |
00000780 => x"00f507b3", |
00000781 => x"00c12083", |
00000782 => x"00080513", |
00000783 => x"00078593", |
00000784 => x"01010113", |
00000785 => x"00008067", |
00000786 => x"06054063", |
00000787 => x"0605c663", |
00000788 => x"00058613", |
00000789 => x"00050593", |
00000790 => x"fff00513", |
00000791 => x"02060c63", |
00000792 => x"00100693", |
00000793 => x"00b67a63", |
00000794 => x"00c05863", |
00000795 => x"00161613", |
00000796 => x"00169693", |
00000797 => x"feb66ae3", |
00000798 => x"00000513", |
00000799 => x"00c5e663", |
00000800 => x"40c585b3", |
00000801 => x"00d56533", |
00000802 => x"0016d693", |
00000803 => x"00165613", |
00000804 => x"fe0696e3", |
00000805 => x"00008067", |
00000806 => x"00008293", |
00000807 => x"fb5ff0ef", |
00000808 => x"00058513", |
00000809 => x"00028067", |
00000810 => x"40a00533", |
00000811 => x"00b04863", |
00000812 => x"40b005b3", |
00000813 => x"f9dff06f", |
00000814 => x"40b005b3", |
00000815 => x"00008293", |
00000816 => x"f91ff0ef", |
00000817 => x"40a00533", |
00000818 => x"00028067", |
00000819 => x"00008293", |
00000820 => x"0005ca63", |
00000821 => x"00054c63", |
00000822 => x"f79ff0ef", |
00000823 => x"00058513", |
00000824 => x"00028067", |
00000825 => x"40b005b3", |
00000826 => x"fe0558e3", |
00000827 => x"40a00533", |
00000828 => x"f61ff0ef", |
00000829 => x"40b00533", |
00000830 => x"00028067", |
00000831 => x"6f727245", |
00000832 => x"4e202172", |
00000833 => x"5047206f", |
00000834 => x"75204f49", |
00000835 => x"2074696e", |
00000836 => x"746e7973", |
00000837 => x"69736568", |
00000838 => x"2164657a", |
00000839 => x"0000000a", |
00000840 => x"6e696c42", |
00000841 => x"676e696b", |
00000842 => x"44454c20", |
00000843 => x"6d656420", |
00000844 => x"7270206f", |
00000845 => x"6172676f", |
00000846 => x"00000a6d", |
00000847 => x"33323130", |
00000848 => x"37363534", |
00000849 => x"00003938", |
00000850 => x"33323130", |
00000851 => x"37363534", |
00000852 => x"62613938", |
00000853 => x"66656463", |
00000854 => x"00000000", |
00000855 => x"0000079c", |
00000856 => x"000007a8", |
00000857 => x"000007b4", |
00000858 => x"000007c0", |
00000859 => x"000007cc", |
00000860 => x"000007d4", |
00000861 => x"000007dc", |
00000862 => x"000007e4", |
00000863 => x"000007ec", |
00000864 => x"00000708", |
00000865 => x"00000708", |
00000866 => x"000007f4", |
00000867 => x"000007fc", |
00000868 => x"00000708", |
00000869 => x"00000708", |
00000870 => x"00000804", |
00000871 => x"00000708", |
00000872 => x"00000708", |
00000873 => x"00000708", |
00000874 => x"0000080c", |
00000875 => x"00000708", |
00000876 => x"00000708", |
00000877 => x"00000708", |
00000878 => x"00000814", |
00000879 => x"00000708", |
00000880 => x"00000708", |
00000881 => x"00000708", |
00000882 => x"00000708", |
00000883 => x"0000081c", |
00000884 => x"00000824", |
00000885 => x"0000082c", |
00000886 => x"00000834", |
00000887 => x"0000083c", |
00000888 => x"00000844", |
00000889 => x"0000084c", |
00000890 => x"00000854", |
00000891 => x"0000085c", |
00000892 => x"00000864", |
00000893 => x"0000086c", |
00000894 => x"00000874", |
00000895 => x"0000087c", |
00000896 => x"00000884", |
00000897 => x"0000088c", |
00000898 => x"00000894", |
00000899 => x"00007830", |
00000900 => x"4554523c", |
00000901 => x"0000203e", |
00000902 => x"74736e49", |
00000903 => x"74637572", |
00000904 => x"206e6f69", |
00000905 => x"72646461", |
00000906 => x"20737365", |
00000907 => x"6173696d", |
00000908 => x"6e67696c", |
00000909 => x"00006465", |
00000910 => x"74736e49", |
00000911 => x"74637572", |
00000912 => x"206e6f69", |
00000913 => x"65636361", |
00000914 => x"66207373", |
00000915 => x"746c7561", |
00000916 => x"00000000", |
00000917 => x"656c6c49", |
00000918 => x"206c6167", |
00000919 => x"74736e69", |
00000920 => x"74637572", |
00000921 => x"006e6f69", |
00000922 => x"61657242", |
00000923 => x"696f706b", |
00000924 => x"0000746e", |
00000925 => x"64616f4c", |
00000926 => x"64646120", |
00000927 => x"73736572", |
00000928 => x"73696d20", |
00000929 => x"67696c61", |
00000930 => x"0064656e", |
00000931 => x"64616f4c", |
00000932 => x"63636120", |
00000933 => x"20737365", |
00000934 => x"6c756166", |
00000935 => x"00000074", |
00000936 => x"726f7453", |
00000937 => x"64612065", |
00000938 => x"73657264", |
00000939 => x"696d2073", |
00000940 => x"696c6173", |
00000941 => x"64656e67", |
00000942 => x"00000000", |
00000943 => x"726f7453", |
00000944 => x"63612065", |
00000945 => x"73736563", |
00000946 => x"75616620", |
00000947 => x"0000746c", |
00000948 => x"69766e45", |
00000949 => x"6d6e6f72", |
00000950 => x"20746e65", |
00000951 => x"6c6c6163", |
00000952 => x"6f726620", |
00000953 => x"2d55206d", |
00000954 => x"65646f6d", |
00000955 => x"00000000", |
00000956 => x"69766e45", |
00000957 => x"6d6e6f72", |
00000958 => x"20746e65", |
00000959 => x"6c6c6163", |
00000960 => x"6f726620", |
00000961 => x"2d4d206d", |
00000962 => x"65646f6d", |
00000963 => x"00000000", |
00000964 => x"6863614d", |
00000965 => x"20656e69", |
00000966 => x"74666f73", |
00000967 => x"65726177", |
00000968 => x"746e6920", |
00000969 => x"75727265", |
00000970 => x"00007470", |
00000971 => x"6863614d", |
00000972 => x"20656e69", |
00000973 => x"656d6974", |
00000974 => x"6e692072", |
00000975 => x"72726574", |
00000976 => x"00747075", |
00000977 => x"6863614d", |
00000978 => x"20656e69", |
00000979 => x"65747865", |
00000980 => x"6c616e72", |
00000981 => x"746e6920", |
00000982 => x"75727265", |
00000983 => x"00007470", |
00000984 => x"74736146", |
00000985 => x"746e6920", |
00000986 => x"75727265", |
00000987 => x"00207470", |
00000988 => x"6e6b6e55", |
00000989 => x"206e776f", |
00000990 => x"70617274", |
00000991 => x"75616320", |
00000992 => x"203a6573", |
00000993 => x"00000000", |
00000994 => x"50204020", |
00000995 => x"00003d43", |
00000996 => x"544d202c", |
00000997 => x"3d4c4156", |
00000998 => x"00000000", |
00000999 => x"000009c0", |
00001000 => x"00000a10", |
00001001 => x"00000a1c", |
00001002 => x"00000a28", |
00001003 => x"00000a34", |
00001004 => x"00000a40", |
00001005 => x"00000a4c", |
00001006 => x"00000a58", |
00001007 => x"00000a64", |
00001008 => x"00000980", |
00001009 => x"00000980", |
00001010 => x"00000a70", |
00001011 => x"4554523c", |
00001012 => x"4157203e", |
00001013 => x"4e494e52", |
00001014 => x"43202147", |
00001015 => x"43205550", |
00001016 => x"73205253", |
00001017 => x"65747379", |
00001018 => x"6f6e206d", |
00001019 => x"76612074", |
00001020 => x"616c6961", |
00001021 => x"21656c62", |
00001022 => x"522f3c20", |
00001023 => x"003e4554", |
00001024 => x"5241570a", |
00001025 => x"474e494e", |
00001026 => x"57532021", |
00001027 => x"4153495f", |
00001028 => x"65662820", |
00001029 => x"72757461", |
00001030 => x"72207365", |
00001031 => x"69757165", |
00001032 => x"29646572", |
00001033 => x"20737620", |
00001034 => x"495f5748", |
00001035 => x"28204153", |
00001036 => x"74616566", |
00001037 => x"73657275", |
00001038 => x"61766120", |
00001039 => x"62616c69", |
00001040 => x"2029656c", |
00001041 => x"6d73696d", |
00001042 => x"68637461", |
00001043 => x"57530a21", |
00001044 => x"4153495f", |
00001045 => x"30203d20", |
00001046 => x"20782578", |
00001047 => x"6d6f6328", |
00001048 => x"656c6970", |
00001049 => x"6c662072", |
00001050 => x"29736761", |
00001051 => x"5f57480a", |
00001052 => x"20415349", |
00001053 => x"7830203d", |
00001054 => x"28207825", |
00001055 => x"6173696d", |
00001056 => x"72736320", |
00001057 => x"000a0a29", |
00001058 => x"33323130", |
00001059 => x"37363534", |
00001060 => x"42413938", |
00001061 => x"46454443", |
others => x"00000000" |
00000497 => x"00078793", |
00000498 => x"00251513", |
00000499 => x"00a78533", |
00000500 => x"60800793", |
00000501 => x"00f52023", |
00000502 => x"00000513", |
00000503 => x"00008067", |
00000504 => x"00100513", |
00000505 => x"00008067", |
00000506 => x"ff010113", |
00000507 => x"00112623", |
00000508 => x"00812423", |
00000509 => x"00912223", |
00000510 => x"39000793", |
00000511 => x"30579073", |
00000512 => x"00000413", |
00000513 => x"01e00493", |
00000514 => x"00040513", |
00000515 => x"00140413", |
00000516 => x"0ff47413", |
00000517 => x"fa5ff0ef", |
00000518 => x"fe9418e3", |
00000519 => x"00c12083", |
00000520 => x"00812403", |
00000521 => x"00412483", |
00000522 => x"01010113", |
00000523 => x"00008067", |
00000524 => x"fe802503", |
00000525 => x"01055513", |
00000526 => x"00157513", |
00000527 => x"00008067", |
00000528 => x"fca02423", |
00000529 => x"fcb02623", |
00000530 => x"00008067", |
00000531 => x"00050613", |
00000532 => x"00000513", |
00000533 => x"0015f693", |
00000534 => x"00068463", |
00000535 => x"00c50533", |
00000536 => x"0015d593", |
00000537 => x"00161613", |
00000538 => x"fe0596e3", |
00000539 => x"00008067", |
00000540 => x"00050313", |
00000541 => x"ff010113", |
00000542 => x"00060513", |
00000543 => x"00068893", |
00000544 => x"00112623", |
00000545 => x"00030613", |
00000546 => x"00050693", |
00000547 => x"00000713", |
00000548 => x"00000793", |
00000549 => x"00000813", |
00000550 => x"0016fe13", |
00000551 => x"00171e93", |
00000552 => x"000e0c63", |
00000553 => x"01060e33", |
00000554 => x"010e3833", |
00000555 => x"00e787b3", |
00000556 => x"00f807b3", |
00000557 => x"000e0813", |
00000558 => x"01f65713", |
00000559 => x"0016d693", |
00000560 => x"00eee733", |
00000561 => x"00161613", |
00000562 => x"fc0698e3", |
00000563 => x"00058663", |
00000564 => x"f7dff0ef", |
00000565 => x"00a787b3", |
00000566 => x"00088a63", |
00000567 => x"00030513", |
00000568 => x"00088593", |
00000569 => x"f69ff0ef", |
00000570 => x"00f507b3", |
00000571 => x"00c12083", |
00000572 => x"00080513", |
00000573 => x"00078593", |
00000574 => x"01010113", |
00000575 => x"00008067", |
00000576 => x"06054063", |
00000577 => x"0605c663", |
00000578 => x"00058613", |
00000579 => x"00050593", |
00000580 => x"fff00513", |
00000581 => x"02060c63", |
00000582 => x"00100693", |
00000583 => x"00b67a63", |
00000584 => x"00c05863", |
00000585 => x"00161613", |
00000586 => x"00169693", |
00000587 => x"feb66ae3", |
00000588 => x"00000513", |
00000589 => x"00c5e663", |
00000590 => x"40c585b3", |
00000591 => x"00d56533", |
00000592 => x"0016d693", |
00000593 => x"00165613", |
00000594 => x"fe0696e3", |
00000595 => x"00008067", |
00000596 => x"00008293", |
00000597 => x"fb5ff0ef", |
00000598 => x"00058513", |
00000599 => x"00028067", |
00000600 => x"40a00533", |
00000601 => x"00b04863", |
00000602 => x"40b005b3", |
00000603 => x"f9dff06f", |
00000604 => x"40b005b3", |
00000605 => x"00008293", |
00000606 => x"f91ff0ef", |
00000607 => x"40a00533", |
00000608 => x"00028067", |
00000609 => x"00008293", |
00000610 => x"0005ca63", |
00000611 => x"00054c63", |
00000612 => x"f79ff0ef", |
00000613 => x"00058513", |
00000614 => x"00028067", |
00000615 => x"40b005b3", |
00000616 => x"fe0558e3", |
00000617 => x"40a00533", |
00000618 => x"f61ff0ef", |
00000619 => x"40b00533", |
00000620 => x"00028067", |
00000621 => x"6f727245", |
00000622 => x"4e202172", |
00000623 => x"5047206f", |
00000624 => x"75204f49", |
00000625 => x"2074696e", |
00000626 => x"746e7973", |
00000627 => x"69736568", |
00000628 => x"2164657a", |
00000629 => x"0000000a", |
00000630 => x"6e696c42", |
00000631 => x"676e696b", |
00000632 => x"44454c20", |
00000633 => x"6d656420", |
00000634 => x"7270206f", |
00000635 => x"6172676f", |
00000636 => x"00000a6d", |
00000637 => x"00000498", |
00000638 => x"000004a4", |
00000639 => x"000004b0", |
00000640 => x"000004bc", |
00000641 => x"000004c8", |
00000642 => x"000004d0", |
00000643 => x"000004d8", |
00000644 => x"000004e0", |
00000645 => x"000004e8", |
00000646 => x"00000408", |
00000647 => x"00000408", |
00000648 => x"000004f0", |
00000649 => x"000004f8", |
00000650 => x"00000408", |
00000651 => x"00000408", |
00000652 => x"00000500", |
00000653 => x"00000408", |
00000654 => x"00000408", |
00000655 => x"00000408", |
00000656 => x"00000508", |
00000657 => x"00000408", |
00000658 => x"00000408", |
00000659 => x"00000408", |
00000660 => x"00000510", |
00000661 => x"00000408", |
00000662 => x"00000408", |
00000663 => x"00000408", |
00000664 => x"00000408", |
00000665 => x"00000518", |
00000666 => x"00000520", |
00000667 => x"00000528", |
00000668 => x"00000530", |
00000669 => x"00000538", |
00000670 => x"00000540", |
00000671 => x"00000548", |
00000672 => x"00000550", |
00000673 => x"00000558", |
00000674 => x"00000560", |
00000675 => x"00000568", |
00000676 => x"00000570", |
00000677 => x"00000578", |
00000678 => x"00000580", |
00000679 => x"00000588", |
00000680 => x"00000590", |
00000681 => x"00007830", |
00000682 => x"4554523c", |
00000683 => x"0000203e", |
00000684 => x"74736e49", |
00000685 => x"74637572", |
00000686 => x"206e6f69", |
00000687 => x"72646461", |
00000688 => x"20737365", |
00000689 => x"6173696d", |
00000690 => x"6e67696c", |
00000691 => x"00006465", |
00000692 => x"74736e49", |
00000693 => x"74637572", |
00000694 => x"206e6f69", |
00000695 => x"65636361", |
00000696 => x"66207373", |
00000697 => x"746c7561", |
00000698 => x"00000000", |
00000699 => x"656c6c49", |
00000700 => x"206c6167", |
00000701 => x"74736e69", |
00000702 => x"74637572", |
00000703 => x"006e6f69", |
00000704 => x"61657242", |
00000705 => x"696f706b", |
00000706 => x"0000746e", |
00000707 => x"64616f4c", |
00000708 => x"64646120", |
00000709 => x"73736572", |
00000710 => x"73696d20", |
00000711 => x"67696c61", |
00000712 => x"0064656e", |
00000713 => x"64616f4c", |
00000714 => x"63636120", |
00000715 => x"20737365", |
00000716 => x"6c756166", |
00000717 => x"00000074", |
00000718 => x"726f7453", |
00000719 => x"64612065", |
00000720 => x"73657264", |
00000721 => x"696d2073", |
00000722 => x"696c6173", |
00000723 => x"64656e67", |
00000724 => x"00000000", |
00000725 => x"726f7453", |
00000726 => x"63612065", |
00000727 => x"73736563", |
00000728 => x"75616620", |
00000729 => x"0000746c", |
00000730 => x"69766e45", |
00000731 => x"6d6e6f72", |
00000732 => x"20746e65", |
00000733 => x"6c6c6163", |
00000734 => x"6f726620", |
00000735 => x"2d55206d", |
00000736 => x"65646f6d", |
00000737 => x"00000000", |
00000738 => x"69766e45", |
00000739 => x"6d6e6f72", |
00000740 => x"20746e65", |
00000741 => x"6c6c6163", |
00000742 => x"6f726620", |
00000743 => x"2d4d206d", |
00000744 => x"65646f6d", |
00000745 => x"00000000", |
00000746 => x"6863614d", |
00000747 => x"20656e69", |
00000748 => x"74666f73", |
00000749 => x"65726177", |
00000750 => x"746e6920", |
00000751 => x"75727265", |
00000752 => x"00007470", |
00000753 => x"6863614d", |
00000754 => x"20656e69", |
00000755 => x"656d6974", |
00000756 => x"6e692072", |
00000757 => x"72726574", |
00000758 => x"00747075", |
00000759 => x"6863614d", |
00000760 => x"20656e69", |
00000761 => x"65747865", |
00000762 => x"6c616e72", |
00000763 => x"746e6920", |
00000764 => x"75727265", |
00000765 => x"00007470", |
00000766 => x"74736146", |
00000767 => x"746e6920", |
00000768 => x"75727265", |
00000769 => x"00207470", |
00000770 => x"6e6b6e55", |
00000771 => x"206e776f", |
00000772 => x"70617274", |
00000773 => x"75616320", |
00000774 => x"203a6573", |
00000775 => x"00000000", |
00000776 => x"50204020", |
00000777 => x"00003d43", |
00000778 => x"544d202c", |
00000779 => x"3d4c4156", |
00000780 => x"00000000", |
00000781 => x"522f3c20", |
00000782 => x"003e4554", |
00000783 => x"000006c4", |
00000784 => x"00000714", |
00000785 => x"00000720", |
00000786 => x"0000072c", |
00000787 => x"00000738", |
00000788 => x"00000744", |
00000789 => x"00000750", |
00000790 => x"0000075c", |
00000791 => x"00000768", |
00000792 => x"00000684", |
00000793 => x"00000684", |
00000794 => x"00000774", |
00000795 => x"33323130", |
00000796 => x"37363534", |
00000797 => x"42413938", |
00000798 => x"46454443" |
); |
|
end neorv32_application_image; |
/core/neorv32_boot_rom.vhd
42,8 → 42,7
|
entity neorv32_boot_rom is |
generic ( |
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000"; -- boot ROM base address |
BOOTROM_SIZE : natural := 4*1024 -- processor-internal boot ROM memory size in bytes |
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000" -- boot ROM base address |
); |
port ( |
clk_i : in std_ulogic; -- global clock line |
56,36 → 55,35
|
architecture neorv32_boot_rom_rtl of neorv32_boot_rom is |
|
-- local types -- |
type boot_img_t is array (0 to BOOTROM_SIZE/4-1) of std_ulogic_vector(31 downto 0); |
-- determine required ROM size in bytes (expand to next power of two) -- |
constant boot_rom_size_index_c : natural := index_size_f((bootloader_init_image'length)); -- address with (32-bit entries) |
constant boot_rom_size_c : natural := (2**boot_rom_size_index_c)*4; -- size in bytes |
|
-- init function -- |
-- impure function: returns NOT the same result every time it is evaluated with the same arguments since the source file might have changed |
impure function init_boot_rom(init : bootloader_init_image_t) return boot_img_t is |
variable mem_v : boot_img_t; |
begin |
mem_v := (others => (others => '0')); |
for i in 0 to init'length-1 loop -- init only in range of source data array |
mem_v(i) := init(i); |
end loop; -- i |
return mem_v; |
end function init_boot_rom; |
-- IO space: module base address -- |
constant hi_abb_c : natural := 31; -- high address boundary bit |
constant lo_abb_c : natural := index_size_f(boot_rom_max_size_c); -- low address boundary bit |
|
-- local signals -- |
signal acc_en : std_ulogic; |
signal rden : std_ulogic; |
signal rdata : std_ulogic_vector(31 downto 0); |
signal addr : std_ulogic_vector(index_size_f(BOOTROM_SIZE/4)-1 downto 0); |
signal addr : std_ulogic_vector(boot_rom_size_index_c-1 downto 0); |
|
-- bootloader image -- |
constant boot_img : boot_img_t := init_boot_rom(bootloader_init_image); |
-- ROM - initialized with executable code -- |
constant mem_rom : mem32_t(0 to boot_rom_size_c/4-1) := mem32_init_f(bootloader_init_image, boot_rom_size_c/4); |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert false report "NEORV32 PROCESSOR CONFIG NOTE: Implementing internal bootloader ROM (" & natural'image(boot_rom_size_c) & " bytes)." severity note; |
assert not (boot_rom_size_c > boot_rom_max_size_c) report "NEORV32 PROCESSOR CONFIG ERROR! Boot ROM size out of range! Max "& natural'image(boot_rom_max_size_c) & " bytes." severity error; |
|
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
acc_en <= '1' when (addr_i >= BOOTROM_BASE) and (addr_i < std_ulogic_vector(unsigned(BOOTROM_BASE) + BOOTROM_SIZE)) else '0'; |
addr <= addr_i(index_size_f(BOOTROM_SIZE/4)+1 downto 2); -- word aligned |
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = BOOTROM_BASE(hi_abb_c downto lo_abb_c)) else '0'; |
addr <= addr_i(boot_rom_size_index_c+1 downto 2); -- word aligned |
|
|
-- Memory Access -------------------------------------------------------------------------- |
95,7 → 93,7
if rising_edge(clk_i) then |
rden <= rden_i and acc_en; |
if (acc_en = '1') then -- reduce switching activity when not accessed |
rdata <= boot_img(to_integer(unsigned(addr))); |
rdata <= mem_rom(to_integer(unsigned(addr))); |
end if; |
end if; |
end process mem_file_access; |
/core/neorv32_bootloader_image.vhd
1,933 → 1,936
-- The NEORV32 RISC-V Processor, https://github.com/stnolting/neorv32 |
-- Auto-generated memory init file (for BOOTLOADER) from source file <bootloader/main.bin> |
-- Size: 4068 bytes |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
package neorv32_bootloader_image is |
|
type bootloader_init_image_t is array (0 to 1019) of std_ulogic_vector(31 downto 0); |
constant bootloader_init_image : bootloader_init_image_t := ( |
constant bootloader_init_image : mem32_t := ( |
00000000 => x"00000013", |
00000001 => x"00000093", |
00000002 => x"00000113", |
00000003 => x"00000193", |
00000004 => x"00000213", |
00000005 => x"00000293", |
00000006 => x"00000313", |
00000007 => x"00000393", |
00000008 => x"00000713", |
00000009 => x"00000793", |
00000010 => x"80012117", |
00000011 => x"fd410113", |
00000012 => x"ffc17113", |
00000013 => x"00010413", |
00000014 => x"80010197", |
00000015 => x"7c818193", |
00000016 => x"00000517", |
00000017 => x"0bc50513", |
00000018 => x"30551073", |
00000019 => x"34151073", |
00000020 => x"34301073", |
00000021 => x"34201073", |
00000022 => x"30001073", |
00000023 => x"30401073", |
00000024 => x"30601073", |
00000025 => x"ffa00593", |
00000026 => x"32059073", |
00000027 => x"b0001073", |
00000028 => x"b8001073", |
00000029 => x"b0201073", |
00000030 => x"b8201073", |
00000031 => x"00010417", |
00000032 => x"d8440413", |
00000033 => x"00010497", |
00000034 => x"f7c48493", |
00000035 => x"00042023", |
00000036 => x"00440413", |
00000037 => x"fe941ce3", |
00000038 => x"80010597", |
00000039 => x"f6858593", |
00000040 => x"80818613", |
00000041 => x"00c5d863", |
00000042 => x"00058023", |
00000043 => x"00158593", |
00000044 => x"ff5ff06f", |
00000045 => x"00001597", |
00000046 => x"f3858593", |
00000047 => x"80010617", |
00000048 => x"f4460613", |
00000049 => x"80010697", |
00000050 => x"f3c68693", |
00000051 => x"00d65c63", |
00000052 => x"00058703", |
00000053 => x"00e60023", |
00000054 => x"00158593", |
00000055 => x"00160613", |
00000056 => x"fedff06f", |
00000057 => x"00000513", |
00000058 => x"00000593", |
00000059 => x"05c000ef", |
00000060 => x"30047073", |
00000061 => x"10500073", |
00000062 => x"ffdff06f", |
00000063 => x"ff810113", |
00000064 => x"00812023", |
00000065 => x"00912223", |
00000066 => x"34202473", |
00000067 => x"02044663", |
00000068 => x"34102473", |
00000069 => x"00041483", |
00000070 => x"0034f493", |
00000001 => x"80010117", |
00000002 => x"1f810113", |
00000003 => x"80010197", |
00000004 => x"7f418193", |
00000005 => x"00000517", |
00000006 => x"0d450513", |
00000007 => x"30551073", |
00000008 => x"34151073", |
00000009 => x"30001073", |
00000010 => x"30401073", |
00000011 => x"30601073", |
00000012 => x"ffa00593", |
00000013 => x"32059073", |
00000014 => x"b0001073", |
00000015 => x"b8001073", |
00000016 => x"b0201073", |
00000017 => x"b8201073", |
00000018 => x"00000093", |
00000019 => x"00000213", |
00000020 => x"00000293", |
00000021 => x"00000313", |
00000022 => x"00000393", |
00000023 => x"00000713", |
00000024 => x"00000793", |
00000025 => x"00010417", |
00000026 => x"d9c40413", |
00000027 => x"00010497", |
00000028 => x"f9448493", |
00000029 => x"00042023", |
00000030 => x"00440413", |
00000031 => x"fe941ce3", |
00000032 => x"80010597", |
00000033 => x"f8058593", |
00000034 => x"80818613", |
00000035 => x"00c5d863", |
00000036 => x"00058023", |
00000037 => x"00158593", |
00000038 => x"ff5ff06f", |
00000039 => x"00001597", |
00000040 => x"f4858593", |
00000041 => x"80010617", |
00000042 => x"f5c60613", |
00000043 => x"80010697", |
00000044 => x"f5468693", |
00000045 => x"00d65c63", |
00000046 => x"00058703", |
00000047 => x"00e60023", |
00000048 => x"00158593", |
00000049 => x"00160613", |
00000050 => x"fedff06f", |
00000051 => x"00000513", |
00000052 => x"00000593", |
00000053 => x"060000ef", |
00000054 => x"34051073", |
00000055 => x"30047073", |
00000056 => x"10500073", |
00000057 => x"ffdff06f", |
00000058 => x"ff810113", |
00000059 => x"00812023", |
00000060 => x"00912223", |
00000061 => x"34202473", |
00000062 => x"02044663", |
00000063 => x"34102473", |
00000064 => x"00041483", |
00000065 => x"0034f493", |
00000066 => x"00240413", |
00000067 => x"34141073", |
00000068 => x"00300413", |
00000069 => x"00941863", |
00000070 => x"34102473", |
00000071 => x"00240413", |
00000072 => x"34141073", |
00000073 => x"00300413", |
00000074 => x"00941863", |
00000075 => x"34102473", |
00000076 => x"00240413", |
00000077 => x"34141073", |
00000078 => x"00012403", |
00000079 => x"00412483", |
00000080 => x"00810113", |
00000081 => x"30200073", |
00000082 => x"800007b7", |
00000083 => x"0007a023", |
00000084 => x"fd010113", |
00000085 => x"8001a223", |
00000086 => x"02812423", |
00000087 => x"fe002403", |
00000088 => x"026267b7", |
00000089 => x"02112623", |
00000090 => x"02912223", |
00000091 => x"03212023", |
00000092 => x"01312e23", |
00000093 => x"01412c23", |
00000094 => x"01512a23", |
00000095 => x"01612823", |
00000096 => x"01712623", |
00000097 => x"01812423", |
00000098 => x"9ff78793", |
00000099 => x"00000613", |
00000100 => x"00000593", |
00000101 => x"00200513", |
00000102 => x"0087f463", |
00000103 => x"00400513", |
00000104 => x"391000ef", |
00000105 => x"00100513", |
00000106 => x"431000ef", |
00000107 => x"00005537", |
00000108 => x"00000613", |
00000109 => x"00000593", |
00000110 => x"b0050513", |
00000111 => x"2bd000ef", |
00000112 => x"1c1000ef", |
00000113 => x"00245793", |
00000114 => x"00a78533", |
00000115 => x"00f537b3", |
00000116 => x"00b785b3", |
00000117 => x"1d9000ef", |
00000118 => x"ffff07b7", |
00000119 => x"4c878793", |
00000120 => x"30579073", |
00000121 => x"08000793", |
00000122 => x"30479073", |
00000123 => x"30046073", |
00000073 => x"00012403", |
00000074 => x"00412483", |
00000075 => x"00810113", |
00000076 => x"30200073", |
00000077 => x"fd010113", |
00000078 => x"02912223", |
00000079 => x"800004b7", |
00000080 => x"00048793", |
00000081 => x"02112623", |
00000082 => x"02812423", |
00000083 => x"03212023", |
00000084 => x"01312e23", |
00000085 => x"01412c23", |
00000086 => x"01512a23", |
00000087 => x"01612823", |
00000088 => x"01712623", |
00000089 => x"01812423", |
00000090 => x"01912223", |
00000091 => x"0007a023", |
00000092 => x"8001a223", |
00000093 => x"ffff07b7", |
00000094 => x"4b878793", |
00000095 => x"30579073", |
00000096 => x"00000613", |
00000097 => x"00000593", |
00000098 => x"00200513", |
00000099 => x"399000ef", |
00000100 => x"421000ef", |
00000101 => x"00048493", |
00000102 => x"00050863", |
00000103 => x"00100513", |
00000104 => x"00000593", |
00000105 => x"44d000ef", |
00000106 => x"00005537", |
00000107 => x"00000613", |
00000108 => x"00000593", |
00000109 => x"b0050513", |
00000110 => x"23d000ef", |
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", |
00000124 => x"00000013", |
00000125 => x"00000013", |
00000126 => x"ffff1537", |
00000127 => x"f1450513", |
00000128 => x"31d000ef", |
00000129 => x"f1302573", |
00000130 => x"250000ef", |
00000131 => x"ffff1537", |
00000132 => x"f4c50513", |
00000133 => x"309000ef", |
00000134 => x"fe002503", |
00000135 => x"23c000ef", |
00000136 => x"ffff1537", |
00000137 => x"f5450513", |
00000138 => x"2f5000ef", |
00000139 => x"fe402503", |
00000140 => x"228000ef", |
00000141 => x"ffff1537", |
00000142 => x"f5c50513", |
00000143 => x"2e1000ef", |
00000144 => x"30102573", |
00000145 => x"214000ef", |
00000146 => x"ffff1537", |
00000147 => x"f6450513", |
00000148 => x"2cd000ef", |
00000149 => x"fc002573", |
00000150 => x"200000ef", |
00000125 => x"ffff1537", |
00000126 => x"f1450513", |
00000127 => x"2c1000ef", |
00000128 => x"f1302573", |
00000129 => x"244000ef", |
00000130 => x"ffff1537", |
00000131 => x"f4c50513", |
00000132 => x"2ad000ef", |
00000133 => x"fe002503", |
00000134 => x"230000ef", |
00000135 => x"ffff1537", |
00000136 => x"f5450513", |
00000137 => x"299000ef", |
00000138 => x"30102573", |
00000139 => x"21c000ef", |
00000140 => x"ffff1537", |
00000141 => x"f5c50513", |
00000142 => x"285000ef", |
00000143 => x"fc002573", |
00000144 => x"208000ef", |
00000145 => x"ffff1537", |
00000146 => x"f6450513", |
00000147 => x"271000ef", |
00000148 => x"fe802503", |
00000149 => x"ffff1437", |
00000150 => x"1f0000ef", |
00000151 => x"ffff1537", |
00000152 => x"f6c50513", |
00000153 => x"2b9000ef", |
00000154 => x"fe802503", |
00000155 => x"ffff14b7", |
00000156 => x"00341413", |
00000157 => x"1e4000ef", |
00000158 => x"ffff1537", |
00000159 => x"f7450513", |
00000160 => x"29d000ef", |
00000161 => x"ff802503", |
00000162 => x"1d0000ef", |
00000163 => x"f7c48513", |
00000164 => x"28d000ef", |
00000165 => x"ff002503", |
00000166 => x"1c0000ef", |
00000167 => x"ffff1537", |
00000168 => x"f8850513", |
00000169 => x"279000ef", |
00000170 => x"ffc02503", |
00000171 => x"1ac000ef", |
00000172 => x"f7c48513", |
00000173 => x"269000ef", |
00000174 => x"ff402503", |
00000175 => x"19c000ef", |
00000176 => x"ffff1537", |
00000177 => x"f9050513", |
00000178 => x"255000ef", |
00000179 => x"0b5000ef", |
00000180 => x"00a404b3", |
00000181 => x"0084b433", |
00000182 => x"00b40433", |
00000183 => x"1e5000ef", |
00000184 => x"02050263", |
00000185 => x"ffff1537", |
00000186 => x"fbc50513", |
00000187 => x"231000ef", |
00000188 => x"0ed000ef", |
00000189 => x"02300793", |
00000190 => x"02f51263", |
00000191 => x"00000513", |
00000192 => x"0180006f", |
00000193 => x"07d000ef", |
00000194 => x"fc85eae3", |
00000195 => x"00b41463", |
00000196 => x"fc9566e3", |
00000197 => x"00100513", |
00000198 => x"5d8000ef", |
00000199 => x"0a4000ef", |
00000200 => x"ffff1937", |
00000201 => x"ffff19b7", |
00000202 => x"02300a13", |
00000203 => x"07200a93", |
00000204 => x"06800b13", |
00000205 => x"07500b93", |
00000206 => x"07300c13", |
00000207 => x"ffff14b7", |
00000208 => x"fc890513", |
00000209 => x"1d9000ef", |
00000210 => x"169000ef", |
00000211 => x"00050413", |
00000212 => x"13d000ef", |
00000213 => x"ecc98513", |
00000214 => x"1c5000ef", |
00000215 => x"fb4400e3", |
00000216 => x"01541863", |
00000217 => x"ffff02b7", |
00000218 => x"00028067", |
00000219 => x"fd5ff06f", |
00000220 => x"01641663", |
00000221 => x"04c000ef", |
00000222 => x"fc9ff06f", |
00000223 => x"00000513", |
00000224 => x"01740e63", |
00000225 => x"01841663", |
00000226 => x"67c000ef", |
00000227 => x"fb5ff06f", |
00000228 => x"06c00793", |
00000229 => x"00f41863", |
00000230 => x"00100513", |
00000231 => x"3f0000ef", |
00000232 => x"fa1ff06f", |
00000233 => x"06500793", |
00000234 => x"00f41663", |
00000235 => x"020000ef", |
00000236 => x"f91ff06f", |
00000237 => x"fd048513", |
00000238 => x"165000ef", |
00000239 => x"f85ff06f", |
00000240 => x"ffff1537", |
00000241 => x"de050513", |
00000242 => x"1550006f", |
00000243 => x"800007b7", |
00000244 => x"0007a783", |
00000245 => x"00079863", |
00000246 => x"ffff1537", |
00000247 => x"e4450513", |
00000248 => x"13d0006f", |
00000249 => x"ff010113", |
00000250 => x"00112623", |
00000251 => x"30047073", |
00000252 => x"00000013", |
00000253 => x"00000013", |
00000254 => x"ffff1537", |
00000255 => x"e6050513", |
00000256 => x"11d000ef", |
00000257 => x"099000ef", |
00000258 => x"fe051ee3", |
00000259 => x"ff002783", |
00000260 => x"00078067", |
00000261 => x"0000006f", |
00000262 => x"ff010113", |
00000263 => x"00812423", |
00000264 => x"00050413", |
00000265 => x"ffff1537", |
00000266 => x"e7050513", |
00000267 => x"00112623", |
00000268 => x"0ed000ef", |
00000269 => x"03040513", |
00000270 => x"0ff57513", |
00000271 => x"051000ef", |
00000272 => x"30047073", |
00000273 => x"00000013", |
00000274 => x"00000013", |
00000275 => x"00100513", |
00000276 => x"189000ef", |
00000277 => x"0000006f", |
00000278 => x"fe010113", |
00000279 => x"01212823", |
00000280 => x"00050913", |
00000281 => x"ffff1537", |
00000282 => x"00912a23", |
00000283 => x"e7c50513", |
00000284 => x"ffff14b7", |
00000285 => x"00812c23", |
00000286 => x"01312623", |
00000287 => x"00112e23", |
00000288 => x"01c00413", |
00000289 => x"099000ef", |
00000290 => x"fdc48493", |
00000291 => x"ffc00993", |
00000292 => x"008957b3", |
00000293 => x"00f7f793", |
00000294 => x"00f487b3", |
00000295 => x"0007c503", |
00000296 => x"ffc40413", |
00000297 => x"7e8000ef", |
00000298 => x"ff3414e3", |
00000299 => x"01c12083", |
00000300 => x"01812403", |
00000301 => x"01412483", |
00000302 => x"01012903", |
00000303 => x"00c12983", |
00000304 => x"02010113", |
00000305 => x"00008067", |
00000306 => x"fb010113", |
00000307 => x"04112623", |
00000308 => x"04512423", |
00000309 => x"04612223", |
00000310 => x"04712023", |
00000311 => x"02812e23", |
00000312 => x"02a12c23", |
00000313 => x"02b12a23", |
00000314 => x"02c12823", |
00000315 => x"02d12623", |
00000316 => x"02e12423", |
00000317 => x"02f12223", |
00000318 => x"03012023", |
00000319 => x"01112e23", |
00000320 => x"01c12c23", |
00000321 => x"01d12a23", |
00000322 => x"01e12823", |
00000323 => x"01f12623", |
00000324 => x"34202473", |
00000325 => x"800007b7", |
00000326 => x"00778793", |
00000327 => x"06f41a63", |
00000328 => x"00000513", |
00000329 => x"099000ef", |
00000330 => x"658000ef", |
00000331 => x"fe002783", |
00000332 => x"0027d793", |
00000333 => x"00a78533", |
00000334 => x"00f537b3", |
00000335 => x"00b785b3", |
00000336 => x"66c000ef", |
00000337 => x"03c12403", |
00000338 => x"04c12083", |
00000339 => x"04812283", |
00000340 => x"04412303", |
00000341 => x"04012383", |
00000342 => x"03812503", |
00000343 => x"03412583", |
00000344 => x"03012603", |
00000345 => x"02c12683", |
00000346 => x"02812703", |
00000347 => x"02412783", |
00000348 => x"02012803", |
00000349 => x"01c12883", |
00000350 => x"01812e03", |
00000351 => x"01412e83", |
00000352 => x"01012f03", |
00000353 => x"00c12f83", |
00000354 => x"05010113", |
00000355 => x"30200073", |
00000356 => x"00700793", |
00000357 => x"00f41863", |
00000358 => x"8041a783", |
00000359 => x"00100513", |
00000360 => x"02079863", |
00000361 => x"ffff1537", |
00000362 => x"e8050513", |
00000363 => x"770000ef", |
00000364 => x"00040513", |
00000365 => x"ea5ff0ef", |
00000366 => x"ffff1537", |
00000367 => x"e9450513", |
00000368 => x"75c000ef", |
00000369 => x"34102573", |
00000370 => x"e91ff0ef", |
00000371 => x"00500513", |
00000372 => x"e49ff0ef", |
00000373 => x"ff010113", |
00000374 => x"00000513", |
00000375 => x"00112623", |
00000376 => x"00812423", |
00000377 => x"780000ef", |
00000378 => x"09e00513", |
00000379 => x"7bc000ef", |
00000380 => x"00000513", |
00000381 => x"7b4000ef", |
00000382 => x"00050413", |
00000383 => x"00000513", |
00000384 => x"784000ef", |
00000385 => x"00c12083", |
00000386 => x"0ff47513", |
00000387 => x"00812403", |
00000388 => x"01010113", |
00000389 => x"00008067", |
00000390 => x"ff010113", |
00000391 => x"00112623", |
00000392 => x"00812423", |
00000153 => x"259000ef", |
00000154 => x"ff802503", |
00000155 => x"1dc000ef", |
00000156 => x"f7440513", |
00000157 => x"249000ef", |
00000158 => x"ff002503", |
00000159 => x"1cc000ef", |
00000160 => x"ffff1537", |
00000161 => x"f8050513", |
00000162 => x"235000ef", |
00000163 => x"ffc02503", |
00000164 => x"1b8000ef", |
00000165 => x"f7440513", |
00000166 => x"225000ef", |
00000167 => x"ff402503", |
00000168 => x"1a8000ef", |
00000169 => x"0d5000ef", |
00000170 => x"06050663", |
00000171 => x"ffff1537", |
00000172 => x"f8850513", |
00000173 => x"209000ef", |
00000174 => x"0d1000ef", |
00000175 => x"fe002403", |
00000176 => x"00341413", |
00000177 => x"00a40933", |
00000178 => x"00893433", |
00000179 => x"00b40433", |
00000180 => x"115000ef", |
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"fb050513", |
00000190 => x"1c5000ef", |
00000191 => x"0cc000ef", |
00000192 => x"1b1000ef", |
00000193 => x"fc050ae3", |
00000194 => x"ffff1537", |
00000195 => x"fb450513", |
00000196 => x"1ad000ef", |
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"fc098513", |
00000207 => x"181000ef", |
00000208 => x"161000ef", |
00000209 => x"00050413", |
00000210 => x"13d000ef", |
00000211 => x"fb0a0513", |
00000212 => x"16d000ef", |
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"ebcc8513", |
00000235 => x"111000ef", |
00000236 => x"f89ff06f", |
00000237 => x"fc890513", |
00000238 => x"ff5ff06f", |
00000239 => x"ffff1537", |
00000240 => x"dfc50513", |
00000241 => x"0f90006f", |
00000242 => x"ff010113", |
00000243 => x"00112623", |
00000244 => x"30047073", |
00000245 => x"00000013", |
00000246 => x"00000013", |
00000247 => x"ffff1537", |
00000248 => x"e6050513", |
00000249 => x"0d9000ef", |
00000250 => x"0ad000ef", |
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"e7050513", |
00000260 => x"00112623", |
00000261 => x"0a9000ef", |
00000262 => x"03040513", |
00000263 => x"0ff57513", |
00000264 => x"065000ef", |
00000265 => x"30047073", |
00000266 => x"00000013", |
00000267 => x"00000013", |
00000268 => x"181000ef", |
00000269 => x"00050863", |
00000270 => x"00100513", |
00000271 => x"00000593", |
00000272 => x"1b1000ef", |
00000273 => x"0000006f", |
00000274 => x"fe010113", |
00000275 => x"01212823", |
00000276 => x"00050913", |
00000277 => x"ffff1537", |
00000278 => x"00912a23", |
00000279 => x"e7c50513", |
00000280 => x"ffff14b7", |
00000281 => x"00812c23", |
00000282 => x"01312623", |
00000283 => x"00112e23", |
00000284 => x"01c00413", |
00000285 => x"049000ef", |
00000286 => x"fd448493", |
00000287 => x"ffc00993", |
00000288 => x"008957b3", |
00000289 => x"00f7f793", |
00000290 => x"00f487b3", |
00000291 => x"0007c503", |
00000292 => x"ffc40413", |
00000293 => x"7f0000ef", |
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"09d000ef", |
00000326 => x"00050663", |
00000327 => x"00000513", |
00000328 => x"0a1000ef", |
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"630000ef", |
00000366 => x"04050263", |
00000367 => x"ffff1537", |
00000368 => x"e8050513", |
00000369 => x"6f8000ef", |
00000370 => x"00048513", |
00000371 => x"e7dff0ef", |
00000372 => x"02000513", |
00000373 => x"6b0000ef", |
00000374 => x"00040513", |
00000375 => x"e6dff0ef", |
00000376 => x"02000513", |
00000377 => x"6a0000ef", |
00000378 => x"34302573", |
00000379 => x"e5dff0ef", |
00000380 => x"ffff1537", |
00000381 => x"e8850513", |
00000382 => x"6c4000ef", |
00000383 => x"00440413", |
00000384 => x"34141073", |
00000385 => x"f45ff06f", |
00000386 => x"ff010113", |
00000387 => x"00000513", |
00000388 => x"00112623", |
00000389 => x"00812423", |
00000390 => x"740000ef", |
00000391 => x"09e00513", |
00000392 => x"77c000ef", |
00000393 => x"00000513", |
00000394 => x"73c000ef", |
00000395 => x"00500513", |
00000396 => x"778000ef", |
00000397 => x"00000513", |
00000398 => x"770000ef", |
00000399 => x"00050413", |
00000400 => x"00147413", |
00000401 => x"00000513", |
00000402 => x"73c000ef", |
00000403 => x"fc041ce3", |
00000404 => x"00c12083", |
00000405 => x"00812403", |
00000406 => x"01010113", |
00000407 => x"00008067", |
00000408 => x"ff010113", |
00000409 => x"00000513", |
00000410 => x"00112623", |
00000411 => x"6f8000ef", |
00000412 => x"00600513", |
00000413 => x"734000ef", |
00000414 => x"00c12083", |
00000415 => x"00000513", |
00000416 => x"01010113", |
00000417 => x"7000006f", |
00000418 => x"ff010113", |
00000419 => x"00812423", |
00000420 => x"00050413", |
00000421 => x"01055513", |
00000422 => x"0ff57513", |
00000394 => x"774000ef", |
00000395 => x"00050413", |
00000396 => x"00000513", |
00000397 => x"744000ef", |
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"6fc000ef", |
00000408 => x"00500513", |
00000409 => x"738000ef", |
00000410 => x"00000513", |
00000411 => x"730000ef", |
00000412 => x"00050413", |
00000413 => x"00147413", |
00000414 => x"00000513", |
00000415 => x"6fc000ef", |
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"708000ef", |
00000425 => x"00845513", |
00000426 => x"0ff57513", |
00000427 => x"6fc000ef", |
00000428 => x"0ff47513", |
00000429 => x"00812403", |
00000430 => x"00c12083", |
00000431 => x"01010113", |
00000432 => x"6e80006f", |
00000433 => x"ff010113", |
00000434 => x"00812423", |
00000435 => x"00050413", |
00000436 => x"00000513", |
00000437 => x"00112623", |
00000438 => x"68c000ef", |
00000439 => x"00300513", |
00000440 => x"6c8000ef", |
00000441 => x"00040513", |
00000442 => x"fa1ff0ef", |
00000443 => x"00000513", |
00000444 => x"6b8000ef", |
00000445 => x"00050413", |
00000446 => x"00000513", |
00000447 => x"688000ef", |
00000448 => x"00c12083", |
00000449 => x"0ff47513", |
00000450 => x"00812403", |
00000451 => x"01010113", |
00000452 => x"00008067", |
00000453 => x"fd010113", |
00000454 => x"02812423", |
00000455 => x"02912223", |
00000456 => x"03212023", |
00000457 => x"01312e23", |
00000458 => x"01412c23", |
00000459 => x"02112623", |
00000460 => x"00050913", |
00000461 => x"00058993", |
00000462 => x"00c10493", |
00000463 => x"00000413", |
00000464 => x"00400a13", |
00000465 => x"02091e63", |
00000466 => x"568000ef", |
00000467 => x"00a48023", |
00000468 => x"00140413", |
00000469 => x"00148493", |
00000470 => x"ff4416e3", |
00000471 => x"02c12083", |
00000472 => x"02812403", |
00000473 => x"00c12503", |
00000474 => x"02412483", |
00000475 => x"02012903", |
00000476 => x"01c12983", |
00000477 => x"01812a03", |
00000478 => x"03010113", |
00000479 => x"00008067", |
00000480 => x"00898533", |
00000481 => x"f41ff0ef", |
00000482 => x"fc5ff06f", |
00000483 => x"fd010113", |
00000484 => x"01412c23", |
00000485 => x"80418793", |
00000486 => x"02812423", |
00000487 => x"02112623", |
00000488 => x"02912223", |
00000489 => x"03212023", |
00000490 => x"01312e23", |
00000491 => x"01512a23", |
00000492 => x"01612823", |
00000493 => x"01712623", |
00000494 => x"01812423", |
00000495 => x"00100713", |
00000496 => x"00e7a023", |
00000497 => x"fe802783", |
00000498 => x"00050413", |
00000499 => x"80418a13", |
00000500 => x"0087f793", |
00000501 => x"00078a63", |
00000502 => x"fe802783", |
00000503 => x"00400513", |
00000504 => x"0047f793", |
00000505 => x"04079663", |
00000506 => x"02041863", |
00000507 => x"ffff1537", |
00000508 => x"e9c50513", |
00000509 => x"528000ef", |
00000510 => x"008005b7", |
00000511 => x"00040513", |
00000512 => x"f15ff0ef", |
00000513 => x"4788d7b7", |
00000514 => x"afe78793", |
00000515 => x"02f50a63", |
00000516 => x"00000513", |
00000517 => x"01c0006f", |
00000518 => x"ffff1537", |
00000519 => x"ebc50513", |
00000520 => x"4fc000ef", |
00000521 => x"4fc000ef", |
00000522 => x"00051663", |
00000523 => x"00300513", |
00000524 => x"be9ff0ef", |
00000525 => x"da1ff0ef", |
00000526 => x"fc0510e3", |
00000527 => x"ff1ff06f", |
00000528 => x"008009b7", |
00000529 => x"00498593", |
00000530 => x"00040513", |
00000531 => x"ec9ff0ef", |
00000532 => x"00050a93", |
00000533 => x"00898593", |
00000534 => x"00040513", |
00000535 => x"eb9ff0ef", |
00000536 => x"ff002c03", |
00000537 => x"00050b13", |
00000538 => x"ffcafb93", |
00000539 => x"00000913", |
00000540 => x"00000493", |
00000541 => x"00c98993", |
00000542 => x"013905b3", |
00000543 => x"052b9c63", |
00000544 => x"016484b3", |
00000545 => x"00200513", |
00000546 => x"fa0494e3", |
00000547 => x"ffff1537", |
00000548 => x"ec850513", |
00000549 => x"488000ef", |
00000550 => x"02c12083", |
00000551 => x"02812403", |
00000552 => x"800007b7", |
00000553 => x"0157a023", |
00000554 => x"000a2023", |
00000555 => x"02412483", |
00000556 => x"02012903", |
00000557 => x"01c12983", |
00000558 => x"01812a03", |
00000559 => x"01412a83", |
00000560 => x"01012b03", |
00000561 => x"00c12b83", |
00000562 => x"00812c03", |
00000563 => x"03010113", |
00000564 => x"00008067", |
00000565 => x"00040513", |
00000566 => x"e3dff0ef", |
00000567 => x"012c07b3", |
00000568 => x"00a484b3", |
00000569 => x"00a7a023", |
00000570 => x"00490913", |
00000571 => x"f8dff06f", |
00000572 => x"ff010113", |
00000573 => x"00112623", |
00000574 => x"e95ff0ef", |
00000575 => x"ffff1537", |
00000576 => x"ecc50513", |
00000577 => x"418000ef", |
00000578 => x"ac5ff0ef", |
00000579 => x"0000006f", |
00000580 => x"ff010113", |
00000581 => x"00112623", |
00000582 => x"00812423", |
00000583 => x"00912223", |
00000584 => x"00058413", |
00000585 => x"00050493", |
00000586 => x"d39ff0ef", |
00000587 => x"00000513", |
00000588 => x"434000ef", |
00000589 => x"00200513", |
00000590 => x"470000ef", |
00000591 => x"00048513", |
00000592 => x"d49ff0ef", |
00000593 => x"00040513", |
00000594 => x"460000ef", |
00000595 => x"00000513", |
00000596 => x"434000ef", |
00000597 => x"00812403", |
00000598 => x"00c12083", |
00000599 => x"00412483", |
00000600 => x"01010113", |
00000601 => x"cb5ff06f", |
00000602 => x"fe010113", |
00000603 => x"00812c23", |
00000604 => x"00912a23", |
00000605 => x"01212823", |
00000606 => x"00112e23", |
00000607 => x"00050493", |
00000608 => x"00b12623", |
00000609 => x"00000413", |
00000610 => x"00400913", |
00000611 => x"00c10793", |
00000612 => x"008787b3", |
00000613 => x"0007c583", |
00000614 => x"00848533", |
00000615 => x"00140413", |
00000616 => x"f71ff0ef", |
00000617 => x"ff2414e3", |
00000618 => x"01c12083", |
00000619 => x"01812403", |
00000620 => x"01412483", |
00000621 => x"01012903", |
00000622 => x"02010113", |
00000623 => x"00008067", |
00000624 => x"ff010113", |
00000625 => x"00112623", |
00000626 => x"00812423", |
00000627 => x"00050413", |
00000628 => x"c91ff0ef", |
00000629 => x"00000513", |
00000630 => x"38c000ef", |
00000631 => x"0d800513", |
00000632 => x"3c8000ef", |
00000633 => x"00040513", |
00000634 => x"ca1ff0ef", |
00000635 => x"00000513", |
00000636 => x"394000ef", |
00000637 => x"00812403", |
00000638 => x"00c12083", |
00000639 => x"01010113", |
00000640 => x"c19ff06f", |
00000641 => x"fe010113", |
00000642 => x"800007b7", |
00000643 => x"00812c23", |
00000644 => x"0007a403", |
00000645 => x"00112e23", |
00000646 => x"00912a23", |
00000647 => x"01212823", |
00000648 => x"01312623", |
00000649 => x"01412423", |
00000650 => x"01512223", |
00000651 => x"02041863", |
00000652 => x"ffff1537", |
00000653 => x"e4450513", |
00000654 => x"01812403", |
00000655 => x"01c12083", |
00000656 => x"01412483", |
00000657 => x"01012903", |
00000658 => x"00c12983", |
00000659 => x"00812a03", |
00000660 => x"00412a83", |
00000661 => x"02010113", |
00000662 => x"2c40006f", |
00000663 => x"ffff1537", |
00000664 => x"ed050513", |
00000665 => x"2b8000ef", |
00000666 => x"00040513", |
00000667 => x"9edff0ef", |
00000668 => x"ffff1537", |
00000669 => x"edc50513", |
00000670 => x"2a4000ef", |
00000671 => x"00800537", |
00000672 => x"9d9ff0ef", |
00000673 => x"ffff1537", |
00000674 => x"ef850513", |
00000675 => x"290000ef", |
00000676 => x"220000ef", |
00000677 => x"00050493", |
00000678 => x"1f4000ef", |
00000679 => x"07900793", |
00000680 => x"0af49e63", |
00000681 => x"b31ff0ef", |
00000682 => x"00051663", |
00000683 => x"00300513", |
00000684 => x"969ff0ef", |
00000685 => x"ffff1537", |
00000686 => x"f0450513", |
00000687 => x"01045493", |
00000688 => x"25c000ef", |
00000689 => x"00148493", |
00000690 => x"00800937", |
00000691 => x"fff00993", |
00000692 => x"00010a37", |
00000693 => x"fff48493", |
00000694 => x"07349063", |
00000695 => x"4788d5b7", |
00000696 => x"afe58593", |
00000697 => x"00800537", |
00000698 => x"e81ff0ef", |
00000699 => x"00800537", |
00000700 => x"00040593", |
00000701 => x"00450513", |
00000702 => x"e71ff0ef", |
00000703 => x"ff002a03", |
00000704 => x"008009b7", |
00000705 => x"ffc47413", |
00000706 => x"00000493", |
00000707 => x"00000913", |
00000708 => x"00c98a93", |
00000709 => x"01548533", |
00000710 => x"009a07b3", |
00000711 => x"02849663", |
00000712 => x"00898513", |
00000713 => x"412005b3", |
00000714 => x"e41ff0ef", |
00000715 => x"ffff1537", |
00000716 => x"ec850513", |
00000717 => x"f05ff06f", |
00000718 => x"00090513", |
00000719 => x"e85ff0ef", |
00000720 => x"01490933", |
00000721 => x"f91ff06f", |
00000722 => x"0007a583", |
00000723 => x"00448493", |
00000724 => x"00b90933", |
00000725 => x"e15ff0ef", |
00000726 => x"fbdff06f", |
00000727 => x"01c12083", |
00000728 => x"01812403", |
00000729 => x"01412483", |
00000730 => x"01012903", |
00000731 => x"00c12983", |
00000732 => x"00812a03", |
00000733 => x"00412a83", |
00000734 => x"02010113", |
00000735 => x"00008067", |
00000736 => x"ff010113", |
00000737 => x"f9402783", |
00000738 => x"f9002703", |
00000739 => x"f9402683", |
00000740 => x"fed79ae3", |
00000741 => x"00e12023", |
00000742 => x"00f12223", |
00000743 => x"00012503", |
00000744 => x"00412583", |
00000745 => x"01010113", |
00000746 => x"00008067", |
00000747 => x"ff010113", |
00000748 => x"00a12023", |
00000749 => x"00b12223", |
00000750 => x"f9800793", |
00000751 => x"fff00713", |
00000752 => x"00e7a023", |
00000753 => x"00412703", |
00000754 => x"f8e02e23", |
00000755 => x"00012703", |
00000756 => x"00e7a023", |
00000757 => x"01010113", |
00000758 => x"00008067", |
00000759 => x"fa402503", |
00000760 => x"0ff57513", |
00000761 => x"00008067", |
00000762 => x"fa002023", |
00000763 => x"fe002703", |
00000764 => x"00151513", |
00000765 => x"00000793", |
00000766 => x"04a77463", |
00000767 => x"000016b7", |
00000768 => x"00000713", |
00000769 => x"ffe68693", |
00000770 => x"04f6e663", |
00000771 => x"00367613", |
00000772 => x"0035f593", |
00000773 => x"fff78793", |
00000774 => x"01461613", |
00000775 => x"00c7e7b3", |
00000776 => x"01659593", |
00000777 => x"01871713", |
00000778 => x"00b7e7b3", |
00000779 => x"00e7e7b3", |
00000780 => x"10000737", |
00000781 => x"00e7e7b3", |
00000782 => x"faf02023", |
00000783 => x"00008067", |
00000784 => x"00178793", |
00000785 => x"01079793", |
00000786 => x"40a70733", |
00000787 => x"0107d793", |
00000788 => x"fa9ff06f", |
00000789 => x"ffe70513", |
00000790 => x"0fd57513", |
00000791 => x"00051a63", |
00000792 => x"0037d793", |
00000793 => x"00170713", |
00000794 => x"0ff77713", |
00000795 => x"f9dff06f", |
00000796 => x"0017d793", |
00000797 => x"ff1ff06f", |
00000798 => x"f71ff06f", |
00000799 => x"fa002783", |
00000800 => x"fe07cee3", |
00000801 => x"faa02223", |
00000802 => x"00008067", |
00000803 => x"ff1ff06f", |
00000804 => x"fa002503", |
00000805 => x"01f55513", |
00000806 => x"00008067", |
00000807 => x"ff5ff06f", |
00000424 => x"6b8000ef", |
00000425 => x"00600513", |
00000426 => x"6f4000ef", |
00000427 => x"00c12083", |
00000428 => x"00000513", |
00000429 => x"01010113", |
00000430 => x"6c00006f", |
00000431 => x"ff010113", |
00000432 => x"00812423", |
00000433 => x"00050413", |
00000434 => x"01055513", |
00000435 => x"0ff57513", |
00000436 => x"00112623", |
00000437 => x"6c8000ef", |
00000438 => x"00845513", |
00000439 => x"0ff57513", |
00000440 => x"6bc000ef", |
00000441 => x"0ff47513", |
00000442 => x"00812403", |
00000443 => x"00c12083", |
00000444 => x"01010113", |
00000445 => x"6a80006f", |
00000446 => x"ff010113", |
00000447 => x"00812423", |
00000448 => x"00050413", |
00000449 => x"00000513", |
00000450 => x"00112623", |
00000451 => x"64c000ef", |
00000452 => x"00300513", |
00000453 => x"688000ef", |
00000454 => x"00040513", |
00000455 => x"fa1ff0ef", |
00000456 => x"00000513", |
00000457 => x"678000ef", |
00000458 => x"00050413", |
00000459 => x"00000513", |
00000460 => x"648000ef", |
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"524000ef", |
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"e8c50513", |
00000515 => x"4b0000ef", |
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"eac50513", |
00000526 => x"484000ef", |
00000527 => x"4d8000ef", |
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"eb850513", |
00000555 => x"410000ef", |
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"430000ef", |
00000587 => x"00200513", |
00000588 => x"46c000ef", |
00000589 => x"00048513", |
00000590 => x"d85ff0ef", |
00000591 => x"00040513", |
00000592 => x"45c000ef", |
00000593 => x"00000513", |
00000594 => x"430000ef", |
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"388000ef", |
00000629 => x"0d800513", |
00000630 => x"3c4000ef", |
00000631 => x"00040513", |
00000632 => x"cddff0ef", |
00000633 => x"00000513", |
00000634 => x"390000ef", |
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"ebc50513", |
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"26c0006f", |
00000661 => x"ffff1537", |
00000662 => x"ed850513", |
00000663 => x"260000ef", |
00000664 => x"00040513", |
00000665 => x"9e5ff0ef", |
00000666 => x"ffff1537", |
00000667 => x"ee050513", |
00000668 => x"24c000ef", |
00000669 => x"08000537", |
00000670 => x"9d1ff0ef", |
00000671 => x"ffff1537", |
00000672 => x"ef850513", |
00000673 => x"238000ef", |
00000674 => x"218000ef", |
00000675 => x"00050493", |
00000676 => x"1f4000ef", |
00000677 => x"07900793", |
00000678 => x"0af49e63", |
00000679 => x"b6dff0ef", |
00000680 => x"00051663", |
00000681 => x"00300513", |
00000682 => x"955ff0ef", |
00000683 => x"ffff1537", |
00000684 => x"f0450513", |
00000685 => x"01045493", |
00000686 => x"204000ef", |
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"eb850513", |
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", |
00000748 => x"00008067", |
00000749 => x"ff010113", |
00000750 => x"00a12023", |
00000751 => x"00b12223", |
00000752 => x"f9800793", |
00000753 => x"fff00713", |
00000754 => x"00e7a023", |
00000755 => x"00412703", |
00000756 => x"f8e02e23", |
00000757 => x"00012703", |
00000758 => x"00e7a023", |
00000759 => x"01010113", |
00000760 => x"00008067", |
00000761 => x"fe802503", |
00000762 => x"01255513", |
00000763 => x"00157513", |
00000764 => x"00008067", |
00000765 => x"fa002023", |
00000766 => x"fe002703", |
00000767 => x"00151513", |
00000768 => x"00000793", |
00000769 => x"04a77463", |
00000770 => x"000016b7", |
00000771 => x"00000713", |
00000772 => x"ffe68693", |
00000773 => x"04f6e663", |
00000774 => x"00367613", |
00000775 => x"0035f593", |
00000776 => x"fff78793", |
00000777 => x"01461613", |
00000778 => x"00c7e7b3", |
00000779 => x"01659593", |
00000780 => x"01871713", |
00000781 => x"00b7e7b3", |
00000782 => x"00e7e7b3", |
00000783 => x"10000737", |
00000784 => x"00e7e7b3", |
00000785 => x"faf02023", |
00000786 => x"00008067", |
00000787 => x"00178793", |
00000788 => x"01079793", |
00000789 => x"40a70733", |
00000790 => x"0107d793", |
00000791 => x"fa9ff06f", |
00000792 => x"ffe70513", |
00000793 => x"0fd57513", |
00000794 => x"00051a63", |
00000795 => x"0037d793", |
00000796 => x"00170713", |
00000797 => x"0ff77713", |
00000798 => x"f9dff06f", |
00000799 => x"0017d793", |
00000800 => x"ff1ff06f", |
00000801 => x"fa002783", |
00000802 => x"fe07cee3", |
00000803 => x"faa02223", |
00000804 => x"00008067", |
00000805 => x"fa002503", |
00000806 => x"01f55513", |
00000807 => x"00008067", |
00000808 => x"fa402503", |
00000809 => x"fe055ee3", |
00000810 => x"0ff57513", |
00000811 => x"00008067", |
00000812 => x"ff1ff06f", |
00000813 => x"fa402503", |
00000814 => x"01f55513", |
00000815 => x"00008067", |
00000816 => x"ff5ff06f", |
00000817 => x"ff010113", |
00000818 => x"00812423", |
00000819 => x"01212023", |
00000820 => x"00112623", |
00000821 => x"00912223", |
00000822 => x"00050413", |
00000823 => x"00a00913", |
00000824 => x"00044483", |
00000825 => x"00140413", |
00000826 => x"00049e63", |
00000827 => x"00c12083", |
00000828 => x"00812403", |
00000829 => x"00412483", |
00000830 => x"00012903", |
00000831 => x"01010113", |
00000832 => x"00008067", |
00000833 => x"01249663", |
00000834 => x"00d00513", |
00000835 => x"f71ff0ef", |
00000836 => x"00048513", |
00000837 => x"f69ff0ef", |
00000838 => x"fc9ff06f", |
00000839 => x"fa9ff06f", |
00000840 => x"fe802503", |
00000841 => x"01355513", |
00000842 => x"00157513", |
00000843 => x"00008067", |
00000844 => x"00757513", |
00000845 => x"00367613", |
00000846 => x"0015f593", |
00000847 => x"00a51513", |
00000848 => x"00d61613", |
00000849 => x"00c56533", |
00000850 => x"00959593", |
00000851 => x"fa800793", |
00000852 => x"00b56533", |
00000853 => x"0007a023", |
00000854 => x"10056513", |
00000855 => x"00a7a023", |
00000856 => x"00008067", |
00000857 => x"fa800713", |
00000858 => x"00072683", |
00000859 => x"00757793", |
00000860 => x"00100513", |
00000861 => x"00f51533", |
00000862 => x"00d56533", |
00000863 => x"00a72023", |
00000864 => x"00008067", |
00000865 => x"fa800713", |
00000866 => x"00072683", |
00000867 => x"00757513", |
00000868 => x"00100793", |
00000869 => x"00a797b3", |
00000870 => x"fff7c793", |
00000871 => x"00d7f7b3", |
00000872 => x"00f72023", |
00000873 => x"00008067", |
00000874 => x"faa02623", |
00000875 => x"fa802783", |
00000876 => x"fe07cee3", |
00000877 => x"fac02503", |
00000878 => x"00008067", |
00000879 => x"f8400713", |
00000880 => x"00072683", |
00000881 => x"00100793", |
00000812 => x"fa402503", |
00000813 => x"01f55513", |
00000814 => x"00008067", |
00000815 => x"ff010113", |
00000816 => x"00812423", |
00000817 => x"01212023", |
00000818 => x"00112623", |
00000819 => x"00912223", |
00000820 => x"00050413", |
00000821 => x"00a00913", |
00000822 => x"00044483", |
00000823 => x"00140413", |
00000824 => x"00049e63", |
00000825 => x"00c12083", |
00000826 => x"00812403", |
00000827 => x"00412483", |
00000828 => x"00012903", |
00000829 => x"01010113", |
00000830 => x"00008067", |
00000831 => x"01249663", |
00000832 => x"00d00513", |
00000833 => x"f81ff0ef", |
00000834 => x"00048513", |
00000835 => x"f79ff0ef", |
00000836 => x"fc9ff06f", |
00000837 => x"fe802503", |
00000838 => x"01355513", |
00000839 => x"00157513", |
00000840 => x"00008067", |
00000841 => x"00757513", |
00000842 => x"00367613", |
00000843 => x"0015f593", |
00000844 => x"00a51513", |
00000845 => x"00d61613", |
00000846 => x"00c56533", |
00000847 => x"00959593", |
00000848 => x"fa800793", |
00000849 => x"00b56533", |
00000850 => x"0007a023", |
00000851 => x"10056513", |
00000852 => x"00a7a023", |
00000853 => x"00008067", |
00000854 => x"fa800713", |
00000855 => x"00072683", |
00000856 => x"00757793", |
00000857 => x"00100513", |
00000858 => x"00f51533", |
00000859 => x"00d56533", |
00000860 => x"00a72023", |
00000861 => x"00008067", |
00000862 => x"fa800713", |
00000863 => x"00072683", |
00000864 => x"00757513", |
00000865 => x"00100793", |
00000866 => x"00a797b3", |
00000867 => x"fff7c793", |
00000868 => x"00d7f7b3", |
00000869 => x"00f72023", |
00000870 => x"00008067", |
00000871 => x"faa02623", |
00000872 => x"fa802783", |
00000873 => x"fe07cee3", |
00000874 => x"fac02503", |
00000875 => x"00008067", |
00000876 => x"fe802503", |
00000877 => x"01055513", |
00000878 => x"00157513", |
00000879 => x"00008067", |
00000880 => x"00100793", |
00000881 => x"01f00713", |
00000882 => x"00a797b3", |
00000883 => x"00d7c7b3", |
00000884 => x"00f72023", |
00000885 => x"00008067", |
00000886 => x"f8a02223", |
00000883 => x"00a74a63", |
00000884 => x"fc802703", |
00000885 => x"00f747b3", |
00000886 => x"fcf02423", |
00000887 => x"00008067", |
00000888 => x"69617641", |
00000889 => x"6c62616c", |
00000890 => x"4d432065", |
00000891 => x"0a3a7344", |
00000892 => x"203a6820", |
00000893 => x"706c6548", |
00000894 => x"3a72200a", |
00000895 => x"73655220", |
00000896 => x"74726174", |
00000897 => x"3a75200a", |
00000898 => x"6c705520", |
00000899 => x"0a64616f", |
00000900 => x"203a7320", |
00000901 => x"726f7453", |
00000902 => x"6f742065", |
00000903 => x"616c6620", |
00000904 => x"200a6873", |
00000905 => x"4c203a6c", |
00000906 => x"2064616f", |
00000907 => x"6d6f7266", |
00000908 => x"616c6620", |
00000909 => x"200a6873", |
00000910 => x"45203a65", |
00000911 => x"75636578", |
00000912 => x"00006574", |
00000913 => x"65206f4e", |
00000914 => x"75636578", |
00000915 => x"6c626174", |
00000916 => x"76612065", |
00000917 => x"616c6961", |
00000918 => x"2e656c62", |
00000919 => x"00000000", |
00000888 => x"fcc02703", |
00000889 => x"00f747b3", |
00000890 => x"fcf02623", |
00000891 => x"00008067", |
00000892 => x"fca02423", |
00000893 => x"fcb02623", |
00000894 => x"00008067", |
00000895 => x"69617641", |
00000896 => x"6c62616c", |
00000897 => x"4d432065", |
00000898 => x"0a3a7344", |
00000899 => x"203a6820", |
00000900 => x"706c6548", |
00000901 => x"3a72200a", |
00000902 => x"73655220", |
00000903 => x"74726174", |
00000904 => x"3a75200a", |
00000905 => x"6c705520", |
00000906 => x"0a64616f", |
00000907 => x"203a7320", |
00000908 => x"726f7453", |
00000909 => x"6f742065", |
00000910 => x"616c6620", |
00000911 => x"200a6873", |
00000912 => x"4c203a6c", |
00000913 => x"2064616f", |
00000914 => x"6d6f7266", |
00000915 => x"616c6620", |
00000916 => x"200a6873", |
00000917 => x"45203a65", |
00000918 => x"75636578", |
00000919 => x"00006574", |
00000920 => x"746f6f42", |
00000921 => x"2e676e69", |
00000922 => x"0a0a2e2e", |
936,36 → 939,36
00000925 => x"5f524f52", |
00000926 => x"00000000", |
00000927 => x"00007830", |
00000928 => x"58450a0a", |
00000929 => x"54504543", |
00000930 => x"204e4f49", |
00000931 => x"7561636d", |
00000932 => x"003d6573", |
00000933 => x"70204020", |
00000934 => x"00003d63", |
00000935 => x"69617741", |
00000936 => x"676e6974", |
00000937 => x"6f656e20", |
00000938 => x"32337672", |
00000939 => x"6578655f", |
00000940 => x"6e69622e", |
00000941 => x"202e2e2e", |
00000942 => x"00000000", |
00000943 => x"64616f4c", |
00000944 => x"2e676e69", |
00000945 => x"00202e2e", |
00000946 => x"00004b4f", |
00000947 => x"0000000a", |
00000948 => x"74697257", |
00000949 => x"78302065", |
00000950 => x"00000000", |
00000951 => x"74796220", |
00000952 => x"74207365", |
00000953 => x"5053206f", |
00000954 => x"6c662049", |
00000955 => x"20687361", |
00000956 => x"78302040", |
00000957 => x"00000000", |
00000928 => x"58455b0a", |
00000929 => x"00002043", |
00000930 => x"00000a5d", |
00000931 => x"69617741", |
00000932 => x"676e6974", |
00000933 => x"6f656e20", |
00000934 => x"32337672", |
00000935 => x"6578655f", |
00000936 => x"6e69622e", |
00000937 => x"202e2e2e", |
00000938 => x"00000000", |
00000939 => x"64616f4c", |
00000940 => x"2e676e69", |
00000941 => x"00202e2e", |
00000942 => x"00004b4f", |
00000943 => x"65206f4e", |
00000944 => x"75636578", |
00000945 => x"6c626174", |
00000946 => x"76612065", |
00000947 => x"616c6961", |
00000948 => x"2e656c62", |
00000949 => x"00000000", |
00000950 => x"74697257", |
00000951 => x"00002065", |
00000952 => x"74796220", |
00000953 => x"74207365", |
00000954 => x"5053206f", |
00000955 => x"6c662049", |
00000956 => x"20687361", |
00000957 => x"00002040", |
00000958 => x"7928203f", |
00000959 => x"20296e2f", |
00000960 => x"00000000", |
973,61 → 976,58
00000962 => x"6e696873", |
00000963 => x"2e2e2e67", |
00000964 => x"00000020", |
00000965 => x"0a0a0a0a", |
00000966 => x"4e203c3c", |
00000967 => x"56524f45", |
00000968 => x"42203233", |
00000969 => x"6c746f6f", |
00000970 => x"6564616f", |
00000971 => x"3e3e2072", |
00000972 => x"4c420a0a", |
00000973 => x"203a5644", |
00000974 => x"206e754a", |
00000975 => x"32203420", |
00000976 => x"0a313230", |
00000977 => x"3a565748", |
00000978 => x"00002020", |
00000965 => x"3c0a0a0a", |
00000966 => x"454e203c", |
00000967 => x"3356524f", |
00000968 => x"6f422032", |
00000969 => x"6f6c746f", |
00000970 => x"72656461", |
00000971 => x"0a3e3e20", |
00000972 => x"444c420a", |
00000973 => x"4a203a56", |
00000974 => x"33206e75", |
00000975 => x"30322030", |
00000976 => x"480a3132", |
00000977 => x"203a5657", |
00000978 => x"00000020", |
00000979 => x"4b4c430a", |
00000980 => x"0020203a", |
00000981 => x"4553550a", |
00000982 => x"00203a52", |
00000983 => x"53494d0a", |
00000984 => x"00203a41", |
00000985 => x"58455a0a", |
00000986 => x"00203a54", |
00000987 => x"4f52500a", |
00000988 => x"00203a43", |
00000989 => x"454d490a", |
00000990 => x"00203a4d", |
00000991 => x"74796220", |
00000992 => x"40207365", |
00000993 => x"00000020", |
00000994 => x"454d440a", |
00000995 => x"00203a4d", |
00000996 => x"75410a0a", |
00000997 => x"6f626f74", |
00000998 => x"6920746f", |
00000999 => x"3828206e", |
00001000 => x"202e7329", |
00001001 => x"73657250", |
00001002 => x"656b2073", |
00001003 => x"6f742079", |
00001004 => x"6f626120", |
00001005 => x"0a2e7472", |
00001006 => x"00000000", |
00001007 => x"726f6241", |
00001008 => x"2e646574", |
00001009 => x"00000a0a", |
00001010 => x"444d430a", |
00001011 => x"00203e3a", |
00001012 => x"61766e49", |
00001013 => x"2064696c", |
00001014 => x"00444d43", |
00001015 => x"33323130", |
00001016 => x"37363534", |
00001017 => x"62613938", |
00001018 => x"66656463", |
others => x"00000000" |
00000981 => x"53494d0a", |
00000982 => x"00203a41", |
00000983 => x"58455a0a", |
00000984 => x"00203a54", |
00000985 => x"4f52500a", |
00000986 => x"00203a43", |
00000987 => x"454d490a", |
00000988 => x"00203a4d", |
00000989 => x"74796220", |
00000990 => x"40207365", |
00000991 => x"00000000", |
00000992 => x"454d440a", |
00000993 => x"00203a4d", |
00000994 => x"75410a0a", |
00000995 => x"6f626f74", |
00000996 => x"6920746f", |
00000997 => x"7338206e", |
00000998 => x"7250202e", |
00000999 => x"20737365", |
00001000 => x"2079656b", |
00001001 => x"61206f74", |
00001002 => x"74726f62", |
00001003 => x"00000a2e", |
00001004 => x"0000000a", |
00001005 => x"726f6241", |
00001006 => x"2e646574", |
00001007 => x"00000a0a", |
00001008 => x"444d430a", |
00001009 => x"00203e3a", |
00001010 => x"61766e49", |
00001011 => x"2064696c", |
00001012 => x"00444d43", |
00001013 => x"33323130", |
00001014 => x"37363534", |
00001015 => x"62613938", |
00001016 => x"66656463" |
); |
|
end neorv32_bootloader_image; |
/core/neorv32_cfs.vhd
66,7 → 66,6
sleep_i : in std_ulogic; -- set if cpu is in sleep mode |
-- interrupt -- |
irq_o : out std_ulogic; -- interrupt request |
irq_ack_i : in std_ulogic; -- interrupt acknowledge |
-- custom io (conduits) -- |
cfs_in_i : in std_ulogic_vector(CFS_IN_SIZE-1 downto 0); -- custom inputs |
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) -- custom outputs |
157,7 → 156,7
-- |
-- The clkgen_i input clocks are available when at least one IO/peripheral device (for example the UART) requires the clocks generated by the |
-- clock generator. The CFS can enable the clock generator by itself by setting the clkgen_en_o signal high. |
-- The CFS cannot ensure to deactive the clock generator by setting the clkgen_en_o signal low as other peripherals might still keep the generator activated. |
-- The CFS cannot ensure to deactivate the clock generator by setting the clkgen_en_o signal low as other peripherals might still keep the generator activated. |
-- Make sure to deactivate the CFS's clkgen_en_o if no clocks are required in here to reduce dynamic power consumption. |
|
clkgen_en_o <= '0'; -- not used for this minimal example |
190,11 → 189,11
-- |
-- The CFS provides up to 32 memory-mapped 32-bit interface register. For instance, these could be used to provide |
-- a <control register> for global control of the unit, a <data register> for reading/writing from/to a data FIFO, a <command register> |
-- for issueing commands and a <status register> for status information. |
-- for issuing commands and a <status register> for status information. |
-- |
-- Following the interface protocol, each read or write access has to be acknowledged in the following cycle using the ack_o signal (or even later |
-- if the module needs additional time; the maximumx latency until an unacknwoledged access will trigger a bus exception is defined via the package's |
-- gloabl "bus_timeout_c" constant). If no ACK is generated, the bus access will time out and cause a store bus access fault exception. |
-- if the module needs additional time; the maximum latency until an unacknowledged access will trigger a bus exception is defined via the package's |
-- global "bus_timeout_c" constant). If no ACK is generated, the bus access will time out and cause a store bus access fault exception. |
|
-- Host access: Read and write access to the interface registers + bus transfer acknowledge. |
-- This example only implements four physical r/w register (the four lowest CF register). The remaining addresses of the CFS are not |
/core/neorv32_cpu.vhd
68,11 → 68,11
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode? |
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
120,7 → 120,6
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt |
-- fast interrupts (custom) -- |
firq_i : in std_ulogic_vector(15 downto 0) := (others => '0'); |
firq_ack_o : out std_ulogic_vector(15 downto 0); |
-- debug mode (halt) request -- |
db_halt_req_i : in std_ulogic := '0' |
); |
137,7 → 136,7
signal alu_res : std_ulogic_vector(data_width_c-1 downto 0); -- alu result |
signal alu_add : std_ulogic_vector(data_width_c-1 downto 0); -- alu address result |
signal mem_rdata : std_ulogic_vector(data_width_c-1 downto 0); -- memory read data |
signal alu_wait : std_ulogic; -- alu is busy due to iterative unit |
signal alu_idone : std_ulogic; -- iterative alu operation done |
signal bus_i_wait : std_ulogic; -- wait for current bus instruction fetch |
signal bus_d_wait : std_ulogic; -- wait for current bus data access |
signal csr_rdata : std_ulogic_vector(data_width_c-1 downto 0); -- csr read data |
151,25 → 150,37
signal be_store : std_ulogic; -- bus error on store data access |
signal fetch_pc : std_ulogic_vector(data_width_c-1 downto 0); -- pc for instruction fetch |
signal curr_pc : std_ulogic_vector(data_width_c-1 downto 0); -- current pc (for current executed instruction) |
signal fpu_rm : std_ulogic_vector(2 downto 0); -- FPU rounding mode |
signal fpu_flags : std_ulogic_vector(4 downto 0); -- FPU exception flags |
|
-- co-processor interface -- |
signal cp_start : std_ulogic_vector(7 downto 0); -- trigger co-processor i |
signal cp_valid : std_ulogic_vector(7 downto 0); -- co-processor i done |
signal cp_result : cp_data_if_t; -- co-processor result |
|
-- pmp interface -- |
signal pmp_addr : pmp_addr_if_t; |
signal pmp_ctrl : pmp_ctrl_if_t; |
signal pmp_addr : pmp_addr_if_t; |
signal pmp_ctrl : pmp_ctrl_if_t; |
|
begin |
|
-- CPU ISA Configuration --------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert false report |
"NEORV32 CPU ISA Configuration (MARCH): " & |
cond_sel_string_f(CPU_EXTENSION_RISCV_E, "RV32E", "RV32I") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_M, "M", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_A, "A", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_C, "C", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_U, "U", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_Zicsr, "_Zicsr", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_Zifencei, "_Zifencei", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_Zfinx, "_Zfinx", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_Zmmul, "_Zmmul", "") & |
cond_sel_string_f(CPU_EXTENSION_RISCV_DEBUG, "_Debug", "") & |
"" |
severity note; |
|
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- hardware reset notifier -- |
assert not ((dedicated_reset_c = false) and (def_rst_val_c = '-')) report "NEORV32 CPU CONFIG NOTE: Using NO dedicated hardware reset for uncritical registers (default, might reduce area footprint). Set the package constant <dedicated_reset_c> to TRUE if you need a defined reset value." severity note; |
assert not ((dedicated_reset_c = true) and (def_rst_val_c = '0')) report "NEORV32 CPU CONFIG NOTE: Using defined hardware reset for uncritical registers (non-default, reset-to-zero, might increase area footprint)." severity note; |
assert not (dedicated_reset_c = false) report "NEORV32 CPU CONFIG NOTE: Implementing NO dedicated hardware reset for uncritical registers (default, might reduce area). Set package constant <dedicated_reset_c> = TRUE to configure a DEFINED reset value for all CPU registers." severity note; |
assert not (dedicated_reset_c = true) report "NEORV32 CPU CONFIG NOTE: Implementing defined hardware reset for uncritical registers (non-default, reset-to-zero, might increase area)." severity note; |
assert not ((def_rst_val_c /= '-') and (def_rst_val_c /= '0')) report "NEORV32 CPU CONFIG ERROR! Invalid configuration of package <def_rst_val_c> constant (has to be '-' or '0')." severity error; |
|
-- CSR system -- |
193,8 → 204,6
-- PMP granularity -- |
assert not ((is_power_of_two_f(PMP_MIN_GRANULARITY) = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be a power of two." severity error; |
assert not ((PMP_MIN_GRANULARITY < 8) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! <PMP_MIN_GRANULARITY> has to be >= 8 bytes." severity error; |
-- PMP notifier -- |
assert not (PMP_NUM_REGIONS > 0) report "NEORV32 CPU CONFIG NOTE: Implementing physical memory protection (PMP) with " & integer'image(PMP_NUM_REGIONS) & " regions and a minimal granularity of " & integer'image(PMP_MIN_GRANULARITY) & " bytes." severity note; |
-- PMP requires Zicsr extension -- |
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (PMP_NUM_REGIONS > 0)) report "NEORV32 CPU CONFIG ERROR! Physical memory protection (PMP) requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error; |
|
201,13 → 210,13
-- HPM counters check -- |
assert not (HPM_NUM_CNTS > 29) report "NEORV32 CPU CONFIG ERROR! Number of HPM counters <HPM_NUM_CNTS> out of valid range (0..29)." severity error; |
assert not ((HPM_CNT_WIDTH < 0) or (HPM_CNT_WIDTH > 64)) report "NEORV32 CPU CONFIG ERROR! HPM counter width <HPM_CNT_WIDTH> has to be 0..64 bit." severity error; |
-- HPM counters notifier -- |
assert not (HPM_NUM_CNTS > 0) report "NEORV32 CPU CONFIG NOTE: Implementing " & integer'image(HPM_NUM_CNTS) & " HPM counters (each " & integer'image(HPM_CNT_WIDTH) & "-bit wide)." severity note; |
-- HPM CNT requires Zicsr extension -- |
assert not ((CPU_EXTENSION_RISCV_Zicsr = false) and (HPM_NUM_CNTS > 0)) report "NEORV32 CPU CONFIG ERROR! Hardware performance monitors (HPM) require <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error; |
|
-- Mul-extension -- |
assert not ((CPU_EXTENSION_RISCV_Zmmul = true) and (CPU_EXTENSION_RISCV_M = true)) report "NEORV32 CPU CONFIG ERROR! <M> and <ZMMUL> extensions cannot co-exist!" severity error; |
|
-- Debug mode -- |
assert not (CPU_EXTENSION_RISCV_DEBUG = true) report "NEORV32 CPU CONFIG NOTE: Implementing RISC-V DEBUG MODE extension." severity note; |
assert not ((CPU_EXTENSION_RISCV_DEBUG = true) and (CPU_EXTENSION_RISCV_Zicsr = false)) report "NEORV32 CPU CONFIG ERROR! Debug mode requires <CPU_EXTENSION_RISCV_Zicsr> extension to be enabled." severity error; |
|
|
227,6 → 236,7
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_DEBUG => CPU_EXTENSION_RISCV_DEBUG, -- implement CPU debug mode? |
-- Extension Options -- |
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64) |
243,7 → 253,7
rstn_i => rstn_i, -- global reset, low-active, async |
ctrl_o => ctrl, -- main control bus |
-- status input -- |
alu_wait_i => alu_wait, -- wait for ALU |
alu_idone_i => alu_idone, -- ALU iterative operation done |
bus_i_wait_i => bus_i_wait, -- wait for bus |
bus_d_wait_i => bus_d_wait, -- wait for bus |
excl_state_i => excl_state, -- atomic/exclusive access lock status |
258,7 → 268,6
curr_pc_o => curr_pc, -- current PC (corresponding to current instruction) |
csr_rdata_o => csr_rdata, -- CSR read data |
-- FPU interface -- |
fpu_rm_o => fpu_rm, -- rounding mode |
fpu_flags_i => fpu_flags, -- exception flags |
-- debug mode (halt) request -- |
db_halt_req_i => db_halt_req_i, |
270,7 → 279,6
nm_irq_i => nm_irq_i, -- nmi |
-- fast interrupts (custom) -- |
firq_i => firq_i, -- fast interrupt trigger |
firq_ack_o => firq_ack_o, -- fast interrupt acknowledge mask |
-- system time input from MTIME -- |
time_i => time_i, -- current system time |
-- physical memory protection -- |
314,9 → 322,13
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_alu_inst: neorv32_cpu_alu |
generic map ( |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension? |
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations |
TINY_SHIFT_EN => TINY_SHIFT_EN -- use tiny (single-bit) shifter for shift operations |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension? |
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!) |
-- Extension Options -- |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN => FAST_SHIFT_EN -- use barrel shifter for shift operations |
) |
port map ( |
-- global control -- |
328,108 → 340,17
rs2_i => rs2, -- rf source 2 |
pc2_i => curr_pc, -- delayed PC |
imm_i => imm, -- immediate |
csr_i => csr_rdata, -- CSR read data |
cmp_i => comparator, -- comparator status |
-- data output -- |
res_o => alu_res, -- ALU result |
add_o => alu_add, -- address computation result |
-- co-processor interface -- |
cp_start_o => cp_start, -- trigger co-processor i |
cp_valid_i => cp_valid, -- co-processor i done |
cp_result_i => cp_result, -- co-processor result |
fpu_flags_o => fpu_flags, -- FPU exception flags |
-- status -- |
wait_o => alu_wait -- busy due to iterative processing units |
idone_o => alu_idone -- iterative processing units done? |
); |
|
|
-- Co-Processor 0: CSR (Read) Access ('Zicsr' Extension) ---------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- "pseudo" co-processor for CSR *read* access operations |
-- required to get CSR read data into the data path |
cp_result(0) <= csr_rdata when (CPU_EXTENSION_RISCV_Zicsr = true) else (others => '0'); |
cp_valid(0) <= cp_start(0); -- always assigned even if Zicsr extension is disabled to make sure CPU does not get stalled if there is an accidental access |
|
|
-- Co-Processor 1: Integer Multiplication/Division ('M' Extension) ------------------------ |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_muldiv_inst_true: |
if (CPU_EXTENSION_RISCV_M = true) generate |
neorv32_cpu_cp_muldiv_inst: neorv32_cpu_cp_muldiv |
generic map ( |
FAST_MUL_EN => FAST_MUL_EN -- use DSPs for faster multiplication |
) |
port map ( |
-- global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
ctrl_i => ctrl, -- main control bus |
start_i => cp_start(1), -- trigger operation |
-- data input -- |
rs1_i => rs1, -- rf source 1 |
rs2_i => rs2, -- rf source 2 |
-- result and status -- |
res_o => cp_result(1), -- operation result |
valid_o => cp_valid(1) -- data output valid |
); |
end generate; |
|
neorv32_cpu_cp_muldiv_inst_false: |
if (CPU_EXTENSION_RISCV_M = false) generate |
cp_result(1) <= (others => '0'); |
cp_valid(1) <= cp_start(1); -- to make sure CPU does not get stalled if there is an accidental access |
end generate; |
|
|
-- Co-Processor 2: reseverd --------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
cp_result(2) <= (others => '0'); |
cp_valid(2) <= cp_start(2); -- to make sure CPU does not get stalled if there is an accidental access |
|
|
-- Co-Processor 3: Single-Precision Floating-Point Unit ('Zfinx' Extension) --------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_fpu_inst_true: |
if (CPU_EXTENSION_RISCV_Zfinx = true) generate |
neorv32_cpu_cp_fpu_inst: neorv32_cpu_cp_fpu |
port map ( |
-- global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
ctrl_i => ctrl, -- main control bus |
start_i => cp_start(3), -- trigger operation |
-- data input -- |
frm_i => fpu_rm, -- rounding mode |
cmp_i => comparator, -- comparator status |
rs1_i => rs1, -- rf source 1 |
rs2_i => rs2, -- rf source 2 |
-- result and status -- |
res_o => cp_result(3), -- operation result |
fflags_o => fpu_flags, -- exception flags |
valid_o => cp_valid(3) -- data output valid |
); |
end generate; |
|
neorv32_cpu_cp_fpu_inst_false: |
if (CPU_EXTENSION_RISCV_Zfinx = false) generate |
cp_result(3) <= (others => '0'); |
fpu_flags <= (others => '0'); |
cp_valid(3) <= cp_start(3); -- to make sure CPU does not get stalled if there is an accidental access |
end generate; |
|
|
-- Co-Processor 4,5,6,7: Not Implemented -------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
cp_result(4) <= (others => '0'); |
cp_valid(4) <= '0'; |
-- |
cp_result(5) <= (others => '0'); |
cp_valid(5) <= '0'; |
-- |
cp_result(6) <= (others => '0'); |
cp_valid(6) <= '0'; |
-- |
cp_result(7) <= (others => '0'); |
cp_valid(7) <= '0'; |
|
|
-- Bus Interface Unit --------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_bus_inst: neorv32_cpu_bus |
466,7 → 387,7
be_store_o => be_store, -- bus error on store data access |
-- physical memory protection -- |
pmp_addr_i => pmp_addr, -- addresses |
pmp_ctrl_i => pmp_ctrl, -- configs |
pmp_ctrl_i => pmp_ctrl, -- configurations |
-- instruction bus -- |
i_bus_addr_o => i_bus_addr_o, -- bus access address |
i_bus_rdata_i => i_bus_rdata_i, -- bus read data |
/core/neorv32_cpu_alu.vhd
43,9 → 43,13
|
entity neorv32_cpu_alu is |
generic ( |
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension? |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
TINY_SHIFT_EN : boolean := false -- use tiny (single-bit) shifter for shift operations |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations |
); |
port ( |
-- global control -- |
57,15 → 61,14
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
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 -- |
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 |
-- co-processor interface -- |
cp_start_o : out std_ulogic_vector(7 downto 0); -- trigger co-processor i |
cp_valid_i : in std_ulogic_vector(7 downto 0); -- co-processor i done |
cp_result_i : in cp_data_if_t; -- co-processor result |
fpu_flags_o : out std_ulogic_vector(4 downto 0); -- FPU exception flags |
-- status -- |
wait_o : out std_ulogic -- busy due to iterative processing units |
idone_o : out std_ulogic -- iterative processing units done? |
); |
end neorv32_cpu_alu; |
|
81,32 → 84,21
signal arith_res : std_ulogic_vector(data_width_c-1 downto 0); |
signal logic_res : std_ulogic_vector(data_width_c-1 downto 0); |
|
-- shifter -- |
type shifter_t is record |
cmd : std_ulogic; |
cmd_ff : std_ulogic; |
start : std_ulogic; |
run : std_ulogic; |
halt : std_ulogic; |
cnt : std_ulogic_vector(4 downto 0); |
sreg : std_ulogic_vector(data_width_c-1 downto 0); |
-- for barrel shifter only -- |
bs_a_in : std_ulogic_vector(4 downto 0); |
bs_d_in : std_ulogic_vector(data_width_c-1 downto 0); |
end record; |
signal shifter : shifter_t; |
|
-- co-processor arbiter and interface -- |
type cp_ctrl_t is record |
cmd : std_ulogic; |
cmd_ff : std_ulogic; |
start : std_ulogic; |
busy : std_ulogic; |
start : std_ulogic; |
halt : std_ulogic; |
timeout : std_ulogic_vector(9 downto 0); |
end record; |
signal cp_ctrl : cp_ctrl_t; |
|
-- co-processor interface -- |
signal cp_start : std_ulogic_vector(3 downto 0); -- trigger co-processor i |
signal cp_valid : std_ulogic_vector(3 downto 0); -- co-processor i done |
signal cp_result : cp_data_if_t; -- co-processor result |
|
begin |
|
-- Operand Mux ---------------------------------------------------------------------------- |
115,7 → 107,7
opb <= imm_i when (ctrl_i(ctrl_alu_opb_mux_c) = '1') else rs2_i; -- operand b (second ALU input operand) |
|
|
-- Binary Adder/Subtractor ---------------------------------------------------------------- |
-- Binary Adder/Subtracter ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
binary_arithmetic_core: process(ctrl_i, opa, opb) |
variable cin_v : std_ulogic_vector(0 downto 0); |
154,122 → 146,6
end process arithmetic_core; |
|
|
-- Shifter Unit --------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
shifter_unit: process(clk_i) |
variable bs_input_v : std_ulogic_vector(data_width_c-1 downto 0); |
variable bs_level_4_v : std_ulogic_vector(data_width_c-1 downto 0); |
variable bs_level_3_v : std_ulogic_vector(data_width_c-1 downto 0); |
variable bs_level_2_v : std_ulogic_vector(data_width_c-1 downto 0); |
variable bs_level_1_v : std_ulogic_vector(data_width_c-1 downto 0); |
variable bs_level_0_v : std_ulogic_vector(data_width_c-1 downto 0); |
begin |
if rising_edge(clk_i) then |
shifter.cmd_ff <= shifter.cmd; |
|
-- -------------------------------------------------------------------------------- |
-- Iterative shifter (small but slow) (default) |
-- -------------------------------------------------------------------------------- |
if (FAST_SHIFT_EN = false) then |
|
if (shifter.start = '1') then -- trigger new shift |
shifter.sreg <= rs1_i; -- shift operand (can only be rs1; opa would also contain pc) |
shifter.cnt <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount |
elsif (shifter.run = '1') then -- running shift |
-- coarse shift: multiples of 4 -- |
if (TINY_SHIFT_EN = false) and -- use coarse shifts first if TINY SHIFT option is NOT enabled |
(or_reduce_f(shifter.cnt(shifter.cnt'left downto 2)) = '1') then -- shift amount >= 4 |
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 4); |
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical |
shifter.sreg <= shifter.sreg(shifter.sreg'left-4 downto 0) & "0000"; |
else -- SRL: shift right logical / SRA: shift right arithmetical |
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & |
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & |
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & |
(shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 4); |
end if; |
-- fine shift: single shifts, 0..3 times; use ONLY single-bit shifts if TINY_SHIFT_EN is enabled (even smaller than the default approach) -- |
else |
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1); |
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical |
shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0'; |
else -- SRL: shift right logical / SRA: shift right arithmetical |
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 1); |
end if; |
end if; |
end if; |
|
-- -------------------------------------------------------------------------------- |
-- Barrel shifter (huge but fast) |
-- -------------------------------------------------------------------------------- |
else |
-- operands and cycle control -- |
if (shifter.start = '1') then -- trigger new shift |
shifter.bs_d_in <= rs1_i; -- shift operand (can only be rs1; opa would also contain pc) |
shifter.bs_a_in <= opb(index_size_f(data_width_c)-1 downto 0); -- shift amount |
shifter.cnt <= (others => '0'); |
end if; |
|
-- convert left shifts to right shifts -- |
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- is left shift? |
bs_input_v := bit_rev_f(shifter.bs_d_in); -- reverse bit order of input operand |
else |
bs_input_v := shifter.bs_d_in; |
end if; |
-- shift >> 16 -- |
if (shifter.bs_a_in(4) = '1') then |
bs_level_4_v(31 downto 16) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c))); |
bs_level_4_v(15 downto 00) := (bs_input_v(31 downto 16)); |
else |
bs_level_4_v := bs_input_v; |
end if; |
-- shift >> 8 -- |
if (shifter.bs_a_in(3) = '1') then |
bs_level_3_v(31 downto 24) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c))); |
bs_level_3_v(23 downto 00) := (bs_level_4_v(31 downto 8)); |
else |
bs_level_3_v := bs_level_4_v; |
end if; |
-- shift >> 4 -- |
if (shifter.bs_a_in(2) = '1') then |
bs_level_2_v(31 downto 28) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c))); |
bs_level_2_v(27 downto 00) := (bs_level_3_v(31 downto 4)); |
else |
bs_level_2_v := bs_level_3_v; |
end if; |
-- shift >> 2 -- |
if (shifter.bs_a_in(1) = '1') then |
bs_level_1_v(31 downto 30) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c))); |
bs_level_1_v(29 downto 00) := (bs_level_2_v(31 downto 2)); |
else |
bs_level_1_v := bs_level_2_v; |
end if; |
-- shift >> 1 -- |
if (shifter.bs_a_in(0) = '1') then |
bs_level_0_v(31 downto 31) := (others => (bs_input_v(bs_input_v'left) and ctrl_i(ctrl_alu_shift_ar_c))); |
bs_level_0_v(30 downto 00) := (bs_level_1_v(31 downto 1)); |
else |
bs_level_0_v := bs_level_1_v; |
end if; |
-- re-convert original left shifts -- |
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then |
shifter.sreg <= bit_rev_f(bs_level_0_v); |
else |
shifter.sreg <= bs_level_0_v; |
end if; |
end if; |
end if; |
end process shifter_unit; |
|
-- is shift operation? -- |
shifter.cmd <= '1' when (ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) = alu_func_cmd_shift_c) else '0'; |
shifter.start <= '1' when (shifter.cmd = '1') and (shifter.cmd_ff = '0') else '0'; |
|
-- shift operation running? -- |
shifter.run <= '1' when (or_reduce_f(shifter.cnt) = '1') or (shifter.start = '1') else '0'; |
shifter.halt <= '1' when (or_reduce_f(shifter.cnt(shifter.cnt'left downto 1)) = '1') or (shifter.start = '1') else '0'; |
|
|
-- Co-Processor Arbiter ------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- Interface: |
283,20 → 159,20
cp_ctrl.timeout <= (others => '0'); |
elsif rising_edge(clk_i) then |
cp_ctrl.cmd_ff <= cp_ctrl.cmd; |
if (or_reduce_f(cp_valid_i) = '1') then -- cp computation done? |
-- timeout counter -- |
if (cp_ctrl.start = '1') then |
cp_ctrl.busy <= '1'; |
elsif (or_reduce_f(cp_valid) = '1') then |
cp_ctrl.busy <= '0'; |
elsif (cp_ctrl.timeout(cp_ctrl.timeout'left) = '1') and (cp_timeout_en_c = true) then -- timeout |
assert false report "NEORV32 CPU CO-PROCESSOR TIMEOUT ERROR!" severity warning; |
cp_ctrl.busy <= '0'; |
elsif (cp_ctrl.start = '1') then |
cp_ctrl.busy <= '1'; |
end if; |
-- timeout counter -- |
if (cp_ctrl.busy = '1') and (cp_timeout_en_c = true) then |
cp_ctrl.timeout <= std_ulogic_vector(unsigned(cp_ctrl.timeout) + 1); |
else |
cp_ctrl.timeout <= (others => '0'); |
end if; |
if (cp_ctrl.timeout(cp_ctrl.timeout'left) = '1') and (cp_timeout_en_c = true) then -- timeout |
assert false report "NEORV32 CPU CO-PROCESSOR TIMEOUT ERROR!" severity warning; |
end if; |
end if; |
end process cp_arbiter; |
|
304,24 → 180,17
cp_ctrl.cmd <= '1' when (ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) = alu_func_cmd_copro_c) else '0'; |
cp_ctrl.start <= '1' when (cp_ctrl.cmd = '1') and (cp_ctrl.cmd_ff = '0') else '0'; |
|
-- co-processor select -- |
cp_operation_trigger: process(cp_ctrl, ctrl_i) |
begin |
for i in 0 to 7 loop |
if (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = std_ulogic_vector(to_unsigned(i, 3))) then |
cp_start_o(i) <= '1'; |
else |
cp_start_o(i) <= '0'; |
end if; |
end loop; -- i |
end process; |
-- co-processor select / star trigger -- |
cp_start(0) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "00") else '0'; |
cp_start(1) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "01") else '0'; |
cp_start(2) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "10") else '0'; |
cp_start(3) <= '1' when (cp_ctrl.start = '1') and (ctrl_i(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) = "11") else '0'; |
|
-- co-processor operation (still) running? -- |
cp_ctrl.halt <= (cp_ctrl.busy and (not or_reduce_f(cp_valid_i))) or cp_ctrl.start; |
-- co-processor operation done? -- |
idone_o <= or_reduce_f(cp_valid); |
|
-- co-processor result - only the *actually selected* co-processor may output data != 0 -- |
cp_res <= cp_result_i(0) or cp_result_i(1) or cp_result_i(2) or cp_result_i(3) or |
cp_result_i(4) or cp_result_i(5) or cp_result_i(6) or cp_result_i(7); |
cp_res <= cp_result(0) or cp_result(1) or cp_result(2) or cp_result(3); |
|
|
-- ALU Logic Core ------------------------------------------------------------------------- |
340,12 → 209,12
|
-- ALU Function Select -------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
alu_function_mux: process(ctrl_i, arith_res, logic_res, shifter.sreg, cp_res) |
alu_function_mux: process(ctrl_i, arith_res, logic_res, csr_i, cp_res) |
begin |
case ctrl_i(ctrl_alu_func1_c downto ctrl_alu_func0_c) is |
when alu_func_cmd_arith_c => res_o <= arith_res; -- (default) |
when alu_func_cmd_logic_c => res_o <= logic_res; |
when alu_func_cmd_shift_c => res_o <= shifter.sreg; |
when alu_func_cmd_csrr_c => res_o <= csr_i; |
when alu_func_cmd_copro_c => res_o <= cp_res; |
when others => res_o <= arith_res; -- undefined |
end case; |
352,9 → 221,97
end process alu_function_mux; |
|
|
-- ALU Busy ------------------------------------------------------------------------------- |
-- ************************************************************************************************************************** |
-- Co-Processors |
-- ************************************************************************************************************************** |
|
-- Co-Processor 0: Shifter (CPU Core ISA) -------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
wait_o <= shifter.halt or cp_ctrl.halt; -- wait until iterative units have completed |
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) ------------------------ |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_muldiv_inst_true: |
if (CPU_EXTENSION_RISCV_M = true) or (CPU_EXTENSION_RISCV_Zmmul = true) generate |
neorv32_cpu_cp_muldiv_inst: neorv32_cpu_cp_muldiv |
generic map ( |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for faster multiplication |
DIVISION_EN => CPU_EXTENSION_RISCV_M -- implement divider hardware |
) |
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(1), -- trigger operation |
-- data input -- |
rs1_i => rs1_i, -- rf source 1 |
rs2_i => rs2_i, -- rf source 2 |
-- result and status -- |
res_o => cp_result(1), -- operation result |
valid_o => cp_valid(1) -- data output valid |
); |
end generate; |
|
neorv32_cpu_cp_muldiv_inst_false: |
if (CPU_EXTENSION_RISCV_M = false) and (CPU_EXTENSION_RISCV_Zmmul = false) generate |
cp_result(1) <= (others => '0'); |
cp_valid(1) <= cp_start(1); -- to make sure CPU does not get stalled if there is an accidental access |
end generate; |
|
|
-- Co-Processor 2: reserved --------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
cp_result(2) <= (others => '0'); |
cp_valid(2) <= cp_start(2); -- to make sure CPU does not get stalled if there is an accidental access |
|
|
-- Co-Processor 3: Single-Precision Floating-Point Unit ('Zfinx' Extension) --------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_cpu_cp_fpu_inst_true: |
if (CPU_EXTENSION_RISCV_Zfinx = true) generate |
neorv32_cpu_cp_fpu_inst: neorv32_cpu_cp_fpu |
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(3), -- trigger operation |
-- data input -- |
cmp_i => cmp_i, -- comparator status |
rs1_i => rs1_i, -- rf source 1 |
rs2_i => rs2_i, -- rf source 2 |
-- result and status -- |
res_o => cp_result(3), -- operation result |
fflags_o => fpu_flags_o, -- exception flags |
valid_o => cp_valid(3) -- data output valid |
); |
end generate; |
|
neorv32_cpu_cp_fpu_inst_false: |
if (CPU_EXTENSION_RISCV_Zfinx = false) generate |
cp_result(3) <= (others => '0'); |
fpu_flags_o <= (others => '0'); |
cp_valid(3) <= cp_start(3); -- to make sure CPU does not get stalled if there is an accidental access |
end generate; |
|
|
end neorv32_cpu_cpu_rtl; |
/core/neorv32_cpu_bus.vhd
478,7 → 478,7
end generate; -- r |
|
|
-- check access type and regions's permissions -- |
-- check access type and region's permissions -- |
pmp_check_permission: process(pmp, pmp_ctrl_i, ctrl_i) |
begin |
for r in 0 to PMP_NUM_REGIONS-1 loop -- iterate over all regions |
/core/neorv32_cpu_control.vhd
60,6 → 60,7
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode? |
-- Extension Options -- |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
76,7 → 77,7
rstn_i : in std_ulogic; -- global reset, low-active, async |
ctrl_o : out std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus |
-- status input -- |
alu_wait_i : in std_ulogic; -- wait for ALU |
alu_idone_i : in std_ulogic; -- ALU iterative operation done |
bus_i_wait_i : in std_ulogic; -- wait for bus |
bus_d_wait_i : in std_ulogic; -- wait for bus |
excl_state_i : in std_ulogic; -- atomic/exclusive access lock status |
91,7 → 92,6
curr_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction) |
csr_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data |
-- FPU interface -- |
fpu_rm_o : out std_ulogic_vector(02 downto 0); -- rounding mode |
fpu_flags_i : in std_ulogic_vector(04 downto 0); -- exception flags |
-- debug mode (halt) request -- |
db_halt_req_i : in std_ulogic; |
103,7 → 103,6
mtime_irq_i : in std_ulogic; -- machine timer interrupt |
-- fast interrupts (custom) -- |
firq_i : in std_ulogic_vector(15 downto 0); |
firq_ack_o : out std_ulogic_vector(15 downto 0); |
-- system time input from MTIME -- |
time_i : in std_ulogic_vector(63 downto 0); -- current system time |
-- physical memory protection -- |
145,8 → 144,7
end record; |
signal fetch_engine : fetch_engine_t; |
|
-- instruction prefetch buffer (IPB, real FIFO) -- |
type ipb_data_fifo_t is array (0 to ipb_entries_c-1) of std_ulogic_vector(2+31 downto 0); |
-- instruction prefetch buffer (FIFO) interface -- |
type ipb_t is record |
wdata : std_ulogic_vector(2+31 downto 0); -- write status (bus_error, align_error) + 32-bit instruction data |
we : std_ulogic; -- trigger write |
156,14 → 154,6
rdata : std_ulogic_vector(2+31 downto 0); -- read data: status (bus_error, align_error) + 32-bit instruction data |
re : std_ulogic; -- read enable |
avail : std_ulogic; -- data available? |
-- |
w_pnt : std_ulogic_vector(index_size_f(ipb_entries_c) downto 0); -- write pointer |
r_pnt : std_ulogic_vector(index_size_f(ipb_entries_c) downto 0); -- read pointer |
match : std_ulogic; |
empty : std_ulogic; |
full : std_ulogic; |
-- |
data : ipb_data_fifo_t; -- fifo memory |
end record; |
signal ipb : ipb_t; |
|
199,6 → 189,8
is_atomic_sc : std_ulogic; |
is_float_op : std_ulogic; |
sys_env_cmd : std_ulogic_vector(11 downto 0); |
is_m_mul : std_ulogic; |
is_m_div : std_ulogic; |
end record; |
signal decode_aux : decode_aux_t; |
|
216,8 → 208,6
-- |
is_ci : std_ulogic; -- current instruction is de-compressed instruction |
is_ci_nxt : std_ulogic; |
is_cp_op : std_ulogic; -- current instruction is a co-processor operation |
is_cp_op_nxt : std_ulogic; |
-- |
branch_taken : std_ulogic; -- branch condition fulfilled |
pc : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction |
271,10 → 261,10
type pmp_addr_t is array (0 to PMP_NUM_REGIONS-1) of std_ulogic_vector(data_width_c-1 downto 0); |
type pmp_ctrl_rd_t is array (0 to 63) of std_ulogic_vector(7 downto 0); |
type mhpmevent_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(hpmcnt_event_size_c-1 downto 0); |
type mhpmcnt_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(32 downto 0); -- 32-bit, plus 1-bit overflow |
type mhpmcnth_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(31 downto 0); -- 32-bit |
type mhpmcnt_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(31 downto 0); |
type mhpmcnt_nxt_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(32 downto 0); |
type mhpmcnt_ovfl_t is array (0 to HPM_NUM_CNTS-1) of std_ulogic_vector(0 downto 0); |
type mhpmcnt_rd_t is array (0 to 29) of std_ulogic_vector(31 downto 0); |
type mhpmcnth_rd_t is array (0 to 29) of std_ulogic_vector(31 downto 0); |
type csr_t is record |
addr : std_ulogic_vector(11 downto 0); -- csr address |
we : std_ulogic; -- csr write enable |
296,7 → 286,6
mcounteren_cy : std_ulogic; -- mcounteren.cy: allow cycle[h] access from user-mode |
mcounteren_tm : std_ulogic; -- mcounteren.tm: allow time[h] access from user-mode |
mcounteren_ir : std_ulogic; -- mcounteren.ir: allow instret[h] access from user-mode |
mcounteren_hpm : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0); -- mcounteren.hpmx: allow mhpmcounterx[h] access from user-mode |
-- |
mcountinhibit_cy : std_ulogic; -- mcounterinhibit.cy: enable auto-increment for [m]cycle[h] |
mcountinhibit_ir : std_ulogic; -- mcounterinhibit.ir: enable auto-increment for [m]instret[h] |
316,18 → 305,21
-- |
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W) |
-- |
mcycle : std_ulogic_vector(32 downto 0); -- mcycle (R/W), plus carry bit |
mcycle_msb : std_ulogic; -- counter low-to-high-word overflow |
mcycle : std_ulogic_vector(31 downto 0); -- mcycle (R/W) |
mcycle_nxt : std_ulogic_vector(32 downto 0); |
mcycle_ovfl : std_ulogic_vector(00 downto 0); -- counter low-to-high-word overflow |
mcycleh : std_ulogic_vector(31 downto 0); -- mcycleh (R/W) |
minstret : std_ulogic_vector(32 downto 0); -- minstret (R/W), plus carry bit |
minstret_msb : std_ulogic; -- counter low-to-high-word overflow |
minstret : std_ulogic_vector(31 downto 0); -- minstret (R/W) |
minstret_nxt : std_ulogic_vector(32 downto 0); |
minstret_ovfl : std_ulogic_vector(00 downto 0); -- counter low-to-high-word overflow |
minstreth : std_ulogic_vector(31 downto 0); -- minstreth (R/W) |
-- |
mhpmcounter : mhpmcnt_t; -- mhpmcounter* (R/W), plus carry bit |
mhpmcounter_msb : std_ulogic_vector(HPM_NUM_CNTS-1 downto 0); -- counter low-to-high-word overflow |
mhpmcounterh : mhpmcnth_t; -- mhpmcounter*h (R/W) |
mhpmcounter_nxt : mhpmcnt_nxt_t; |
mhpmcounter_ovfl : mhpmcnt_ovfl_t; -- counter low-to-high-word overflow |
mhpmcounterh : mhpmcnt_t; -- mhpmcounter*h (R/W) |
mhpmcounter_rd : mhpmcnt_rd_t; -- mhpmcounter* (R/W): actual read data |
mhpmcounterh_rd : mhpmcnth_rd_t; -- mhpmcounter*h (R/W): actual read data |
mhpmcounterh_rd : mhpmcnt_rd_t; -- mhpmcounter*h (R/W): actual read data |
-- |
pmpcfg : pmp_ctrl_t; -- physical memory protection - configuration registers |
pmpcfg_rd : pmp_ctrl_rd_t; -- physical memory protection - actual read data |
464,47 → 456,29
|
-- Instruction Prefetch Buffer (FIFO) ----------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
instr_prefetch_buffer_ctrl: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
ipb.w_pnt <= (others => def_rst_val_c); |
ipb.r_pnt <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
-- write port -- |
if (ipb.clear = '1') then |
ipb.w_pnt <= (others => '0'); |
elsif (ipb.we = '1') then |
ipb.w_pnt <= std_ulogic_vector(unsigned(ipb.w_pnt) + 1); |
end if; |
-- read port -- |
if (ipb.clear = '1') then |
ipb.r_pnt <= (others => '0'); |
elsif (ipb.re = '1') then |
ipb.r_pnt <= std_ulogic_vector(unsigned(ipb.r_pnt) + 1); |
end if; |
end if; |
end process instr_prefetch_buffer_ctrl; |
instr_prefetch_buffer: neorv32_fifo |
generic map ( |
FIFO_DEPTH => ipb_entries_c, -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH => ipb.wdata'length, -- size of data elements in fifo |
FIFO_RSYNC => false, -- we NEED to read data asynchronously |
FIFO_SAFE => false -- no safe access required (ensured by FIFO-external control) |
) |
port map ( |
-- control -- |
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => ipb.clear, -- sync reset, high-active |
-- write port -- |
wdata_i => ipb.wdata, -- write data |
we_i => ipb.we, -- write enable |
free_o => ipb.free, -- at least one entry is free when set |
-- read port -- |
re_i => ipb.re, -- read enable |
rdata_o => ipb.rdata, -- read data |
avail_o => ipb.avail -- data available when set |
); |
|
instr_prefetch_buffer_data: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (ipb.we = '1') then -- write access |
ipb.data(to_integer(unsigned(ipb.w_pnt(ipb.w_pnt'left-1 downto 0)))) <= ipb.wdata; |
end if; |
end if; |
end process instr_prefetch_buffer_data; |
|
-- async read -- |
ipb.rdata <= ipb.data(to_integer(unsigned(ipb.r_pnt(ipb.r_pnt'left-1 downto 0)))); |
|
-- status -- |
ipb.match <= '1' when (ipb.r_pnt(ipb.r_pnt'left-1 downto 0) = ipb.w_pnt(ipb.w_pnt'left-1 downto 0)) else '0'; |
ipb.full <= '1' when (ipb.r_pnt(ipb.r_pnt'left) /= ipb.w_pnt(ipb.w_pnt'left)) and (ipb.match = '1') else '0'; |
ipb.empty <= '1' when (ipb.r_pnt(ipb.r_pnt'left) = ipb.w_pnt(ipb.w_pnt'left)) and (ipb.match = '1') else '0'; |
ipb.free <= not ipb.full; |
ipb.avail <= not ipb.empty; |
|
|
-- **************************************************************************************************************************** |
-- Instruction Issue (recoding of compressed instructions and 32-bit instruction word construction) |
-- **************************************************************************************************************************** |
719,7 → 693,6
execute_engine.state_prev <= SYS_WAIT; |
execute_engine.i_reg <= (others => def_rst_val_c); |
execute_engine.is_ci <= def_rst_val_c; |
execute_engine.is_cp_op <= def_rst_val_c; |
execute_engine.last_pc <= (others => def_rst_val_c); |
execute_engine.i_reg_last <= (others => def_rst_val_c); |
execute_engine.next_pc <= (others => def_rst_val_c); |
738,13 → 711,12
end if; |
-- |
execute_engine.state <= execute_engine.state_nxt; |
execute_engine.sleep <= execute_engine.sleep_nxt; |
execute_engine.sleep <= execute_engine.sleep_nxt and (not debug_ctrl.running); -- do not execute when in debug mode |
execute_engine.branched <= execute_engine.branched_nxt; |
-- |
execute_engine.state_prev <= execute_engine.state; |
execute_engine.i_reg <= execute_engine.i_reg_nxt; |
execute_engine.is_ci <= execute_engine.is_ci_nxt; |
execute_engine.is_cp_op <= execute_engine.is_cp_op_nxt; |
|
-- PC & IR of "last executed" instruction -- |
if (execute_engine.state = EXECUTE) then |
829,6 → 801,8
else |
ctrl_o(ctrl_debug_running_c) <= '0'; |
end if; |
-- FPU rounding mode -- |
ctrl_o(ctrl_alu_frm2_c downto ctrl_alu_frm0_c) <= csr.frm; |
end process ctrl_output; |
|
|
843,6 → 817,8
decode_aux.is_atomic_lr <= '0'; |
decode_aux.is_atomic_sc <= '0'; |
decode_aux.is_float_op <= '0'; |
decode_aux.is_m_mul <= '0'; |
decode_aux.is_m_div <= '0'; |
|
-- is immediate ALU operation? -- |
decode_aux.alu_immediate <= not execute_engine.i_reg(instr_opcode_msb_c-1); |
871,19 → 847,25
-- system/environment instructions -- |
sys_env_cmd_mask_v := funct12_ecall_c or funct12_ebreak_c or funct12_mret_c or funct12_wfi_c or funct12_dret_c; -- sum-up set bits |
decode_aux.sys_env_cmd <= execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) and sys_env_cmd_mask_v; -- set unused bits to always-zero |
|
-- integer MUL (M/Zmmul) / DIV (M) operation -- |
if (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and |
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then |
decode_aux.is_m_mul <= not execute_engine.i_reg(instr_funct3_msb_c); |
decode_aux.is_m_div <= execute_engine.i_reg(instr_funct3_msb_c); |
end if; |
end process decode_helper; |
|
|
-- Execute Engine FSM Comb ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
execute_engine_fsm_comb: process(execute_engine, debug_ctrl, decode_aux, fetch_engine, cmd_issue, trap_ctrl, csr, ctrl, csr_acc_valid, |
alu_wait_i, bus_d_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i, excl_state_i) |
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) |
variable opcode_v : std_ulogic_vector(6 downto 0); |
begin |
-- arbiter defaults -- |
execute_engine.state_nxt <= execute_engine.state; |
execute_engine.i_reg_nxt <= execute_engine.i_reg; |
execute_engine.is_cp_op_nxt <= execute_engine.is_cp_op; |
execute_engine.is_ci_nxt <= execute_engine.is_ci; |
execute_engine.sleep_nxt <= execute_engine.sleep; |
execute_engine.branched_nxt <= execute_engine.branched; |
939,8 → 921,7
-- ------------------------------------------------------------ |
-- set reg_file's r0 to zero -- |
if (rf_r0_is_reg_c = true) then -- is r0 implemented as physical register, which has to be set to zero? |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; -- hacky! CSR read-access CP selected without a valid CSR-read -> results zero |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_csr_rd_c; -- use CSR-READ CP |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_csrr_c; -- hacky! CSR read-access without a valid CSR-read -> results zero |
ctrl_nxt(ctrl_rf_r0_we_c) <= '1'; -- force RF write access and force rd=r0 |
end if; |
-- |
949,8 → 930,6
|
when DISPATCH => -- Get new command from instruction issue engine |
-- ------------------------------------------------------------ |
-- housekeeping -- |
execute_engine.is_cp_op_nxt <= '0'; -- no co-processor operation yet |
-- PC update -- |
execute_engine.pc_mux_sel <= '0'; -- linear next PC |
-- IR update -- |
966,7 → 945,9
trap_ctrl.instr_be <= cmd_issue.data(34); -- bus access fault during instruction fetch |
illegal_compressed <= cmd_issue.data(35); -- invalid decompressed instruction |
-- any reason to go to trap state? -- |
if (execute_engine.sleep = '1') or (trap_ctrl.env_start = '1') or (trap_ctrl.exc_fire = '1') or ((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then |
if (execute_engine.sleep = '1') or -- WFI instruction - this will enter sleep state |
(trap_ctrl.env_start = '1') or -- pending trap (IRQ or exception) |
((cmd_issue.data(33) or cmd_issue.data(34)) = '1') then -- exception during instruction fetch of the CURRENT instruction |
execute_engine.state_nxt <= TRAP_ENTER; |
else |
execute_engine.state_nxt <= EXECUTE; |
977,8 → 958,8
when TRAP_ENTER => -- Start trap environment - get TVEC, stay here for sleep mode |
-- ------------------------------------------------------------ |
if (trap_ctrl.env_start = '1') then -- trap triggered? |
trap_ctrl.env_start_ack <= '1'; |
execute_engine.state_nxt <= TRAP_EXECUTE; |
trap_ctrl.env_start_ack <= '1'; |
execute_engine.state_nxt <= TRAP_EXECUTE; |
end if; |
|
when TRAP_EXIT => -- Return from trap environment - get EPC |
986,7 → 967,7
trap_ctrl.env_end <= '1'; |
execute_engine.state_nxt <= TRAP_EXECUTE; |
|
when TRAP_EXECUTE => -- Start trap environment -> jump to TVEC / return from trap environment -> jump to EPC |
when TRAP_EXECUTE => -- Start trap environment -> jump to *TVEC / return from trap environment -> jump to EPC |
-- ------------------------------------------------------------ |
execute_engine.pc_mux_sel <= '0'; -- next_PC |
fetch_engine.reset <= '1'; |
1031,17 → 1012,20
end case; |
|
-- co-processor MULDIV operation? -- |
if (CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV CP op? |
if ((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV |
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) then -- MUL |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- use MULDIV CP |
execute_engine.is_cp_op_nxt <= '1'; -- this is a CP operation |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; |
else |
-- ALU operation, function select -- |
else |
execute_engine.is_cp_op_nxt <= '0'; -- no CP operation |
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is -- actual ALU.func operation (re-coding) |
when funct3_xor_c | funct3_or_c | funct3_and_c => ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_logic_c; |
when funct3_sll_c | funct3_sr_c => ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_shift_c; |
when others => ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_arith_c; |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_shifter_c; -- use SHIFTER CP (only relevant for shift operations) |
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is |
when funct3_sll_c | funct3_sr_c => -- SHIFT operation |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; |
when funct3_xor_c | funct3_or_c | funct3_and_c => -- LOGIC operation |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_logic_c; |
when others => -- ARITHMETIC operation |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_arith_c; |
end case; |
end if; |
|
1048,7 → 1032,8
-- multi cycle ALU operation? -- |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or -- SLL shift operation? |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) or -- SR shift operation? |
((CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5)) and (execute_engine.i_reg(instr_funct7_lsb_c) = '1')) then -- MULDIV CP op? |
((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV |
((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) then -- MUL |
execute_engine.state_nxt <= ALU_WAIT; |
else -- single cycle ALU operation |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
1077,7 → 1062,7
ctrl_nxt(ctrl_bus_mo_we_c) <= '1'; -- write to MAR and MDO (MDO only relevant for store) |
-- |
if (CPU_EXTENSION_RISCV_A = false) or -- atomic extension disabled |
(execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "00") then -- normal integerload/store |
(execute_engine.i_reg(instr_opcode_lsb_c+3 downto instr_opcode_lsb_c+2) = "00") then -- normal integer load/store |
execute_engine.state_nxt <= LOADSTORE_0; |
else -- atomic operation |
if (execute_engine.i_reg(instr_funct5_msb_c downto instr_funct5_lsb_c) = funct5_a_sc_c) or -- store-conditional |
1107,8 → 1092,6
-- ------------------------------------------------------------ |
if (CPU_EXTENSION_RISCV_Zicsr = true) then |
csr.re_nxt <= csr_acc_valid; -- always read CSR if valid access, only relevant for CSR-instructions |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; -- only relevant for CSR-instructions |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_csr_rd_c; -- use CSR-READ CP, 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 |
1121,8 → 1104,7
when opcode_fop_c => -- floating-point operations |
-- ------------------------------------------------------------ |
if (CPU_EXTENSION_RISCV_Zfinx = true) and (decode_aux.is_float_op = '1') then |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_fpu_c; -- use FPU CP |
execute_engine.is_cp_op_nxt <= '1'; -- this is a CP operation |
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_fpu_c; -- trigger FPU CP |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; |
execute_engine.state_nxt <= ALU_WAIT; |
else |
1143,13 → 1125,8
when funct12_ecall_c => trap_ctrl.env_call <= '1'; -- ECALL |
when funct12_ebreak_c => trap_ctrl.break_point <= '1'; -- EBREAK |
when funct12_mret_c => execute_engine.state_nxt <= TRAP_EXIT; -- MRET |
when funct12_wfi_c => -- WFI |
if (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1') then |
NULL; -- just a NOP when in debug mode |
else |
execute_engine.sleep_nxt <= '1'; -- WFI (normal) |
end if; |
when funct12_dret_c => -- DRET |
when funct12_wfi_c => execute_engine.sleep_nxt <= '1'; -- WFI |
when funct12_dret_c => -- DRET |
if (CPU_EXTENSION_RISCV_DEBUG = true) then |
execute_engine.state_nxt <= TRAP_EXIT; |
debug_ctrl.dret <= '1'; |
1172,23 → 1149,18
csr.we_nxt <= '0'; |
end case; |
-- register file write back -- |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_csrr_c; |
ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
execute_engine.state_nxt <= DISPATCH; |
|
|
when ALU_WAIT => -- wait for multi-cycle ALU operation (shifter or CP) to finish |
when ALU_WAIT => -- wait for multi-cycle ALU operation (co-processor) to finish |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_rf_in_mux_c) <= '0'; -- RF input = ALU result |
-- cp access or alu.shift? -- |
if (execute_engine.is_cp_op = '1') then |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; |
else |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_shift_c; |
end if; |
ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_cmd_copro_c; |
-- wait for result -- |
if (alu_wait_i = '0') then |
if (alu_idone_i = '1') then -- done |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back |
execute_engine.state_nxt <= DISPATCH; |
end if; |
1239,7 → 1211,7
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or (decode_aux.is_atomic_lr = '1') then -- normal load or atomic load-reservate |
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request |
else -- store |
if (CPU_EXTENSION_RISCV_A = true) and (decode_aux.is_atomic_sc = '1') then -- evaluate lock state |
if (decode_aux.is_atomic_sc = '1') then -- evaluate lock state |
if (excl_state_i = '1') then -- lock is still ok - perform write access |
ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- write request |
end if; |
1250,9 → 1222,9
execute_engine.state_nxt <= LOADSTORE_1; |
|
|
when LOADSTORE_1 => -- memory latency |
when LOADSTORE_1 => -- memory access latency |
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD) |
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- write input data to MDI (only relevant for LOADs) |
execute_engine.state_nxt <= LOADSTORE_2; |
|
|
1260,14 → 1232,10
-- ------------------------------------------------------------ |
ctrl_nxt(ctrl_bus_mi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for load (and SC.W) operations) |
ctrl_nxt(ctrl_rf_in_mux_c) <= '1'; -- RF input = memory input (only relevant for LOADs) |
-- wait for memory response -- |
if ((ma_load_i or be_load_i or ma_store_i or be_store_i) = '1') then -- abort if exception |
execute_engine.state_nxt <= DISPATCH; |
-- wait for memory response / exception -- |
if (trap_ctrl.env_start = '1') then -- abort if exception |
execute_engine.state_nxt <= SYS_WAIT; |
elsif (bus_d_wait_i = '0') then -- wait for bus to finish transaction |
-- remove atomic lock if this is NOT the LR.W instruction used to SET the lock -- |
if (CPU_EXTENSION_RISCV_A = true) and (decode_aux.is_atomic_lr = '0') then -- execute and evaluate atomic store-conditional |
ctrl_nxt(ctrl_bus_de_lock_c) <= '1'; |
end if; |
-- data write-back -- |
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') or -- normal load |
(decode_aux.is_atomic_lr = '1') or -- atomic load-reservate |
1274,6 → 1242,10
(decode_aux.is_atomic_sc = '1') then -- atomic store-conditional |
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; |
end if; |
-- remove atomic lock if this is NOT the LR.W instruction used to SET the lock -- |
if (decode_aux.is_atomic_lr = '0') then -- execute and evaluate atomic store-conditional |
ctrl_nxt(ctrl_bus_de_lock_c) <= '1'; |
end if; |
execute_engine.state_nxt <= DISPATCH; |
end if; |
|
1293,8 → 1265,7
-- CSR Access Check ----------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
csr_access_check: process(execute_engine.i_reg, csr, debug_ctrl) |
variable csr_wacc_v : std_ulogic; -- to check access to read-only CSRs |
variable csr_mcounteren_hpm_v : std_ulogic_vector(31 downto 0); -- max 29 HPM counters, plus 3 LSB-aligned dummy bits |
variable csr_wacc_v : std_ulogic; -- to check access to read-only CSRs |
begin |
-- is this CSR instruction really going to write to a CSR? -- |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or |
1304,14 → 1275,6
csr_wacc_v := or_reduce_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c)); -- write allowed if rs1/uimm5 != 0 |
end if; |
|
-- low privilege level access to hpm counters? -- |
csr_mcounteren_hpm_v := (others => '0'); |
if (CPU_EXTENSION_RISCV_U = true) and (HPM_NUM_CNTS /= 0) then |
csr_mcounteren_hpm_v(3+(HPM_NUM_CNTS-1) downto 3+0) := csr.mcounteren_hpm(HPM_NUM_CNTS-1 downto 0); |
else -- 'mcounteren' CSR is hardwired to zero if user mode is not implemented |
csr_mcounteren_hpm_v := (others => '0'); |
end if; |
|
-- check CSR access -- |
csr_acc_valid <= '0'; -- default = invalid access |
case csr.addr is |
1330,7 → 1293,7
when csr_mip_c | csr_mtval_c => -- NOTE: MIP and MTVAL are read-only in the NEORV32! |
csr_acc_valid <= (not csr_wacc_v) and csr.priv_m_mode; -- M-mode only, read-only |
|
-- physical memory protection - address & configuration -- |
-- physical memory protection (PMP) - address & configuration -- |
when csr_pmpaddr0_c | csr_pmpaddr1_c | csr_pmpaddr2_c | csr_pmpaddr3_c | csr_pmpaddr4_c | csr_pmpaddr5_c | csr_pmpaddr6_c | csr_pmpaddr7_c | |
csr_pmpaddr8_c | csr_pmpaddr9_c | csr_pmpaddr10_c | csr_pmpaddr11_c | csr_pmpaddr12_c | csr_pmpaddr13_c | csr_pmpaddr14_c | csr_pmpaddr15_c | |
csr_pmpaddr16_c | csr_pmpaddr17_c | csr_pmpaddr18_c | csr_pmpaddr19_c | csr_pmpaddr20_c | csr_pmpaddr21_c | csr_pmpaddr22_c | csr_pmpaddr23_c | |
1339,8 → 1302,8
csr_pmpaddr40_c | csr_pmpaddr41_c | csr_pmpaddr42_c | csr_pmpaddr43_c | csr_pmpaddr44_c | csr_pmpaddr45_c | csr_pmpaddr46_c | csr_pmpaddr47_c | |
csr_pmpaddr48_c | csr_pmpaddr49_c | csr_pmpaddr50_c | csr_pmpaddr51_c | csr_pmpaddr52_c | csr_pmpaddr53_c | csr_pmpaddr54_c | csr_pmpaddr55_c | |
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 | |
csr_pmpcfg8_c | csr_pmpcfg9_c | csr_pmpcfg10_c | csr_pmpcfg11_c | csr_pmpcfg12_c | csr_pmpcfg13_c | csr_pmpcfg14_c | csr_pmpcfg15_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 | |
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 |
1347,22 → 1310,22
NULL; |
end if; |
|
-- machine counters/timers -- |
when csr_mcycle_c | csr_minstret_c => |
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode only, access valid if really implemented |
when csr_mcycleh_c | csr_minstreth_c => |
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode only, access valid if really implemented |
|
when csr_mhpmcounter3_c | csr_mhpmcounter4_c | csr_mhpmcounter5_c | csr_mhpmcounter6_c | csr_mhpmcounter7_c | csr_mhpmcounter8_c | -- LOW |
-- 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 |
csr_mhpmcounter9_c | csr_mhpmcounter10_c | csr_mhpmcounter11_c | csr_mhpmcounter12_c | csr_mhpmcounter13_c | csr_mhpmcounter14_c | |
csr_mhpmcounter15_c | csr_mhpmcounter16_c | csr_mhpmcounter17_c | csr_mhpmcounter18_c | csr_mhpmcounter19_c | csr_mhpmcounter20_c | |
csr_mhpmcounter21_c | csr_mhpmcounter22_c | csr_mhpmcounter23_c | csr_mhpmcounter24_c | csr_mhpmcounter25_c | csr_mhpmcounter26_c | |
csr_mhpmcounter27_c | csr_mhpmcounter28_c | csr_mhpmcounter29_c | csr_mhpmcounter30_c | csr_mhpmcounter31_c | |
csr_mhpmcounter3h_c | csr_mhpmcounter4h_c | csr_mhpmcounter5h_c | csr_mhpmcounter6h_c | csr_mhpmcounter7h_c | csr_mhpmcounter8h_c | -- HIGH |
csr_mhpmcounter3h_c | csr_mhpmcounter4h_c | csr_mhpmcounter5h_c | csr_mhpmcounter6h_c | csr_mhpmcounter7h_c | csr_mhpmcounter8h_c | -- counter HIGH |
csr_mhpmcounter9h_c | csr_mhpmcounter10h_c | csr_mhpmcounter11h_c | csr_mhpmcounter12h_c | csr_mhpmcounter13h_c | csr_mhpmcounter14h_c | |
csr_mhpmcounter15h_c | csr_mhpmcounter16h_c | csr_mhpmcounter17h_c | csr_mhpmcounter18h_c | csr_mhpmcounter19h_c | csr_mhpmcounter20h_c | |
csr_mhpmcounter21h_c | csr_mhpmcounter22h_c | csr_mhpmcounter23h_c | csr_mhpmcounter24h_c | csr_mhpmcounter25h_c | csr_mhpmcounter26h_c | |
csr_mhpmcounter27h_c | csr_mhpmcounter28h_c | csr_mhpmcounter29h_c | csr_mhpmcounter30h_c | csr_mhpmcounter31h_c => |
csr_mhpmcounter27h_c | csr_mhpmcounter28h_c | csr_mhpmcounter29h_c | csr_mhpmcounter30h_c | csr_mhpmcounter31h_c | |
csr_mhpmevent3_c | csr_mhpmevent4_c | csr_mhpmevent5_c | csr_mhpmevent6_c | csr_mhpmevent7_c | csr_mhpmevent8_c | -- event configuration |
csr_mhpmevent9_c | csr_mhpmevent10_c | csr_mhpmevent11_c | csr_mhpmevent12_c | csr_mhpmevent13_c | csr_mhpmevent14_c | |
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 |
1369,7 → 1332,12
NULL; |
end if; |
|
-- user counters/timers -- |
-- counters/timers -- |
when csr_mcycle_c | csr_minstret_c => |
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode only, access valid if really implemented |
when csr_mcycleh_c | csr_minstreth_c => |
csr_acc_valid <= csr.priv_m_mode and bool_to_ulogic_f(boolean(cpu_cnt_hi_width_c > 0)); -- M-mode only, access valid if really implemented |
|
when csr_cycle_c => |
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr.mcounteren_cy) and bool_to_ulogic_f(boolean(cpu_cnt_lo_width_c > 0)); -- M-mode, U-mode if authorized, read-only, access if implemented |
when csr_cycleh_c => |
1382,36 → 1350,9
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 |
|
when csr_hpmcounter3_c | csr_hpmcounter4_c | csr_hpmcounter5_c | csr_hpmcounter6_c | csr_hpmcounter7_c | csr_hpmcounter8_c | -- LOW |
csr_hpmcounter9_c | csr_hpmcounter10_c | csr_hpmcounter11_c | csr_hpmcounter12_c | csr_hpmcounter13_c | csr_hpmcounter14_c | |
csr_hpmcounter15_c | csr_hpmcounter16_c | csr_hpmcounter17_c | csr_hpmcounter18_c | csr_hpmcounter19_c | csr_hpmcounter20_c | |
csr_hpmcounter21_c | csr_hpmcounter22_c | csr_hpmcounter23_c | csr_hpmcounter24_c | csr_hpmcounter25_c | csr_hpmcounter26_c | |
csr_hpmcounter27_c | csr_hpmcounter28_c | csr_hpmcounter29_c | csr_hpmcounter30_c | csr_hpmcounter31_c | |
csr_hpmcounter3h_c | csr_hpmcounter4h_c | csr_hpmcounter5h_c | csr_hpmcounter6h_c | csr_hpmcounter7h_c | csr_hpmcounter8h_c | -- HIGH |
csr_hpmcounter9h_c | csr_hpmcounter10h_c | csr_hpmcounter11h_c | csr_hpmcounter12h_c | csr_hpmcounter13h_c | csr_hpmcounter14h_c | |
csr_hpmcounter15h_c | csr_hpmcounter16h_c | csr_hpmcounter17h_c | csr_hpmcounter18h_c | csr_hpmcounter19h_c | csr_hpmcounter20h_c | |
csr_hpmcounter21h_c | csr_hpmcounter22h_c | csr_hpmcounter23h_c | csr_hpmcounter24h_c | csr_hpmcounter25h_c | csr_hpmcounter26h_c | |
csr_hpmcounter27h_c | csr_hpmcounter28h_c | csr_hpmcounter29h_c | csr_hpmcounter30h_c | csr_hpmcounter31h_c => |
if (HPM_NUM_CNTS > 0) then |
csr_acc_valid <= (not csr_wacc_v) and (csr.priv_m_mode or csr_mcounteren_hpm_v(to_integer(unsigned(csr.addr(4 downto 0))))); -- M-mode, U-mode if authorized, read-only |
else |
NULL; |
end if; |
|
-- machine counter setup -- |
when csr_mcountinhibit_c => |
csr_acc_valid <= csr.priv_m_mode; -- M-mode only |
|
when csr_mhpmevent3_c | csr_mhpmevent4_c | csr_mhpmevent5_c | csr_mhpmevent6_c | csr_mhpmevent7_c | csr_mhpmevent8_c | |
csr_mhpmevent9_c | csr_mhpmevent10_c | csr_mhpmevent11_c | csr_mhpmevent12_c | csr_mhpmevent13_c | csr_mhpmevent14_c | |
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; |
|
-- machine information registers & custom (NEORV32-specific) read-only CSRs -- |
when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mzext_c => |
1455,7 → 1396,6
opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11"; -- save some bits here, LSBs are always 11 for rv32 |
case opcode_v is |
|
|
when opcode_lui_c | opcode_auipc_c | opcode_jal_c => -- check sufficient LUI, UIPC, JAL (only check actual OPCODE) |
-- ------------------------------------------------------------ |
illegal_instruction <= '0'; |
1466,7 → 1406,11
|
when opcode_alu_c => -- check ALU.funct3 & ALU.funct7 |
-- ------------------------------------------------------------ |
if (execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV |
if (decode_aux.is_m_mul = '1') then -- MUL |
if (CPU_EXTENSION_RISCV_M = false) and (CPU_EXTENSION_RISCV_Zmmul = false) then -- not implemented |
illegal_instruction <= '1'; |
end if; |
elsif (decode_aux.is_m_div = '1') then -- DIV |
if (CPU_EXTENSION_RISCV_M = false) then -- not implemented |
illegal_instruction <= '1'; |
end if; |
1561,10 → 1505,9
|
when opcode_fence_c => -- fence instructions |
-- ------------------------------------------------------------ |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) then -- FENCE.I -- NO trap if not implemented |
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fencei_c) or -- FENCE.I -- NO trap if not implemented |
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE |
illegal_instruction <= '0'; |
elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_fence_c) then -- FENCE |
illegal_instruction <= '0'; |
else |
illegal_instruction <= '1'; |
end if; |
1741,14 → 1684,10
trap_ctrl.irq_fire <= (or_reduce_f(trap_ctrl.irq_buf) and csr.mstatus_mie and trap_ctrl.db_irq_en) or trap_ctrl.db_irq_fire; -- interrupts CAN be masked |
|
-- debug mode (entry) interrupts -- |
trap_ctrl.db_irq_en <= '1' when (CPU_EXTENSION_RISCV_DEBUG = false) else |
'0' when (debug_ctrl.running = '1') or (csr.dcsr_step = '1') else '1'; -- no interrupts when IN debug mode or IN single-step mode |
trap_ctrl.db_irq_en <= '0' when (CPU_EXTENSION_RISCV_DEBUG = true) and ((debug_ctrl.running = '1') or (csr.dcsr_step = '1')) else '1'; -- no interrupts when IN debug mode or IN single-step mode |
trap_ctrl.db_irq_fire <= (trap_ctrl.irq_buf(interrupt_db_step_c) or trap_ctrl.irq_buf(interrupt_db_halt_c)) when (CPU_EXTENSION_RISCV_DEBUG = true) else '0'; -- "NMI" for debug mode entry |
|
-- acknowledge mask output -- |
firq_ack_o <= trap_ctrl.irq_ack(interrupt_firq_15_c downto interrupt_firq_0_c); |
|
|
-- Trap Priority Encoder ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
trap_priority: process(trap_ctrl) |
1998,10 → 1937,9
-- |
csr.mhpmevent <= (others => (others => def_rst_val_c)); |
-- |
csr.mcounteren_cy <= def_rst_val_c; |
csr.mcounteren_tm <= def_rst_val_c; |
csr.mcounteren_ir <= def_rst_val_c; |
csr.mcounteren_hpm <= (others => def_rst_val_c); |
csr.mcounteren_cy <= def_rst_val_c; |
csr.mcounteren_tm <= def_rst_val_c; |
csr.mcounteren_ir <= def_rst_val_c; |
-- |
csr.mcountinhibit_cy <= def_rst_val_c; |
csr.mcountinhibit_ir <= def_rst_val_c; |
2075,10 → 2013,9
-- R/W: machine counter enable register -- |
if (CPU_EXTENSION_RISCV_U = true) then -- this CSR is hardwired to zero if user mode is not implemented |
if (csr.addr(3 downto 0) = csr_mcounteren_c(3 downto 0)) then |
csr.mcounteren_cy <= csr.wdata(0); -- enable user-level access to cycle[h] |
csr.mcounteren_tm <= csr.wdata(1); -- enable user-level access to time[h] |
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h] |
csr.mcounteren_hpm <= csr.wdata(csr.mcounteren_hpm'left+3 downto 3); -- enable user-level access to hpmcounterx[h] |
csr.mcounteren_cy <= csr.wdata(0); -- enable user-level access to cycle[h] |
csr.mcounteren_tm <= csr.wdata(1); -- enable user-level access to time[h] |
csr.mcounteren_ir <= csr.wdata(2); -- enable user-level access to instret[h] |
end if; |
end if; |
end if; |
2228,7 → 2165,7
|
end if; |
|
-- trap enter: write dpc and dcsr -- |
-- DEBUG MODE (trap) enter: write dpc and dcsr -- |
-- -------------------------------------------------------------------- |
if (CPU_EXTENSION_RISCV_DEBUG = true) and (trap_ctrl.cause(5) = '1') and (debug_ctrl.running = '0') then -- debug mode entry exception |
|
2287,14 → 2224,13
|
-- user mode disabled -- |
if (CPU_EXTENSION_RISCV_U = false) then |
csr.privilege <= priv_mode_m_c; |
csr.mstatus_mpp <= priv_mode_m_c; |
csr.mcounteren_cy <= '0'; |
csr.mcounteren_tm <= '0'; |
csr.mcounteren_ir <= '0'; |
csr.mcounteren_hpm <= (others => '0'); |
csr.dcsr_ebreaku <= '0'; |
csr.dcsr_prv <= priv_mode_m_c; |
csr.privilege <= priv_mode_m_c; |
csr.mstatus_mpp <= priv_mode_m_c; |
csr.mcounteren_cy <= '0'; |
csr.mcounteren_tm <= '0'; |
csr.mcounteren_ir <= '0'; |
csr.dcsr_ebreaku <= '0'; |
csr.dcsr_prv <= priv_mode_m_c; |
end if; |
|
-- pmp disabled -- |
2306,7 → 2242,6
-- hpms disabled -- |
if (HPM_NUM_CNTS = 0) then |
csr.mhpmevent <= (others => (others => '0')); |
csr.mcounteren_hpm <= (others => '0'); |
csr.mcountinhibit_hpm <= (others => '0'); |
end if; |
|
2338,7 → 2273,7
end process csr_write_access; |
|
-- decode current privilege mode -- |
csr.privilege_rd <= priv_mode_m_c when (CPU_EXTENSION_RISCV_E) and (debug_ctrl.running = '1') else csr.privilege; -- effective privilege mode ("machine" when in debug mode) |
csr.privilege_rd <= priv_mode_m_c when (CPU_EXTENSION_RISCV_DEBUG = true) and (debug_ctrl.running = '1') else csr.privilege; -- effective privilege mode ("machine" when in debug mode) |
csr.priv_m_mode <= '1' when (csr.privilege_rd = priv_mode_m_c) else '0'; |
csr.priv_u_mode <= '1' when (csr.privilege_rd = priv_mode_u_c) and (CPU_EXTENSION_RISCV_U = true) else '0'; |
|
2367,10 → 2302,7
end if; |
end process pmp_rd_dummy; |
|
-- FPU rounding mode -- |
fpu_rm_o <= csr.frm; |
|
|
-- Control and Status Registers - Counters ------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
csr_counters: process(rstn_i, clk_i) |
2377,28 → 2309,28
begin |
-- Counter CSRs (each counter is split into two 32-bit counters - coupled via an MSB overflow detector) |
if (rstn_i = '0') then |
csr.mcycle <= (others => def_rst_val_c); |
csr.mcycle_msb <= def_rst_val_c; |
csr.mcycleh <= (others => def_rst_val_c); |
csr.minstret <= (others => def_rst_val_c); |
csr.minstret_msb <= def_rst_val_c; |
csr.minstreth <= (others => def_rst_val_c); |
csr.mhpmcounter <= (others => (others => def_rst_val_c)); |
csr.mhpmcounter_msb <= (others => def_rst_val_c); |
csr.mhpmcounterh <= (others => (others => def_rst_val_c)); |
csr.mcycle <= (others => def_rst_val_c); |
csr.mcycle_ovfl <= (others => def_rst_val_c); |
csr.mcycleh <= (others => def_rst_val_c); |
csr.minstret <= (others => def_rst_val_c); |
csr.minstret_ovfl <= (others => def_rst_val_c); |
csr.minstreth <= (others => def_rst_val_c); |
csr.mhpmcounter <= (others => (others => def_rst_val_c)); |
csr.mhpmcounter_ovfl <= (others => (others => def_rst_val_c)); |
csr.mhpmcounterh <= (others => (others => def_rst_val_c)); |
elsif rising_edge(clk_i) then |
|
-- [m]cycle -- |
if (cpu_cnt_lo_width_c > 0) then |
csr.mcycle_msb <= csr.mcycle(csr.mcycle'left); |
csr.mcycle_ovfl(0) <= csr.mcycle_nxt(csr.mcycle_nxt'left); |
if (csr.we = '1') and (csr.addr = csr_mcycle_c) then -- write access |
csr.mcycle(cpu_cnt_lo_width_c downto 0) <= '0' & csr.wdata(cpu_cnt_lo_width_c-1 downto 0); |
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0); |
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update |
csr.mcycle(cpu_cnt_lo_width_c downto 0) <= std_ulogic_vector(unsigned('0' & csr.mcycle(cpu_cnt_lo_width_c-1 downto 0)) + 1); |
csr.mcycle(cpu_cnt_lo_width_c-1 downto 0) <= csr.mcycle_nxt(cpu_cnt_lo_width_c-1 downto 0); |
end if; |
else |
csr.mcycle <= (others => '-'); |
csr.mcycle_msb <= '-'; |
csr.mcycle <= (others => '-'); |
csr.mcycle_ovfl(0) <= '-'; |
end if; |
|
-- [m]cycleh -- |
2405,8 → 2337,8
if (cpu_cnt_hi_width_c > 0) then |
if (csr.we = '1') and (csr.addr = csr_mcycleh_c) then -- write access |
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0); |
elsif (csr.mcycle_msb = '0') and (csr.mcycle(csr.mcycle'left) = '1') then -- automatic update (continued) |
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0)) + 1); |
elsif (csr.mcountinhibit_cy = '0') and (cnt_event(hpmcnt_event_cy_c) = '1') then -- non-inhibited automatic update |
csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mcycleh(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mcycle_ovfl)); |
end if; |
else |
csr.mcycleh <= (others => '-'); |
2415,15 → 2347,15
|
-- [m]instret -- |
if (cpu_cnt_lo_width_c > 0) then |
csr.minstret_msb <= csr.minstret(csr.minstret'left); |
csr.minstret_ovfl(0) <= csr.minstret_nxt(csr.minstret_nxt'left); |
if (csr.we = '1') and (csr.addr = csr_minstret_c) then -- write access |
csr.minstret(cpu_cnt_lo_width_c downto 0) <= '0' & csr.wdata(cpu_cnt_lo_width_c-1 downto 0); |
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.wdata(cpu_cnt_lo_width_c-1 downto 0); |
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update |
csr.minstret(cpu_cnt_lo_width_c downto 0) <= std_ulogic_vector(unsigned('0' & csr.minstret(cpu_cnt_lo_width_c-1 downto 0)) + 1); |
csr.minstret(cpu_cnt_lo_width_c-1 downto 0) <= csr.minstret_nxt(cpu_cnt_lo_width_c-1 downto 0); |
end if; |
else |
csr.minstret <= (others => '-'); |
csr.minstret_msb <= '-'; |
csr.minstret <= (others => '-'); |
csr.minstret_ovfl(0) <= '-'; |
end if; |
|
-- [m]instreth -- |
2430,8 → 2362,8
if (cpu_cnt_hi_width_c > 0) then |
if (csr.we = '1') and (csr.addr = csr_minstreth_c) then -- write access |
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= csr.wdata(cpu_cnt_hi_width_c-1 downto 0); |
elsif (csr.minstret_msb = '0') and (csr.minstret(csr.minstret'left) = '1') then -- automatic update (continued) |
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.minstreth(cpu_cnt_hi_width_c-1 downto 0)) + 1); |
elsif (csr.mcountinhibit_ir = '0') and (cnt_event(hpmcnt_event_ir_c) = '1') then -- non-inhibited automatic update |
csr.minstreth(cpu_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.minstreth(cpu_cnt_hi_width_c-1 downto 0)) + unsigned(csr.minstret_ovfl)); |
end if; |
else |
csr.minstreth <= (others => '-'); |
2443,15 → 2375,15
|
-- [m]hpmcounter* -- |
if (hpm_cnt_lo_width_c > 0) then |
csr.mhpmcounter_msb(i) <= csr.mhpmcounter(i)(csr.mhpmcounter(i)'left); |
csr.mhpmcounter_ovfl(i)(0) <= csr.mhpmcounter_nxt(i)(csr.mhpmcounter_nxt(i)'left); |
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3_c) + i)) then -- write access |
csr.mhpmcounter(i)(hpm_cnt_lo_width_c downto 0) <= '0' & csr.wdata(hpm_cnt_lo_width_c-1 downto 0); |
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.wdata(hpm_cnt_lo_width_c-1 downto 0); |
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update |
csr.mhpmcounter(i)(hpm_cnt_lo_width_c downto 0) <= std_ulogic_vector(unsigned('0' & csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0)) + 1); |
csr.mhpmcounter(i)(hpm_cnt_lo_width_c-1 downto 0) <= csr.mhpmcounter_nxt(i)(hpm_cnt_lo_width_c-1 downto 0); |
end if; |
else |
csr.mhpmcounter(i) <= (others => '-'); |
csr.mhpmcounter_msb(i) <= '-'; |
csr.mhpmcounter(i) <= (others => '-'); |
csr.mhpmcounter_ovfl(i)(0) <= '-'; |
end if; |
|
-- [m]hpmcounter*h -- |
2458,8 → 2390,8
if (hpm_cnt_hi_width_c > 0) then |
if (csr.we = '1') and (csr.addr = std_ulogic_vector(unsigned(csr_mhpmcounter3h_c) + i)) then -- write access |
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= csr.wdata(hpm_cnt_hi_width_c-1 downto 0); |
elsif (csr.mhpmcounter_msb(i) = '0') and (csr.mhpmcounter(i)(csr.mhpmcounter(i)'left) = '1') then -- automatic update (continued) |
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0)) + 1); |
elsif (csr.mcountinhibit_hpm(i) = '0') and (hpmcnt_trigger(i) = '1') then -- non-inhibited automatic update |
csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0) <= std_ulogic_vector(unsigned(csr.mhpmcounterh(i)(hpm_cnt_hi_width_c-1 downto 0)) + unsigned(csr.mhpmcounter_ovfl(i))); |
end if; |
else |
csr.mhpmcounterh(i) <= (others => '-'); |
2471,7 → 2403,18
end process csr_counters; |
|
|
-- hpm counters read dummy -- |
-- mcycle & minstret increment LOW -- |
csr.mcycle_nxt <= std_ulogic_vector(unsigned('0' & csr.mcycle) + 1); |
csr.minstret_nxt <= std_ulogic_vector(unsigned('0' & csr.minstret) + 1); |
|
-- hpm counter increment LOW -- |
hmp_cnt_lo_inc: |
for i in 0 to HPM_NUM_CNTS-1 generate |
csr.mhpmcounter_nxt(i) <= std_ulogic_vector(unsigned('0' & csr.mhpmcounter(i)) + 1); |
end generate; |
|
|
-- hpm counter read -- |
hpm_rd_dummy: process(csr) |
begin |
csr.mhpmcounter_rd <= (others => (others => '0')); |
2537,10 → 2480,7
-- ------------------------------------------------------------------------------------------- |
csr_read_access: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
csr.re <= def_rst_val_c; |
csr.rdata <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
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 |
2588,7 → 2528,6
csr.rdata(0) <= csr.mcounteren_cy; -- enable user-level access to cycle[h] |
csr.rdata(1) <= csr.mcounteren_tm; -- enable user-level access to time[h] |
csr.rdata(2) <= csr.mcounteren_ir; -- enable user-level access to instret[h] |
csr.rdata(csr.mcounteren_hpm'left+3 downto 3) <= csr.mcounteren_hpm; -- enable user-level access to hpmcounterx[h] |
end if; |
|
-- machine trap handling -- |
2752,69 → 2691,69
|
-- hardware performance counters -- |
-- -------------------------------------------------------------------- |
when csr_hpmcounter3_c | csr_mhpmcounter3_c => if (HPM_NUM_CNTS > 00) then csr.rdata <= csr.mhpmcounter_rd(00); else NULL; end if; -- (R)/(W): [m]hpmcounter3 - low |
when csr_hpmcounter4_c | csr_mhpmcounter4_c => if (HPM_NUM_CNTS > 01) then csr.rdata <= csr.mhpmcounter_rd(01); else NULL; end if; -- (R)/(W): [m]hpmcounter4 - low |
when csr_hpmcounter5_c | csr_mhpmcounter5_c => if (HPM_NUM_CNTS > 02) then csr.rdata <= csr.mhpmcounter_rd(02); else NULL; end if; -- (R)/(W): [m]hpmcounter5 - low |
when csr_hpmcounter6_c | csr_mhpmcounter6_c => if (HPM_NUM_CNTS > 03) then csr.rdata <= csr.mhpmcounter_rd(03); else NULL; end if; -- (R)/(W): [m]hpmcounter6 - low |
when csr_hpmcounter7_c | csr_mhpmcounter7_c => if (HPM_NUM_CNTS > 04) then csr.rdata <= csr.mhpmcounter_rd(04); else NULL; end if; -- (R)/(W): [m]hpmcounter7 - low |
when csr_hpmcounter8_c | csr_mhpmcounter8_c => if (HPM_NUM_CNTS > 05) then csr.rdata <= csr.mhpmcounter_rd(05); else NULL; end if; -- (R)/(W): [m]hpmcounter8 - low |
when csr_hpmcounter9_c | csr_mhpmcounter9_c => if (HPM_NUM_CNTS > 06) then csr.rdata <= csr.mhpmcounter_rd(06); else NULL; end if; -- (R)/(W): [m]hpmcounter9 - low |
when csr_hpmcounter10_c | csr_mhpmcounter10_c => if (HPM_NUM_CNTS > 07) then csr.rdata <= csr.mhpmcounter_rd(07); else NULL; end if; -- (R)/(W): [m]hpmcounter10 - low |
when csr_hpmcounter11_c | csr_mhpmcounter11_c => if (HPM_NUM_CNTS > 08) then csr.rdata <= csr.mhpmcounter_rd(08); else NULL; end if; -- (R)/(W): [m]hpmcounter11 - low |
when csr_hpmcounter12_c | csr_mhpmcounter12_c => if (HPM_NUM_CNTS > 09) then csr.rdata <= csr.mhpmcounter_rd(09); else NULL; end if; -- (R)/(W): [m]hpmcounter12 - low |
when csr_hpmcounter13_c | csr_mhpmcounter13_c => if (HPM_NUM_CNTS > 10) then csr.rdata <= csr.mhpmcounter_rd(10); else NULL; end if; -- (R)/(W): [m]hpmcounter13 - low |
when csr_hpmcounter14_c | csr_mhpmcounter14_c => if (HPM_NUM_CNTS > 11) then csr.rdata <= csr.mhpmcounter_rd(11); else NULL; end if; -- (R)/(W): [m]hpmcounter14 - low |
when csr_hpmcounter15_c | csr_mhpmcounter15_c => if (HPM_NUM_CNTS > 12) then csr.rdata <= csr.mhpmcounter_rd(12); else NULL; end if; -- (R)/(W): [m]hpmcounter15 - low |
when csr_hpmcounter16_c | csr_mhpmcounter16_c => if (HPM_NUM_CNTS > 13) then csr.rdata <= csr.mhpmcounter_rd(13); else NULL; end if; -- (R)/(W): [m]hpmcounter16 - low |
when csr_hpmcounter17_c | csr_mhpmcounter17_c => if (HPM_NUM_CNTS > 14) then csr.rdata <= csr.mhpmcounter_rd(14); else NULL; end if; -- (R)/(W): [m]hpmcounter17 - low |
when csr_hpmcounter18_c | csr_mhpmcounter18_c => if (HPM_NUM_CNTS > 15) then csr.rdata <= csr.mhpmcounter_rd(15); else NULL; end if; -- (R)/(W): [m]hpmcounter18 - low |
when csr_hpmcounter19_c | csr_mhpmcounter19_c => if (HPM_NUM_CNTS > 16) then csr.rdata <= csr.mhpmcounter_rd(16); else NULL; end if; -- (R)/(W): [m]hpmcounter19 - low |
when csr_hpmcounter20_c | csr_mhpmcounter20_c => if (HPM_NUM_CNTS > 17) then csr.rdata <= csr.mhpmcounter_rd(17); else NULL; end if; -- (R)/(W): [m]hpmcounter20 - low |
when csr_hpmcounter21_c | csr_mhpmcounter21_c => if (HPM_NUM_CNTS > 18) then csr.rdata <= csr.mhpmcounter_rd(18); else NULL; end if; -- (R)/(W): [m]hpmcounter21 - low |
when csr_hpmcounter22_c | csr_mhpmcounter22_c => if (HPM_NUM_CNTS > 19) then csr.rdata <= csr.mhpmcounter_rd(19); else NULL; end if; -- (R)/(W): [m]hpmcounter22 - low |
when csr_hpmcounter23_c | csr_mhpmcounter23_c => if (HPM_NUM_CNTS > 20) then csr.rdata <= csr.mhpmcounter_rd(20); else NULL; end if; -- (R)/(W): [m]hpmcounter23 - low |
when csr_hpmcounter24_c | csr_mhpmcounter24_c => if (HPM_NUM_CNTS > 21) then csr.rdata <= csr.mhpmcounter_rd(21); else NULL; end if; -- (R)/(W): [m]hpmcounter24 - low |
when csr_hpmcounter25_c | csr_mhpmcounter25_c => if (HPM_NUM_CNTS > 22) then csr.rdata <= csr.mhpmcounter_rd(22); else NULL; end if; -- (R)/(W): [m]hpmcounter25 - low |
when csr_hpmcounter26_c | csr_mhpmcounter26_c => if (HPM_NUM_CNTS > 23) then csr.rdata <= csr.mhpmcounter_rd(23); else NULL; end if; -- (R)/(W): [m]hpmcounter26 - low |
when csr_hpmcounter27_c | csr_mhpmcounter27_c => if (HPM_NUM_CNTS > 24) then csr.rdata <= csr.mhpmcounter_rd(24); else NULL; end if; -- (R)/(W): [m]hpmcounter27 - low |
when csr_hpmcounter28_c | csr_mhpmcounter28_c => if (HPM_NUM_CNTS > 25) then csr.rdata <= csr.mhpmcounter_rd(25); else NULL; end if; -- (R)/(W): [m]hpmcounter28 - low |
when csr_hpmcounter29_c | csr_mhpmcounter29_c => if (HPM_NUM_CNTS > 26) then csr.rdata <= csr.mhpmcounter_rd(26); else NULL; end if; -- (R)/(W): [m]hpmcounter29 - low |
when csr_hpmcounter30_c | csr_mhpmcounter30_c => if (HPM_NUM_CNTS > 27) then csr.rdata <= csr.mhpmcounter_rd(27); else NULL; end if; -- (R)/(W): [m]hpmcounter30 - low |
when csr_hpmcounter31_c | csr_mhpmcounter31_c => if (HPM_NUM_CNTS > 28) then csr.rdata <= csr.mhpmcounter_rd(28); else NULL; end if; -- (R)/(W): [m]hpmcounter31 - low |
when csr_mhpmcounter3_c => if (HPM_NUM_CNTS > 00) then csr.rdata <= csr.mhpmcounter_rd(00); else NULL; end if; -- r/w: mhpmcounter3 - low |
when csr_mhpmcounter4_c => if (HPM_NUM_CNTS > 01) then csr.rdata <= csr.mhpmcounter_rd(01); else NULL; end if; -- r/w: mhpmcounter4 - low |
when csr_mhpmcounter5_c => if (HPM_NUM_CNTS > 02) then csr.rdata <= csr.mhpmcounter_rd(02); else NULL; end if; -- r/w: mhpmcounter5 - low |
when csr_mhpmcounter6_c => if (HPM_NUM_CNTS > 03) then csr.rdata <= csr.mhpmcounter_rd(03); else NULL; end if; -- r/w: mhpmcounter6 - low |
when csr_mhpmcounter7_c => if (HPM_NUM_CNTS > 04) then csr.rdata <= csr.mhpmcounter_rd(04); else NULL; end if; -- r/w: mhpmcounter7 - low |
when csr_mhpmcounter8_c => if (HPM_NUM_CNTS > 05) then csr.rdata <= csr.mhpmcounter_rd(05); else NULL; end if; -- r/w: mhpmcounter8 - low |
when csr_mhpmcounter9_c => if (HPM_NUM_CNTS > 06) then csr.rdata <= csr.mhpmcounter_rd(06); else NULL; end if; -- r/w: mhpmcounter9 - low |
when csr_mhpmcounter10_c => if (HPM_NUM_CNTS > 07) then csr.rdata <= csr.mhpmcounter_rd(07); else NULL; end if; -- r/w: mhpmcounter10 - low |
when csr_mhpmcounter11_c => if (HPM_NUM_CNTS > 08) then csr.rdata <= csr.mhpmcounter_rd(08); else NULL; end if; -- r/w: mhpmcounter11 - low |
when csr_mhpmcounter12_c => if (HPM_NUM_CNTS > 09) then csr.rdata <= csr.mhpmcounter_rd(09); else NULL; end if; -- r/w: mhpmcounter12 - low |
when csr_mhpmcounter13_c => if (HPM_NUM_CNTS > 10) then csr.rdata <= csr.mhpmcounter_rd(10); else NULL; end if; -- r/w: mhpmcounter13 - low |
when csr_mhpmcounter14_c => if (HPM_NUM_CNTS > 11) then csr.rdata <= csr.mhpmcounter_rd(11); else NULL; end if; -- r/w: mhpmcounter14 - low |
when csr_mhpmcounter15_c => if (HPM_NUM_CNTS > 12) then csr.rdata <= csr.mhpmcounter_rd(12); else NULL; end if; -- r/w: mhpmcounter15 - low |
when csr_mhpmcounter16_c => if (HPM_NUM_CNTS > 13) then csr.rdata <= csr.mhpmcounter_rd(13); else NULL; end if; -- r/w: mhpmcounter16 - low |
when csr_mhpmcounter17_c => if (HPM_NUM_CNTS > 14) then csr.rdata <= csr.mhpmcounter_rd(14); else NULL; end if; -- r/w: mhpmcounter17 - low |
when csr_mhpmcounter18_c => if (HPM_NUM_CNTS > 15) then csr.rdata <= csr.mhpmcounter_rd(15); else NULL; end if; -- r/w: mhpmcounter18 - low |
when csr_mhpmcounter19_c => if (HPM_NUM_CNTS > 16) then csr.rdata <= csr.mhpmcounter_rd(16); else NULL; end if; -- r/w: mhpmcounter19 - low |
when csr_mhpmcounter20_c => if (HPM_NUM_CNTS > 17) then csr.rdata <= csr.mhpmcounter_rd(17); else NULL; end if; -- r/w: mhpmcounter20 - low |
when csr_mhpmcounter21_c => if (HPM_NUM_CNTS > 18) then csr.rdata <= csr.mhpmcounter_rd(18); else NULL; end if; -- r/w: mhpmcounter21 - low |
when csr_mhpmcounter22_c => if (HPM_NUM_CNTS > 19) then csr.rdata <= csr.mhpmcounter_rd(19); else NULL; end if; -- r/w: mhpmcounter22 - low |
when csr_mhpmcounter23_c => if (HPM_NUM_CNTS > 20) then csr.rdata <= csr.mhpmcounter_rd(20); else NULL; end if; -- r/w: mhpmcounter23 - low |
when csr_mhpmcounter24_c => if (HPM_NUM_CNTS > 21) then csr.rdata <= csr.mhpmcounter_rd(21); else NULL; end if; -- r/w: mhpmcounter24 - low |
when csr_mhpmcounter25_c => if (HPM_NUM_CNTS > 22) then csr.rdata <= csr.mhpmcounter_rd(22); else NULL; end if; -- r/w: mhpmcounter25 - low |
when csr_mhpmcounter26_c => if (HPM_NUM_CNTS > 23) then csr.rdata <= csr.mhpmcounter_rd(23); else NULL; end if; -- r/w: mhpmcounter26 - low |
when csr_mhpmcounter27_c => if (HPM_NUM_CNTS > 24) then csr.rdata <= csr.mhpmcounter_rd(24); else NULL; end if; -- r/w: mhpmcounter27 - low |
when csr_mhpmcounter28_c => if (HPM_NUM_CNTS > 25) then csr.rdata <= csr.mhpmcounter_rd(25); else NULL; end if; -- r/w: mhpmcounter28 - low |
when csr_mhpmcounter29_c => if (HPM_NUM_CNTS > 26) then csr.rdata <= csr.mhpmcounter_rd(26); else NULL; end if; -- r/w: mhpmcounter29 - low |
when csr_mhpmcounter30_c => if (HPM_NUM_CNTS > 27) then csr.rdata <= csr.mhpmcounter_rd(27); else NULL; end if; -- r/w: mhpmcounter30 - low |
when csr_mhpmcounter31_c => if (HPM_NUM_CNTS > 28) then csr.rdata <= csr.mhpmcounter_rd(28); else NULL; end if; -- r/w: mhpmcounter31 - low |
|
when csr_hpmcounter3h_c | csr_mhpmcounter3h_c => if (HPM_NUM_CNTS > 00) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(00); else NULL; end if; -- (R)/(W): [m]hpmcounter3h - high |
when csr_hpmcounter4h_c | csr_mhpmcounter4h_c => if (HPM_NUM_CNTS > 01) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(01); else NULL; end if; -- (R)/(W): [m]hpmcounter4h - high |
when csr_hpmcounter5h_c | csr_mhpmcounter5h_c => if (HPM_NUM_CNTS > 02) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(02); else NULL; end if; -- (R)/(W): [m]hpmcounter5h - high |
when csr_hpmcounter6h_c | csr_mhpmcounter6h_c => if (HPM_NUM_CNTS > 03) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(03); else NULL; end if; -- (R)/(W): [m]hpmcounter6h - high |
when csr_hpmcounter7h_c | csr_mhpmcounter7h_c => if (HPM_NUM_CNTS > 04) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(04); else NULL; end if; -- (R)/(W): [m]hpmcounter7h - high |
when csr_hpmcounter8h_c | csr_mhpmcounter8h_c => if (HPM_NUM_CNTS > 05) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(05); else NULL; end if; -- (R)/(W): [m]hpmcounter8h - high |
when csr_hpmcounter9h_c | csr_mhpmcounter9h_c => if (HPM_NUM_CNTS > 06) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(06); else NULL; end if; -- (R)/(W): [m]hpmcounter9h - high |
when csr_hpmcounter10h_c | csr_mhpmcounter10h_c => if (HPM_NUM_CNTS > 07) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(07); else NULL; end if; -- (R)/(W): [m]hpmcounter10h - high |
when csr_hpmcounter11h_c | csr_mhpmcounter11h_c => if (HPM_NUM_CNTS > 08) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(08); else NULL; end if; -- (R)/(W): [m]hpmcounter11h - high |
when csr_hpmcounter12h_c | csr_mhpmcounter12h_c => if (HPM_NUM_CNTS > 09) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(09); else NULL; end if; -- (R)/(W): [m]hpmcounter12h - high |
when csr_hpmcounter13h_c | csr_mhpmcounter13h_c => if (HPM_NUM_CNTS > 10) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(10); else NULL; end if; -- (R)/(W): [m]hpmcounter13h - high |
when csr_hpmcounter14h_c | csr_mhpmcounter14h_c => if (HPM_NUM_CNTS > 11) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(11); else NULL; end if; -- (R)/(W): [m]hpmcounter14h - high |
when csr_hpmcounter15h_c | csr_mhpmcounter15h_c => if (HPM_NUM_CNTS > 12) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(12); else NULL; end if; -- (R)/(W): [m]hpmcounter15h - high |
when csr_hpmcounter16h_c | csr_mhpmcounter16h_c => if (HPM_NUM_CNTS > 13) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(13); else NULL; end if; -- (R)/(W): [m]hpmcounter16h - high |
when csr_hpmcounter17h_c | csr_mhpmcounter17h_c => if (HPM_NUM_CNTS > 14) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(14); else NULL; end if; -- (R)/(W): [m]hpmcounter17h - high |
when csr_hpmcounter18h_c | csr_mhpmcounter18h_c => if (HPM_NUM_CNTS > 15) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(15); else NULL; end if; -- (R)/(W): [m]hpmcounter18h - high |
when csr_hpmcounter19h_c | csr_mhpmcounter19h_c => if (HPM_NUM_CNTS > 16) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(16); else NULL; end if; -- (R)/(W): [m]hpmcounter19h - high |
when csr_hpmcounter20h_c | csr_mhpmcounter20h_c => if (HPM_NUM_CNTS > 17) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(17); else NULL; end if; -- (R)/(W): [m]hpmcounter20h - high |
when csr_hpmcounter21h_c | csr_mhpmcounter21h_c => if (HPM_NUM_CNTS > 18) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(18); else NULL; end if; -- (R)/(W): [m]hpmcounter21h - high |
when csr_hpmcounter22h_c | csr_mhpmcounter22h_c => if (HPM_NUM_CNTS > 19) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(19); else NULL; end if; -- (R)/(W): [m]hpmcounter22h - high |
when csr_hpmcounter23h_c | csr_mhpmcounter23h_c => if (HPM_NUM_CNTS > 20) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(20); else NULL; end if; -- (R)/(W): [m]hpmcounter23h - high |
when csr_hpmcounter24h_c | csr_mhpmcounter24h_c => if (HPM_NUM_CNTS > 21) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(21); else NULL; end if; -- (R)/(W): [m]hpmcounter24h - high |
when csr_hpmcounter25h_c | csr_mhpmcounter25h_c => if (HPM_NUM_CNTS > 22) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(22); else NULL; end if; -- (R)/(W): [m]hpmcounter25h - high |
when csr_hpmcounter26h_c | csr_mhpmcounter26h_c => if (HPM_NUM_CNTS > 23) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(23); else NULL; end if; -- (R)/(W): [m]hpmcounter26h - high |
when csr_hpmcounter27h_c | csr_mhpmcounter27h_c => if (HPM_NUM_CNTS > 24) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(24); else NULL; end if; -- (R)/(W): [m]hpmcounter27h - high |
when csr_hpmcounter28h_c | csr_mhpmcounter28h_c => if (HPM_NUM_CNTS > 25) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(25); else NULL; end if; -- (R)/(W): [m]hpmcounter28h - high |
when csr_hpmcounter29h_c | csr_mhpmcounter29h_c => if (HPM_NUM_CNTS > 26) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(26); else NULL; end if; -- (R)/(W): [m]hpmcounter29h - high |
when csr_hpmcounter30h_c | csr_mhpmcounter30h_c => if (HPM_NUM_CNTS > 27) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(27); else NULL; end if; -- (R)/(W): [m]hpmcounter30h - high |
when csr_hpmcounter31h_c | csr_mhpmcounter31h_c => if (HPM_NUM_CNTS > 28) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(28); else NULL; end if; -- (R)/(W): [m]hpmcounter31h - high |
when csr_mhpmcounter3h_c => if (HPM_NUM_CNTS > 00) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(00); else NULL; end if; -- r/w: mhpmcounter3h - high |
when csr_mhpmcounter4h_c => if (HPM_NUM_CNTS > 01) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(01); else NULL; end if; -- r/w: mhpmcounter4h - high |
when csr_mhpmcounter5h_c => if (HPM_NUM_CNTS > 02) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(02); else NULL; end if; -- r/w: mhpmcounter5h - high |
when csr_mhpmcounter6h_c => if (HPM_NUM_CNTS > 03) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(03); else NULL; end if; -- r/w: mhpmcounter6h - high |
when csr_mhpmcounter7h_c => if (HPM_NUM_CNTS > 04) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(04); else NULL; end if; -- r/w: mhpmcounter7h - high |
when csr_mhpmcounter8h_c => if (HPM_NUM_CNTS > 05) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(05); else NULL; end if; -- r/w: mhpmcounter8h - high |
when csr_mhpmcounter9h_c => if (HPM_NUM_CNTS > 06) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(06); else NULL; end if; -- r/w: mhpmcounter9h - high |
when csr_mhpmcounter10h_c => if (HPM_NUM_CNTS > 07) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(07); else NULL; end if; -- r/w: mhpmcounter10h - high |
when csr_mhpmcounter11h_c => if (HPM_NUM_CNTS > 08) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(08); else NULL; end if; -- r/w: mhpmcounter11h - high |
when csr_mhpmcounter12h_c => if (HPM_NUM_CNTS > 09) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(09); else NULL; end if; -- r/w: mhpmcounter12h - high |
when csr_mhpmcounter13h_c => if (HPM_NUM_CNTS > 10) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(10); else NULL; end if; -- r/w: mhpmcounter13h - high |
when csr_mhpmcounter14h_c => if (HPM_NUM_CNTS > 11) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(11); else NULL; end if; -- r/w: mhpmcounter14h - high |
when csr_mhpmcounter15h_c => if (HPM_NUM_CNTS > 12) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(12); else NULL; end if; -- r/w: mhpmcounter15h - high |
when csr_mhpmcounter16h_c => if (HPM_NUM_CNTS > 13) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(13); else NULL; end if; -- r/w: mhpmcounter16h - high |
when csr_mhpmcounter17h_c => if (HPM_NUM_CNTS > 14) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(14); else NULL; end if; -- r/w: mhpmcounter17h - high |
when csr_mhpmcounter18h_c => if (HPM_NUM_CNTS > 15) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(15); else NULL; end if; -- r/w: mhpmcounter18h - high |
when csr_mhpmcounter19h_c => if (HPM_NUM_CNTS > 16) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(16); else NULL; end if; -- r/w: mhpmcounter19h - high |
when csr_mhpmcounter20h_c => if (HPM_NUM_CNTS > 17) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(17); else NULL; end if; -- r/w: mhpmcounter20h - high |
when csr_mhpmcounter21h_c => if (HPM_NUM_CNTS > 18) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(18); else NULL; end if; -- r/w: mhpmcounter21h - high |
when csr_mhpmcounter22h_c => if (HPM_NUM_CNTS > 19) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(19); else NULL; end if; -- r/w: mhpmcounter22h - high |
when csr_mhpmcounter23h_c => if (HPM_NUM_CNTS > 20) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(20); else NULL; end if; -- r/w: mhpmcounter23h - high |
when csr_mhpmcounter24h_c => if (HPM_NUM_CNTS > 21) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(21); else NULL; end if; -- r/w: mhpmcounter24h - high |
when csr_mhpmcounter25h_c => if (HPM_NUM_CNTS > 22) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(22); else NULL; end if; -- r/w: mhpmcounter25h - high |
when csr_mhpmcounter26h_c => if (HPM_NUM_CNTS > 23) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(23); else NULL; end if; -- r/w: mhpmcounter26h - high |
when csr_mhpmcounter27h_c => if (HPM_NUM_CNTS > 24) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(24); else NULL; end if; -- r/w: mhpmcounter27h - high |
when csr_mhpmcounter28h_c => if (HPM_NUM_CNTS > 25) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(25); else NULL; end if; -- r/w: mhpmcounter28h - high |
when csr_mhpmcounter29h_c => if (HPM_NUM_CNTS > 26) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(26); else NULL; end if; -- r/w: mhpmcounter29h - high |
when csr_mhpmcounter30h_c => if (HPM_NUM_CNTS > 27) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(27); else NULL; end if; -- r/w: mhpmcounter30h - high |
when csr_mhpmcounter31h_c => if (HPM_NUM_CNTS > 28) and (hpm_cnt_hi_width_c > 0) then csr.rdata <= csr.mhpmcounterh_rd(28); else NULL; end if; -- r/w: mhpmcounter31h - high |
|
-- machine information registers -- |
-- -------------------------------------------------------------------- |
when csr_mvendorid_c => csr.rdata <= (others => '0'); -- mvendorid (r/-): vendor ID |
-- when csr_mvendorid_c => csr.rdata <= (others => '0'); -- mvendorid (r/-): vendor ID, implemented but always zero |
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 |
2824,6 → 2763,8
when csr_mzext_c => -- mzext (r/-): available RISC-V Z* sub-extensions |
csr.rdata(0) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Zicsr |
csr.rdata(1) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zifencei); -- Zifencei |
csr.rdata(2) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zmmul); -- Zmmul |
-- ... -- |
csr.rdata(5) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- Zfinx ("F-alternative") |
if (CPU_CNT_WIDTH = 64) then |
csr.rdata(6) <= '0'; -- Zxscnt (custom) |
/core/neorv32_cpu_cp_fpu.vhd
63,7 → 63,6
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus |
start_i : in std_ulogic; -- trigger operation |
-- data input -- |
frm_i : in std_ulogic_vector(2 downto 0); -- rounding mode |
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status |
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1 |
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
367,7 → 366,7
-- rounding mode -- |
-- TODO / FIXME "round to nearest, ties to max magnitude" (0b100) is not supported yet |
if (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "111") then |
fpu_operands.frm <= '0' & frm_i(1 downto 0); |
fpu_operands.frm <= '0' & ctrl_i(ctrl_alu_frm1_c downto ctrl_alu_frm0_c); |
else |
fpu_operands.frm <= '0' & ctrl_i(ctrl_ir_funct3_1_c downto ctrl_ir_funct3_0_c); |
end if; |
505,7 → 504,7
|
-- Min/Max Select (FMIN/FMAX) ------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
min_max_select: process(fpu_operands, comp_less_ff, fpu_operands, fu_compare, ctrl_i) |
min_max_select: process(fpu_operands, comp_less_ff, fu_compare, ctrl_i) |
variable cond_v : std_ulogic_vector(2 downto 0); |
begin |
-- comparison restul - check for special cases: -0 is less than +0 |
/core/neorv32_cpu_cp_muldiv.vhd
1,13 → 1,12
-- ################################################################################################# |
-- # << NEORV32 - CPU Co-Processor: Integer Multiplier/Divider Unit (RISC-V "M" Extension)>> # |
-- # << NEORV32 - CPU Co-Processor: Integer Multiplier/Divider Unit (RISC-V "M" Extension) >> # |
-- # ********************************************************************************************* # |
-- # Multiplier and Divider unit. Implements the RISC-V M CPU extension. # |
-- # # |
-- # Multiplier core (signed/unsigned) uses classical serial algorithm. Unit atency: 31+3 cycles # |
-- # Multiplier core (signed/unsigned) uses classical serial algorithm. Unit latency: 31+3 cycles # |
-- # Divider core (unsigned) uses classical serial algorithm. Unit latency: 32+4 cycles # |
-- # # |
-- # Multiplications can be mapped to DSP blocks (faster!) when FAST_MUL_EN = true. # |
-- # Unit latency: 3 cycles # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
49,7 → 48,8
|
entity neorv32_cpu_cp_muldiv is |
generic ( |
FAST_MUL_EN : boolean := false -- use DSPs for faster multiplication |
FAST_MUL_EN : boolean := false; -- use DSPs for faster multiplication |
DIVISION_EN : boolean := true -- implement divider hardware |
); |
port ( |
-- global control -- |
104,8 → 104,6
signal div_res : std_ulogic_vector(data_width_c-1 downto 0); |
|
-- multiplier core -- |
signal mul_product_p : std_ulogic_vector(63 downto 0); |
signal mul_product_s : std_ulogic_vector(63 downto 0); |
signal mul_product : std_ulogic_vector(63 downto 0); |
signal mul_do_add : std_ulogic_vector(data_width_c downto 0); |
signal mul_sign_cycle : std_ulogic; |
140,7 → 138,7
when IDLE => |
cp_op_ff <= cp_op; |
if (start_i = '1') then |
if (operation = '1') then -- division |
if (operation = '1') and (DIVISION_EN = true) then -- division |
cnt <= "11111"; |
state <= DIV_PREPROCESS; |
else |
154,31 → 152,35
end if; |
|
when DIV_PREPROCESS => |
-- check rlevatn input signs -- |
if (cp_op = cp_op_div_c) then -- result sign compensation for div? |
div_res_corr <= rs1_i(rs1_i'left) xor rs2_i(rs2_i'left); |
elsif (cp_op = cp_op_rem_c) then -- result sign compensation for rem? |
div_res_corr <= rs1_i(rs1_i'left); |
if (DIVISION_EN = true) then |
-- check rlevatn input signs -- |
if (cp_op = cp_op_div_c) then -- result sign compensation for div? |
div_res_corr <= rs1_i(rs1_i'left) xor rs2_i(rs2_i'left); |
elsif (cp_op = cp_op_rem_c) then -- result sign compensation for rem? |
div_res_corr <= rs1_i(rs1_i'left); |
else |
div_res_corr <= '0'; |
end if; |
-- divide by zero? -- |
opy_is_zero <= not or_reduce_f(rs2_i); -- set if rs2 = 0 |
-- abs(rs1) -- |
if ((rs1_i(rs1_i'left) and rs1_is_signed) = '1') then -- signed division? |
div_opx <= std_ulogic_vector(0 - unsigned(rs1_i)); -- make positive |
else |
div_opx <= rs1_i; |
end if; |
-- abs(rs2) -- |
if ((rs2_i(rs2_i'left) and rs2_is_signed) = '1') then -- signed division? |
div_opy <= std_ulogic_vector(0 - unsigned(rs2_i)); -- make positive |
else |
div_opy <= rs2_i; |
end if; |
-- |
start_div <= '1'; |
state <= PROCESSING; |
else |
div_res_corr <= '0'; |
state <= IDLE; |
end if; |
-- divide by zero? -- |
opy_is_zero <= not or_reduce_f(rs2_i); -- set if rs2 = 0 |
-- abs(rs1) -- |
if ((rs1_i(rs1_i'left) and rs1_is_signed) = '1') then -- signed division? |
div_opx <= std_ulogic_vector(0 - unsigned(rs1_i)); -- make positive |
else |
div_opx <= rs1_i; |
end if; |
-- abs(rs2) -- |
if ((rs2_i(rs2_i'left) and rs2_is_signed) = '1') then -- signed division? |
div_opy <= std_ulogic_vector(0 - unsigned(rs2_i)); -- make positive |
else |
div_opy <= rs2_i; |
end if; |
-- |
start_div <= '1'; |
state <= PROCESSING; |
|
when PROCESSING => |
cnt <= std_ulogic_vector(unsigned(cnt) - 1); |
214,40 → 216,42
|
-- Multiplier Core (signed/unsigned) ------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
multiplier_core_serial: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
mul_product_s <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
if (FAST_MUL_EN = false) then -- use small iterative computation |
-- iterative multiplication (bit-serial) -- |
multiplier_core_serial: |
if (FAST_MUL_EN = false) generate |
multiplier_core: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
mul_product <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
if (start_mul = '1') then -- start new multiplication |
mul_product_s(63 downto 32) <= (others => '0'); |
mul_product_s(31 downto 00) <= rs2_i; |
mul_product(63 downto 32) <= (others => '0'); |
mul_product(31 downto 00) <= rs2_i; |
elsif (state = PROCESSING) or (state = FINALIZE) then -- processing step or sign-finalization step |
mul_product_s(63 downto 31) <= mul_do_add(32 downto 0); |
mul_product_s(30 downto 00) <= mul_product_s(31 downto 1); |
mul_product(63 downto 31) <= mul_do_add(32 downto 0); |
mul_product(30 downto 00) <= mul_product(31 downto 1); |
end if; |
end if; |
end if; |
end process multiplier_core_serial; |
end process multiplier_core; |
end generate; |
|
multiplier_core_dsp: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (FAST_MUL_EN = true) then -- use direct approach using DSP blocks |
-- parallel multiplication -- |
multiplier_core_dsp: |
if (FAST_MUL_EN = true) generate |
multiplier_core: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (start_mul = '1') then |
mul_op_x <= signed((rs1_i(rs1_i'left) and rs1_is_signed) & rs1_i); |
mul_op_y <= signed((rs2_i(rs2_i'left) and rs2_is_signed) & rs2_i); |
end if; |
mul_buf_ff <= mul_op_x * mul_op_y; |
mul_product_p <= std_ulogic_vector(mul_buf_ff(63 downto 0)); -- let the register balancing do the magic here |
mul_buf_ff <= mul_op_x * mul_op_y; |
mul_product <= std_ulogic_vector(mul_buf_ff(63 downto 0)); -- let the register balancing do the magic here |
end if; |
end if; |
end process multiplier_core_dsp; |
end process multiplier_core; |
end generate; |
|
mul_product <= mul_product_p when (FAST_MUL_EN = true) else mul_product_s; |
|
-- do another addition -- |
-- do another addition (bit-serial) -- |
mul_update: process(mul_product, mul_sign_cycle, mul_p_sext, rs1_is_signed, rs1_i) |
begin |
-- current bit of rs2_i to take care of -- |
269,35 → 273,46
|
-- Divider Core (unsigned) ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
divider_core: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
quotient <= (others => def_rst_val_c); |
remainder <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
if (start_div = '1') then -- start new division |
quotient <= div_opx; |
remainder <= (others => '0'); |
elsif (state = PROCESSING) or (state = FINALIZE) then -- running? |
quotient <= quotient(30 downto 0) & (not div_sub(32)); |
if (div_sub(32) = '0') then -- still overflowing |
remainder <= div_sub(31 downto 0); |
else -- underflow |
remainder <= remainder(30 downto 0) & quotient(31); |
divider_core_serial: |
if (DIVISION_EN = true) generate |
divider_core: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
quotient <= (others => def_rst_val_c); |
remainder <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
if (start_div = '1') then -- start new division |
quotient <= div_opx; |
remainder <= (others => '0'); |
elsif (state = PROCESSING) or (state = FINALIZE) then -- running? |
quotient <= quotient(30 downto 0) & (not div_sub(32)); |
if (div_sub(32) = '0') then -- still overflowing |
remainder <= div_sub(31 downto 0); |
else -- underflow |
remainder <= remainder(30 downto 0) & quotient(31); |
end if; |
end if; |
end if; |
end if; |
end process divider_core; |
end process divider_core; |
|
-- try another subtraction -- |
div_sub <= std_ulogic_vector(unsigned('0' & remainder(30 downto 0) & quotient(31)) - unsigned('0' & div_opy)); |
-- try another subtraction -- |
div_sub <= std_ulogic_vector(unsigned('0' & remainder(30 downto 0) & quotient(31)) - unsigned('0' & div_opy)); |
|
-- result sign compensation -- |
div_sign_comp_in <= quotient when (cp_op = cp_op_div_c) else remainder; |
div_sign_comp <= std_ulogic_vector(0 - unsigned(div_sign_comp_in)); |
div_res <= div_sign_comp when (div_res_corr = '1') and (opy_is_zero = '0') else div_sign_comp_in; |
-- result sign compensation -- |
div_sign_comp_in <= quotient when (cp_op = cp_op_div_c) else remainder; |
div_sign_comp <= std_ulogic_vector(0 - unsigned(div_sign_comp_in)); |
div_res <= div_sign_comp when (div_res_corr = '1') and (opy_is_zero = '0') else div_sign_comp_in; |
end generate; |
|
-- no divider -- |
divider_core_serial_none: |
if (DIVISION_EN = false) generate |
remainder <= (others => '-'); |
quotient <= (others => '-'); |
div_res <= (others => '-'); |
end generate; |
|
|
-- Data Output ---------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
operation_result: process(rstn_i, clk_i) |
313,17 → 328,21
when cp_op_mulh_c | cp_op_mulhsu_c | cp_op_mulhu_c => |
res_o <= mul_product(63 downto 32); |
when cp_op_div_c => |
res_o <= div_res; |
if (DIVISION_EN = true) then res_o <= div_res; else NULL; end if; |
when cp_op_divu_c => |
res_o <= quotient; |
if (DIVISION_EN = true) then res_o <= quotient; else NULL; end if; |
when cp_op_rem_c => |
if (opy_is_zero = '0') then |
res_o <= div_res; |
if (DIVISION_EN = true) then |
if (opy_is_zero = '0') then |
res_o <= div_res; |
else |
res_o <= rs1_i; |
end if; |
else |
res_o <= rs1_i; |
NULL; |
end if; |
when others => -- cp_op_remu_c |
res_o <= remainder; |
if (DIVISION_EN = true) then res_o <= remainder; else NULL; end if; |
end case; |
end if; |
end if; |
/core/neorv32_cpu_cp_shifter.vhd
0,0 → 1,190
-- ################################################################################################# |
-- # << NEORV32 - CPU Co-Processor: Shifter (CPU Core ISA) >> # |
-- # ********************************************************************************************* # |
-- # Bit-shift unit for base ISA. # |
-- # FAST_SHIFT_EN = false (default): Use bit-serial shifter architecture (small but slow) # |
-- # FAST_SHIFT_EN = true: Use barrel shifter architecture (large but fast) # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
entity neorv32_cpu_cp_shifter is |
generic ( |
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations |
); |
port ( |
-- global control -- |
clk_i : in std_ulogic; -- global clock, rising edge |
rstn_i : in std_ulogic; -- global reset, low-active, async |
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus |
start_i : in std_ulogic; -- trigger operation |
-- data input -- |
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1 |
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
-- result and status -- |
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result |
valid_o : out std_ulogic -- data output valid |
); |
end neorv32_cpu_cp_shifter; |
|
architecture neorv32_cpu_cp_shifter_rtl of neorv32_cpu_cp_shifter is |
|
-- operands -- |
signal shift_amount : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); |
|
-- serial shifter -- |
type shifter_t is record |
busy : std_ulogic; |
busy_ff : std_ulogic; |
done : std_ulogic; |
cnt : std_ulogic_vector(index_size_f(data_width_c)-1 downto 0); |
sreg : std_ulogic_vector(data_width_c-1 downto 0); |
end record; |
signal shifter : shifter_t; |
|
-- barrel shifter -- |
type bs_level_t is array (index_size_f(data_width_c) downto 0) of std_ulogic_vector(data_width_c-1 downto 0); |
signal bs_level : bs_level_t; |
signal bs_result : std_ulogic_vector(data_width_c-1 downto 0); |
|
begin |
|
-- Shift Amount --------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
shift_amount <= imm_i(index_size_f(data_width_c)-1 downto 0) when (ctrl_i(ctrl_alu_opb_mux_c) = '1') else -- immediate source |
rs2_i(index_size_f(data_width_c)-1 downto 0); -- register source |
|
|
-- Iterative Shifter Core (small but slow) ------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
serial_shifter_sync: |
if (FAST_SHIFT_EN = false) generate |
shifter_unit_sync: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
shifter.busy <= '0'; |
shifter.busy_ff <= def_rst_val_c; |
shifter.sreg <= (others => def_rst_val_c); |
shifter.cnt <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
shifter.busy_ff <= shifter.busy; |
if (start_i = '1') then |
shifter.busy <= '1'; |
elsif (shifter.done = '1') then |
shifter.busy <= '0'; |
end if; |
-- |
if (start_i = '1') then -- trigger new shift |
shifter.sreg <= rs1_i; -- shift operand |
shifter.cnt <= shift_amount; -- shift amount |
elsif (or_reduce_f(shifter.cnt) = '1') then -- running shift (cnt != 0) |
shifter.cnt <= std_ulogic_vector(unsigned(shifter.cnt) - 1); |
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- SLL: shift left logical |
shifter.sreg <= shifter.sreg(shifter.sreg'left-1 downto 0) & '0'; |
else -- SRL: shift right logical / SRA: shift right arithmetical |
shifter.sreg <= (shifter.sreg(shifter.sreg'left) and ctrl_i(ctrl_alu_shift_ar_c)) & shifter.sreg(shifter.sreg'left downto 1); |
end if; |
end if; |
end if; |
end process shifter_unit_sync; |
end generate; |
|
-- shift control -- |
serial_shifter_ctrl: |
if (FAST_SHIFT_EN = false) generate |
shifter.done <= not or_reduce_f(shifter.cnt(shifter.cnt'left downto 1)); |
valid_o <= shifter.busy and shifter.done; |
res_o <= shifter.sreg when (shifter.busy = '0') and (shifter.busy_ff = '1') else (others => '0'); |
end generate; |
|
|
-- Barrel Shifter Core (fast but large) --------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
barrel_shifter_async: |
if (FAST_SHIFT_EN = true) generate |
shifter_unit_async: process(rs1_i, shift_amount, ctrl_i, bs_level) |
begin |
-- input level: convert left shifts to right shifts -- |
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then -- is left shift? |
bs_level(index_size_f(data_width_c)) <= bit_rev_f(rs1_i); -- reverse bit order of input operand |
else |
bs_level(index_size_f(data_width_c)) <= rs1_i; |
end if; |
|
-- shifter array -- |
for i in index_size_f(data_width_c)-1 downto 0 loop |
if (shift_amount(i) = '1') then |
bs_level(i)(data_width_c-1 downto data_width_c-(2**i)) <= (others => (bs_level(i+1)(data_width_c-1) and ctrl_i(ctrl_alu_shift_ar_c))); |
bs_level(i)((data_width_c-(2**i))-1 downto 0) <= bs_level(i+1)(data_width_c-1 downto 2**i); |
else |
bs_level(i) <= bs_level(i+1); |
end if; |
end loop; |
|
-- re-convert original left shifts -- |
if (ctrl_i(ctrl_alu_shift_dir_c) = '0') then |
bs_result <= bit_rev_f(bs_level(0)); |
else |
bs_result <= bs_level(0); |
end if; |
end process shifter_unit_async; |
end generate; |
|
-- output register -- |
barrel_shifter_sync: |
if (FAST_SHIFT_EN = true) generate |
shifter_unit_sync: process(clk_i) |
begin |
if rising_edge(clk_i) then |
res_o <= (others => '0'); |
if (start_i = '1') then |
res_o <= bs_result; |
end if; |
end if; |
end process shifter_unit_sync; |
end generate; |
|
-- shift control -- |
barrel_shifter_ctrl: |
if (FAST_SHIFT_EN = true) generate |
valid_o <= start_i; |
end generate; |
|
|
end neorv32_cpu_cp_shifter_rtl; |
/core/neorv32_debug_dm.vhd
214,7 → 214,8
00000020 => x"01000413", |
00000021 => x"98802023", |
00000022 => x"7b202473", |
00000023 => x"88000067", |
00000023 => x"0000100f", |
00000024 => x"88000067", |
others => x"00100073" -- ebreak |
); |
|
/core/neorv32_dmem.vhd
68,35 → 68,26
signal rden : std_ulogic; |
signal addr : std_ulogic_vector(index_size_f(DMEM_SIZE/4)-1 downto 0); |
|
-- RAM -- |
-- The memory is built from 4x byte-wide memories defined as unique signals, since many synthesis tools |
-- have problems with 32-bit memories with byte-enable signals or with multi-dimensional arrays. |
type dmem_file_t is array (0 to DMEM_SIZE/4-1) of std_ulogic_vector(7 downto 0); |
signal dmem_file_ll : dmem_file_t; |
signal dmem_file_lh : dmem_file_t; |
signal dmem_file_hl : dmem_file_t; |
signal dmem_file_hh : dmem_file_t; |
-- -------------------------------------------------------------------------------------------------------------- -- |
-- The memory (RAM) is built from 4 individual byte-wide memories b0..b3, since some synthesis tools have -- |
-- problems with 32-bit memories that provide dedicated byte-enable signals AND/OR with multi-dimensional arrays. -- |
-- -------------------------------------------------------------------------------------------------------------- -- |
|
-- RAM - not initialized at all -- |
signal mem_ram_b0 : mem8_t(0 to DMEM_SIZE/4-1); |
signal mem_ram_b1 : mem8_t(0 to DMEM_SIZE/4-1); |
signal mem_ram_b2 : mem8_t(0 to DMEM_SIZE/4-1); |
signal mem_ram_b3 : mem8_t(0 to DMEM_SIZE/4-1); |
|
-- -------------------------------------------------------------------------------- -- |
-- attributes - these are *NOT mandatory*; just for footprint / timing optimization -- |
-- -------------------------------------------------------------------------------- -- |
-- read data -- |
signal mem_ram_b0_rd, mem_ram_b1_rd, mem_ram_b2_rd, mem_ram_b3_rd : std_ulogic_vector(7 downto 0); |
|
-- lattice radiant -- |
attribute syn_ramstyle : string; |
attribute syn_ramstyle of dmem_file_ll : signal is "no_rw_check"; |
attribute syn_ramstyle of dmem_file_lh : signal is "no_rw_check"; |
attribute syn_ramstyle of dmem_file_hl : signal is "no_rw_check"; |
attribute syn_ramstyle of dmem_file_hh : signal is "no_rw_check"; |
begin |
|
-- intel quartus prime -- |
attribute ramstyle : string; |
attribute ramstyle of dmem_file_ll : signal is "no_rw_check"; |
attribute ramstyle of dmem_file_lh : signal is "no_rw_check"; |
attribute ramstyle of dmem_file_hl : signal is "no_rw_check"; |
attribute ramstyle of dmem_file_hh : signal is "no_rw_check"; |
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert false report "NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal DMEM (RAM, " & natural'image(DMEM_SIZE) & " bytes)." severity note; |
|
begin |
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
106,36 → 97,50
|
-- Memory Access -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
dmem_file_access: process(clk_i) |
mem_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
rden <= rden_i and acc_en; |
ack_o <= acc_en and (rden_i or wren_i); |
-- this RAM style should not require "no_rw_check" attributes as the read-after-write behavior |
-- is intended to be defined implicitly via the if-WRITE-else-READ construct |
if (acc_en = '1') then -- reduce switching activity when not accessed |
-- write -- |
if (wren_i = '1') then |
if (ben_i(0) = '1') then |
dmem_file_ll(to_integer(unsigned(addr))) <= data_i(07 downto 00); |
end if; |
if (ben_i(1) = '1') then |
dmem_file_lh(to_integer(unsigned(addr))) <= data_i(15 downto 08); |
end if; |
if (ben_i(2) = '1') then |
dmem_file_hl(to_integer(unsigned(addr))) <= data_i(23 downto 16); |
end if; |
if (ben_i(3) = '1') then |
dmem_file_hh(to_integer(unsigned(addr))) <= data_i(31 downto 24); |
end if; |
if (wren_i = '1') and (ben_i(0) = '1') then -- byte 0 |
mem_ram_b0(to_integer(unsigned(addr))) <= data_i(07 downto 00); |
else |
mem_ram_b0_rd <= mem_ram_b0(to_integer(unsigned(addr))); |
end if; |
-- read -- |
rdata(07 downto 00) <= dmem_file_ll(to_integer(unsigned(addr))); |
rdata(15 downto 08) <= dmem_file_lh(to_integer(unsigned(addr))); |
rdata(23 downto 16) <= dmem_file_hl(to_integer(unsigned(addr))); |
rdata(31 downto 24) <= dmem_file_hh(to_integer(unsigned(addr))); |
if (wren_i = '1') and (ben_i(1) = '1') then -- byte 1 |
mem_ram_b1(to_integer(unsigned(addr))) <= data_i(15 downto 08); |
else |
mem_ram_b1_rd <= mem_ram_b1(to_integer(unsigned(addr))); |
end if; |
if (wren_i = '1') and (ben_i(2) = '1') then -- byte 2 |
mem_ram_b2(to_integer(unsigned(addr))) <= data_i(23 downto 16); |
else |
mem_ram_b2_rd <= mem_ram_b2(to_integer(unsigned(addr))); |
end if; |
if (wren_i = '1') and (ben_i(3) = '1') then -- byte 3 |
mem_ram_b3(to_integer(unsigned(addr))) <= data_i(31 downto 24); |
else |
mem_ram_b3_rd <= mem_ram_b3(to_integer(unsigned(addr))); |
end if; |
end if; |
end if; |
end process dmem_file_access; |
end process mem_access; |
|
|
-- Bus Feedback --------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
bus_feedback: process(clk_i) |
begin |
if rising_edge(clk_i) then |
rden <= acc_en and rden_i; |
ack_o <= acc_en and (rden_i or wren_i); |
end if; |
end process bus_feedback; |
|
-- pack -- |
rdata <= mem_ram_b3_rd & mem_ram_b2_rd & mem_ram_b1_rd & mem_ram_b0_rd; |
|
-- output gate -- |
data_o <= rdata when (rden = '1') else (others => '0'); |
|
/core/neorv32_fifo.vhd
0,0 → 1,163
-- ################################################################################################# |
-- # << NEORV32 - General Purpose FIFO Component >> # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
entity neorv32_fifo is |
generic ( |
FIFO_DEPTH : natural := 4; -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH : natural := 32; -- size of data elements in fifo |
FIFO_RSYNC : boolean := false; -- false = async read; true = sync read |
FIFO_SAFE : boolean := false -- true = allow read/write only if data available |
); |
port ( |
-- control -- |
clk_i : in std_ulogic; -- clock, rising edge |
rstn_i : in std_ulogic; -- async reset, low-active |
clear_i : in std_ulogic; -- sync reset, high-active |
-- write port -- |
wdata_i : in std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- write data |
we_i : in std_ulogic; -- write enable |
free_o : out std_ulogic; -- at least one entry is free when set |
-- read port -- |
re_i : in std_ulogic; -- read enable |
rdata_o : out std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- read data |
avail_o : out std_ulogic -- data available when set |
); |
end neorv32_fifo; |
|
architecture neorv32_fifo_rtl of neorv32_fifo is |
|
-- FIFO -- |
type fifo_data_t is array (0 to FIFO_DEPTH-1) of std_ulogic_vector(FIFO_WIDTH-1 downto 0); |
type fifo_t is record |
we : std_ulogic; -- write enable |
re : std_ulogic; -- read enable |
w_pnt : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- write pointer |
r_pnt : std_ulogic_vector(index_size_f(FIFO_DEPTH) downto 0); -- read pointer |
data : fifo_data_t; -- fifo memory |
match : std_ulogic; |
empty : std_ulogic; |
full : std_ulogic; |
free : std_ulogic; |
avail : std_ulogic; |
end record; |
signal fifo : fifo_t; |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert not (FIFO_DEPTH = 0) report "NEORV32 CONFIG ERROR: FIFO depth has to be > 0." severity error; |
assert not (is_power_of_two_f(FIFO_DEPTH) = false) report "NEORV32 CONFIG ERROR: FIFO depth has to be a power of two." severity error; |
|
|
-- 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 Control --------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
fifo_control: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
fifo.w_pnt <= (others => '0'); |
fifo.r_pnt <= (others => '0'); |
elsif rising_edge(clk_i) then |
-- write port -- |
if (clear_i = '1') then |
fifo.w_pnt <= (others => '0'); |
elsif (fifo.we = '1') then |
fifo.w_pnt <= std_ulogic_vector(unsigned(fifo.w_pnt) + 1); |
end if; |
-- read port -- |
if (clear_i = '1') then |
fifo.r_pnt <= (others => '0'); |
elsif (fifo.re = '1') then |
fifo.r_pnt <= std_ulogic_vector(unsigned(fifo.r_pnt) + 1); |
end if; |
end if; |
end process fifo_control; |
|
-- status -- |
fifo.match <= '1' when (fifo.r_pnt(fifo.r_pnt'left-1 downto 0) = fifo.w_pnt(fifo.w_pnt'left-1 downto 0)) else '0'; |
fifo.full <= '1' when (fifo.r_pnt(fifo.r_pnt'left) /= fifo.w_pnt(fifo.w_pnt'left)) and (fifo.match = '1') else '0'; |
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; |
|
-- status output -- |
free_o <= fifo.free; |
avail_o <= fifo.avail; |
|
|
-- FIFO Memory ---------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
fifo_memory_write: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (fifo.we = '1') then |
fifo.data(to_integer(unsigned(fifo.w_pnt(fifo.w_pnt'left-1 downto 0)))) <= wdata_i; |
end if; |
end if; |
end process fifo_memory_write; |
|
-- asynchronous read -- |
fifo_read_async: |
if (FIFO_RSYNC = false) generate |
rdata_o <= fifo.data(to_integer(unsigned(fifo.r_pnt(fifo.r_pnt'left-1 downto 0)))); |
end generate; |
|
-- synchronous read -- |
fifo_read_sync: |
if (FIFO_RSYNC = true) generate |
fifo_memory_read: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (fifo.re = '1') then |
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; |
end generate; |
|
|
end neorv32_fifo_rtl; |
/core/neorv32_gpio.vhd
1,8 → 1,7
-- ################################################################################################# |
-- # << NEORV32 - General Purpose Parallel Input/Output Port (GPIO) >> # |
-- # ********************************************************************************************* # |
-- # 32-bit parallel input & output unit. Any pin change (HI->LO or LO->HI) of an enabled input # |
-- # pin (via irq_en register) triggers an IRQ. # |
-- # 64-bit general purpose parallel input & output port unit. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
53,10 → 52,8
data_o : out std_ulogic_vector(31 downto 0); -- data out |
ack_o : out std_ulogic; -- transfer acknowledge |
-- parallel io -- |
gpio_o : out std_ulogic_vector(31 downto 0); |
gpio_i : in std_ulogic_vector(31 downto 0); |
-- interrupt -- |
irq_o : out std_ulogic |
gpio_o : out std_ulogic_vector(63 downto 0); |
gpio_i : in std_ulogic_vector(63 downto 0) |
); |
end neorv32_gpio; |
|
71,13 → 68,9
signal addr : std_ulogic_vector(31 downto 0); -- access address |
|
-- accessible regs -- |
signal din : std_ulogic_vector(31 downto 0); -- r/- |
signal dout : std_ulogic_vector(31 downto 0); -- r/w |
signal irq_en : std_ulogic_vector(31 downto 0); -- -/w, uses the same address as data_in |
signal din_lo, din_hi : std_ulogic_vector(31 downto 0); -- r/- |
signal dout_lo, dout_hi : std_ulogic_vector(31 downto 0); -- r/w |
|
-- misc -- |
signal in_buf : std_ulogic_vector(31 downto 0); |
|
begin |
|
-- Access Control ------------------------------------------------------------------------- |
91,43 → 84,40
rw_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- bus handshake -- |
ack_o <= acc_en and (rden_i or wren_i); |
|
-- write access -- |
if ((acc_en and wren_i) = '1') then |
if (addr = gpio_in_addr_c) then |
irq_en <= data_i; -- pin change IRQ enable |
else -- gpio_out_addr_c |
dout <= data_i; -- data output port |
if (addr = gpio_out_lo_addr_c) then |
dout_lo <= data_i; |
end if; |
if (addr = gpio_out_hi_addr_c) then |
dout_hi <= data_i; |
end if; |
end if; |
|
-- input buffer -- |
din_lo <= gpio_i(31 downto 00); |
din_hi <= gpio_i(63 downto 32); |
|
-- read access -- |
data_o <= (others => '0'); |
if ((acc_en and rden_i) = '1') then |
if (addr = gpio_in_addr_c) then |
data_o <= din; -- data input port |
else -- gpio_out_addr_c |
data_o <= dout; -- data output port |
end if; |
case addr is |
when gpio_in_lo_addr_c => data_o <= din_lo; |
when gpio_in_hi_addr_c => data_o <= din_hi; |
when gpio_out_lo_addr_c => data_o <= dout_lo; |
when gpio_out_hi_addr_c => data_o <= dout_hi; |
when others => data_o <= (others => '0'); |
end case; |
end if; |
|
end if; |
end process rw_access; |
|
-- output -- |
gpio_o <= dout; |
gpio_o <= dout_hi & dout_lo; |
|
|
-- IRQ Detector ------------------------------------------------------------ |
-- ----------------------------------------------------------------------------- |
irq_detector: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- input synchronizer -- |
in_buf <= gpio_i; |
din <= in_buf; |
-- IRQ -- |
irq_o <= or_reduce_f((in_buf xor din) and irq_en); -- any enabled pin transition triggers an interrupt |
end if; |
end process irq_detector; |
|
|
end neorv32_gpio_rtl; |
/core/neorv32_icache.vhd
132,13 → 132,16
type ctrl_engine_state_t is (S_IDLE, S_CACHE_CLEAR, S_CACHE_CHECK, S_CACHE_MISS, S_BUS_DOWNLOAD_REQ, S_BUS_DOWNLOAD_GET, |
S_CACHE_RESYNC_0, S_CACHE_RESYNC_1, S_BUS_ERROR); |
type ctrl_t is record |
state : ctrl_engine_state_t; -- current state |
state_nxt : ctrl_engine_state_t; -- next state |
addr_reg : std_ulogic_vector(31 downto 0); -- address register for block download |
addr_reg_nxt : std_ulogic_vector(31 downto 0); |
state : ctrl_engine_state_t; -- current state |
state_nxt : ctrl_engine_state_t; -- next state |
addr_reg : std_ulogic_vector(31 downto 0); -- address register for block download |
addr_reg_nxt : std_ulogic_vector(31 downto 0); |
-- |
re_buf : std_ulogic; -- read request buffer |
re_buf_nxt : std_ulogic; |
re_buf : std_ulogic; -- read request buffer |
re_buf_nxt : std_ulogic; |
-- |
clear_buf : std_ulogic; -- clear request buffer |
clear_buf_nxt : std_ulogic; |
end record; |
signal ctrl : ctrl_t; |
|
161,11 → 164,13
ctrl_engine_fsm_sync_rst: process(rstn_i, clk_i) |
begin |
if (rstn_i = '0') then |
ctrl.state <= S_CACHE_CLEAR; |
ctrl.re_buf <= '0'; |
ctrl.state <= S_CACHE_CLEAR; |
ctrl.re_buf <= '0'; |
ctrl.clear_buf <= '0'; |
elsif rising_edge(clk_i) then |
ctrl.state <= ctrl.state_nxt; |
ctrl.re_buf <= ctrl.re_buf_nxt; |
ctrl.state <= ctrl.state_nxt; |
ctrl.re_buf <= ctrl.re_buf_nxt; |
ctrl.clear_buf <= ctrl.clear_buf_nxt; |
end if; |
end process ctrl_engine_fsm_sync_rst; |
|
186,6 → 191,7
ctrl.state_nxt <= ctrl.state; |
ctrl.addr_reg_nxt <= ctrl.addr_reg; |
ctrl.re_buf_nxt <= ctrl.re_buf or host_re_i; |
ctrl.clear_buf_nxt <= ctrl.clear_buf or clear_i; -- buffer clear request from CPU |
|
-- cache defaults -- |
cache.clear <= '0'; |
215,7 → 221,7
|
when S_IDLE => -- wait for host access request or cache control operation |
-- ------------------------------------------------------------ |
if (clear_i = '1') then -- cache control operation? |
if (ctrl.clear_buf = '1') then -- cache control operation? |
ctrl.state_nxt <= S_CACHE_CLEAR; |
elsif (host_re_i = '1') or (ctrl.re_buf = '1') then -- cache access |
ctrl.re_buf_nxt <= '0'; |
224,8 → 230,9
|
when S_CACHE_CLEAR => -- invalidate all cache entries |
-- ------------------------------------------------------------ |
cache.clear <= '1'; |
ctrl.state_nxt <= S_IDLE; |
ctrl.clear_buf_nxt <= '0'; |
cache.clear <= '1'; |
ctrl.state_nxt <= S_IDLE; |
|
when S_CACHE_CHECK => -- finalize host access if cache hit |
-- ------------------------------------------------------------ |
/core/neorv32_imem.vhd
47,10 → 47,9
|
entity neorv32_imem is |
generic ( |
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address |
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes |
IMEM_AS_ROM : boolean := false; -- implement IMEM as read-only memory? |
BOOTLOADER_EN : boolean := true -- implement and use bootloader? |
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address |
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes |
IMEM_AS_IROM : boolean := false -- implement IMEM as pre-initialized read-only memory? |
); |
port ( |
clk_i : in std_ulogic; -- global clock line |
70,21 → 69,6
constant hi_abb_c : natural := 31; -- high address boundary bit |
constant lo_abb_c : natural := index_size_f(IMEM_SIZE); -- low address boundary bit |
|
-- ROM types -- |
type imem_file8_t is array (0 to IMEM_SIZE/4-1) of std_ulogic_vector(07 downto 0); |
|
-- init function and split 1x32-bit memory into 4x8-bit memories -- |
-- impure function: returns NOT the same result every time it is evaluated with the same arguments since the source file might have changed |
impure function init_imem(byte : natural; init : application_init_image_t) return imem_file8_t is |
variable mem_v : imem_file8_t; |
begin |
mem_v := (others => (others => '0')); |
for i in 0 to init'length-1 loop -- init only in range of source data array |
mem_v(i) := init(i)(byte*8+7 downto byte*8+0); |
end loop; -- i |
return mem_v; |
end function init_imem; |
|
-- local signals -- |
signal acc_en : std_ulogic; |
signal rdata : std_ulogic_vector(31 downto 0); |
91,56 → 75,47
signal rden : std_ulogic; |
signal addr : std_ulogic_vector(index_size_f(IMEM_SIZE/4)-1 downto 0); |
|
-- The memory is built from 4x byte-wide memories defined as unique signals, since many synthesis tools |
-- have problems with 32-bit memories with byte-enable signals or with multi-dimensional arrays. |
-- --------------------------- -- |
-- IMEM as pre-initialized ROM -- |
-- --------------------------- -- |
|
-- internal "RAM" type - implemented if bootloader is used and IMEM is RAM and initialized with app code -- |
signal imem_file_init_ram_ll : imem_file8_t := init_imem(0, application_init_image); |
signal imem_file_init_ram_lh : imem_file8_t := init_imem(1, application_init_image); |
signal imem_file_init_ram_hl : imem_file8_t := init_imem(2, application_init_image); |
signal imem_file_init_ram_hh : imem_file8_t := init_imem(3, application_init_image); |
-- application (image) size in bytes -- |
constant imem_app_size_c : natural := (application_init_image'length)*4; |
|
-- internal "ROM" type - implemented if bootloader is NOT used; always initialize with app code -- |
constant imem_file_rom_ll : imem_file8_t := init_imem(0, application_init_image); |
constant imem_file_rom_lh : imem_file8_t := init_imem(1, application_init_image); |
constant imem_file_rom_hl : imem_file8_t := init_imem(2, application_init_image); |
constant imem_file_rom_hh : imem_file8_t := init_imem(3, application_init_image); |
-- ROM - initialized with executable code -- |
constant mem_rom : mem32_t(0 to IMEM_SIZE/4-1) := mem32_init_f(application_init_image, IMEM_SIZE/4); |
|
-- internal "RAM" type - implemented if bootloader is used and IMEM is RAM -- |
signal imem_file_ram_ll : imem_file8_t; |
signal imem_file_ram_lh : imem_file8_t; |
signal imem_file_ram_hl : imem_file8_t; |
signal imem_file_ram_hh : imem_file8_t; |
-- read data -- |
signal mem_rom_rd : std_ulogic_vector(31 downto 0); |
|
-- -------------------------------------------------------------------------------------------------------------- -- |
-- The memory (RAM) is built from 4 individual byte-wide memories b0..b3, since some synthesis tools have -- |
-- problems with 32-bit memories that provide dedicated byte-enable signals AND/OR with multi-dimensional arrays. -- |
-- -------------------------------------------------------------------------------------------------------------- -- |
|
-- -------------------------------------------------------------------------------- -- |
-- attributes - these are *NOT mandatory*; just for footprint / timing optimization -- |
-- -------------------------------------------------------------------------------- -- |
-- RAM - not initialized at all -- |
signal mem_ram_b0 : mem8_t(0 to IMEM_SIZE/4-1); |
signal mem_ram_b1 : mem8_t(0 to IMEM_SIZE/4-1); |
signal mem_ram_b2 : mem8_t(0 to IMEM_SIZE/4-1); |
signal mem_ram_b3 : mem8_t(0 to IMEM_SIZE/4-1); |
|
-- lattice radiant -- |
attribute syn_ramstyle : string; |
attribute syn_ramstyle of imem_file_ram_ll : signal is "no_rw_check"; |
attribute syn_ramstyle of imem_file_ram_lh : signal is "no_rw_check"; |
attribute syn_ramstyle of imem_file_ram_hl : signal is "no_rw_check"; |
attribute syn_ramstyle of imem_file_ram_hh : signal is "no_rw_check"; |
attribute syn_ramstyle of imem_file_init_ram_ll : signal is "no_rw_check"; |
attribute syn_ramstyle of imem_file_init_ram_lh : signal is "no_rw_check"; |
attribute syn_ramstyle of imem_file_init_ram_hl : signal is "no_rw_check"; |
attribute syn_ramstyle of imem_file_init_ram_hh : signal is "no_rw_check"; |
-- read data -- |
signal mem_b0_rd, mem_b1_rd, mem_b2_rd, mem_b3_rd : std_ulogic_vector(7 downto 0); |
|
-- intel quartus prime -- |
attribute ramstyle : string; |
attribute ramstyle of imem_file_ram_ll : signal is "no_rw_check"; |
attribute ramstyle of imem_file_ram_lh : signal is "no_rw_check"; |
attribute ramstyle of imem_file_ram_hl : signal is "no_rw_check"; |
attribute ramstyle of imem_file_ram_hh : signal is "no_rw_check"; |
attribute ramstyle of imem_file_init_ram_ll : signal is "no_rw_check"; |
attribute ramstyle of imem_file_init_ram_lh : signal is "no_rw_check"; |
attribute ramstyle of imem_file_init_ram_hl : signal is "no_rw_check"; |
attribute ramstyle of imem_file_init_ram_hh : signal is "no_rw_check"; |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert not (IMEM_AS_IROM = true) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as ROM (" & natural'image(IMEM_SIZE) & |
" bytes), pre-initialized with application (" & natural'image(imem_app_size_c) & " bytes)." severity note; |
-- |
assert not (IMEM_AS_IROM = false) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing processor-internal IMEM as blank RAM (" & natural'image(IMEM_SIZE) & |
" bytes)." severity note; |
-- |
assert not ((IMEM_AS_IROM = true) and (imem_app_size_c > IMEM_SIZE)) report "NEORV32 PROCESSOR CONFIG ERROR: Application (image = " & natural'image(imem_app_size_c) & |
" bytes) does not fit into processor-internal IMEM (ROM = " & natural'image(IMEM_SIZE) & " bytes)!" severity error; |
|
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = IMEM_BASE(hi_abb_c downto lo_abb_c)) else '0'; |
147,67 → 122,74
addr <= addr_i(index_size_f(IMEM_SIZE/4)+1 downto 2); -- word aligned |
|
|
-- Memory Access -------------------------------------------------------------------------- |
-- Implement IMEM as pre-initialized ROM -------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
imem_file_access: process(clk_i) |
imem_rom: |
if (IMEM_AS_IROM = true) generate |
mem_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
if (acc_en = '1') then -- reduce switching activity when not accessed |
mem_rom_rd <= mem_rom(to_integer(unsigned(addr))); |
end if; |
end if; |
end process mem_access; |
-- read data -- |
rdata <= mem_rom_rd; |
end generate; |
|
|
-- Implement IMEM as not-initialized RAM -------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
imem_ram: |
if (IMEM_AS_IROM = false) generate |
mem_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- this RAM style should not require "no_rw_check" attributes as the read-after-write behavior |
-- is intended to be defined implicitly via the if-WRITE-else-READ construct |
if (acc_en = '1') then -- reduce switching activity when not accessed |
if (wren_i = '1') and (ben_i(0) = '1') then -- byte 0 |
mem_ram_b0(to_integer(unsigned(addr))) <= data_i(07 downto 00); |
else |
mem_b0_rd <= mem_ram_b0(to_integer(unsigned(addr))); |
end if; |
if (wren_i = '1') and (ben_i(1) = '1') then -- byte 1 |
mem_ram_b1(to_integer(unsigned(addr))) <= data_i(15 downto 08); |
else |
mem_b1_rd <= mem_ram_b1(to_integer(unsigned(addr))); |
end if; |
if (wren_i = '1') and (ben_i(2) = '1') then -- byte 2 |
mem_ram_b2(to_integer(unsigned(addr))) <= data_i(23 downto 16); |
else |
mem_b2_rd <= mem_ram_b2(to_integer(unsigned(addr))); |
end if; |
if (wren_i = '1') and (ben_i(3) = '1') then -- byte 3 |
mem_ram_b3(to_integer(unsigned(addr))) <= data_i(31 downto 24); |
else |
mem_b3_rd <= mem_ram_b3(to_integer(unsigned(addr))); |
end if; |
end if; |
end if; |
end process mem_access; |
-- read data -- |
rdata <= mem_b3_rd & mem_b2_rd & mem_b1_rd & mem_b0_rd; |
end generate; |
|
|
-- Bus Feedback --------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
bus_feedback: process(clk_i) |
begin |
if rising_edge(clk_i) then |
rden <= acc_en and rden_i; |
if (IMEM_AS_ROM = true) then |
if (IMEM_AS_IROM = true) then |
ack_o <= acc_en and rden_i; |
else |
ack_o <= acc_en and (rden_i or wren_i); |
end if; |
if (acc_en = '1') then -- reduce switching activity when not accessed |
if (IMEM_AS_ROM = true) then -- implement IMEM as true ROM (initialized of course) |
rdata(07 downto 00) <= imem_file_rom_ll(to_integer(unsigned(addr))); |
rdata(15 downto 08) <= imem_file_rom_lh(to_integer(unsigned(addr))); |
rdata(23 downto 16) <= imem_file_rom_hl(to_integer(unsigned(addr))); |
rdata(31 downto 24) <= imem_file_rom_hh(to_integer(unsigned(addr))); |
|
elsif (BOOTLOADER_EN = true) then -- implement IMEM as non-initialized RAM |
if (wren_i = '1') then |
if (ben_i(0) = '1') then |
imem_file_ram_ll(to_integer(unsigned(addr))) <= data_i(07 downto 00); |
end if; |
if (ben_i(1) = '1') then |
imem_file_ram_lh(to_integer(unsigned(addr))) <= data_i(15 downto 08); |
end if; |
if (ben_i(2) = '1') then |
imem_file_ram_hl(to_integer(unsigned(addr))) <= data_i(23 downto 16); |
end if; |
if (ben_i(3) = '1') then |
imem_file_ram_hh(to_integer(unsigned(addr))) <= data_i(31 downto 24); |
end if; |
end if; |
rdata(07 downto 00) <= imem_file_ram_ll(to_integer(unsigned(addr))); |
rdata(15 downto 08) <= imem_file_ram_lh(to_integer(unsigned(addr))); |
rdata(23 downto 16) <= imem_file_ram_hl(to_integer(unsigned(addr))); |
rdata(31 downto 24) <= imem_file_ram_hh(to_integer(unsigned(addr))); |
|
else -- implement IMEM as PRE-INITIALIZED RAM |
if (wren_i = '1') then |
if (ben_i(0) = '1') then |
imem_file_init_ram_ll(to_integer(unsigned(addr))) <= data_i(07 downto 00); |
end if; |
if (ben_i(1) = '1') then |
imem_file_init_ram_lh(to_integer(unsigned(addr))) <= data_i(15 downto 08); |
end if; |
if (ben_i(2) = '1') then |
imem_file_init_ram_hl(to_integer(unsigned(addr))) <= data_i(23 downto 16); |
end if; |
if (ben_i(3) = '1') then |
imem_file_init_ram_hh(to_integer(unsigned(addr))) <= data_i(31 downto 24); |
end if; |
end if; |
rdata(07 downto 00) <= imem_file_init_ram_ll(to_integer(unsigned(addr))); |
rdata(15 downto 08) <= imem_file_init_ram_lh(to_integer(unsigned(addr))); |
rdata(23 downto 16) <= imem_file_init_ram_hl(to_integer(unsigned(addr))); |
rdata(31 downto 24) <= imem_file_init_ram_hh(to_integer(unsigned(addr))); |
end if; |
end if; |
end if; |
end process imem_file_access; |
end process bus_feedback; |
|
-- output gate -- |
data_o <= rdata when (rden = '1') else (others => '0'); |
/core/neorv32_mtime.vhd
71,19 → 71,18
signal wren : std_ulogic; -- module access enable |
|
-- time write access buffer -- |
signal wdata_buf : std_ulogic_vector(31 downto 0); |
signal mtime_lo_we : std_ulogic; |
signal mtime_hi_we : std_ulogic; |
|
-- accessible regs -- |
signal mtimecmp_lo : std_ulogic_vector(31 downto 0); |
signal mtimecmp_hi : std_ulogic_vector(31 downto 0); |
signal mtime_lo : std_ulogic_vector(32 downto 0); |
signal mtime_lo_msb_ff : std_ulogic; |
signal mtime_hi : std_ulogic_vector(31 downto 0); |
signal inc_hi : std_ulogic_vector(31 downto 0); |
signal mtimecmp_lo : std_ulogic_vector(31 downto 0); |
signal mtimecmp_hi : std_ulogic_vector(31 downto 0); |
signal mtime_lo : std_ulogic_vector(31 downto 0); |
signal mtime_lo_nxt : std_ulogic_vector(32 downto 0); |
signal mtime_lo_ovfl : std_ulogic_vector(00 downto 0); |
signal mtime_hi : std_ulogic_vector(31 downto 0); |
|
-- irq control -- |
-- comparator and IRQ trigger -- |
signal cmp_lo : std_ulogic; |
signal cmp_lo_ff : std_ulogic; |
signal cmp_hi : std_ulogic; |
114,31 → 113,29
end if; |
|
-- mtime access buffer -- |
wdata_buf <= data_i; |
-- wdata_buf <= data_i; -- not required, CPU wdata is stable until transfer is acknowledged |
mtime_lo_we <= wren and bool_to_ulogic_f(boolean(addr = mtime_time_lo_addr_c)); |
mtime_hi_we <= wren and bool_to_ulogic_f(boolean(addr = mtime_time_hi_addr_c)); |
|
-- mtime low -- |
if (mtime_lo_we = '1') then -- write access |
mtime_lo_msb_ff <= '0'; |
mtime_lo <= '0' & wdata_buf; |
mtime_lo <= data_i; |
else -- auto increment |
mtime_lo_msb_ff <= mtime_lo(mtime_lo'left); |
mtime_lo <= std_ulogic_vector(unsigned(mtime_lo) + 1); |
mtime_lo <= mtime_lo_nxt(31 downto 0); |
end if; |
mtime_lo_ovfl(0) <= mtime_lo_nxt(32); -- overflow (carry) |
|
-- mtime high -- |
if (mtime_hi_we = '1') then -- write access |
mtime_hi <= wdata_buf; |
mtime_hi <= data_i; |
else -- auto increment (if mtime.low overflows) |
mtime_hi <= std_ulogic_vector(unsigned(mtime_hi) + unsigned(inc_hi)); |
mtime_hi <= std_ulogic_vector(unsigned(mtime_hi) + unsigned(mtime_lo_ovfl)); |
end if; |
end if; |
end process wr_access; |
|
-- mtime.time_HI increment (0 or 1) -- |
inc_hi(0) <= mtime_lo_msb_ff xor mtime_lo(mtime_lo'left); |
inc_hi(31 downto 1) <= (others => '0'); |
-- mtime.time_LO increment -- |
mtime_lo_nxt <= std_ulogic_vector(unsigned('0' & mtime_lo) + 1); |
|
|
-- Read Access ---------------------------------------------------------------------------- |
151,7 → 148,7
if (rden_i = '1') and (acc_en = '1') then |
case addr is |
when mtime_time_lo_addr_c => -- mtime LOW |
data_o <= mtime_lo(31 downto 00); |
data_o <= mtime_lo; |
when mtime_time_hi_addr_c => -- mtime HIGH |
data_o <= mtime_hi; |
when mtime_cmp_lo_addr_c => -- mtimecmp LOW |
164,7 → 161,7
end process rd_access; |
|
-- system time output for cpu -- |
time_o <= mtime_hi & mtime_lo(31 downto 00); |
time_o <= mtime_hi & mtime_lo; |
|
|
-- Comparator ----------------------------------------------------------------------------- |
179,8 → 176,8
end process cmp_sync; |
|
-- test words -- |
cmp_lo <= '1' when (unsigned(mtime_lo(31 downto 00)) >= unsigned(mtimecmp_lo)) else '0'; |
cmp_hi <= '1' when (unsigned(mtime_hi(31 downto 00)) >= unsigned(mtimecmp_hi)) else '0'; |
cmp_lo <= '1' when (unsigned(mtime_lo) >= unsigned(mtimecmp_lo)) else '0'; |
cmp_hi <= '1' when (unsigned(mtime_hi) >= unsigned(mtimecmp_hi)) else '0'; |
|
|
end neorv32_mtime_rtl; |
/core/neorv32_neoled.vhd
144,22 → 144,20
type tx_buffer_t is record |
we : std_ulogic; -- write enable |
re : std_ulogic; -- read enable |
wdata : std_ulogic_vector(31 downto 0); -- write data (excluding excluding) |
wdata : std_ulogic_vector(31 downto 0); -- write data (excluding mode) |
rdata : std_ulogic_vector(31+1 downto 0); -- read data (including mode) |
-- |
w_pnt : std_ulogic_vector(index_size_f(tx_buffer_entries_c) downto 0); -- write pointer |
r_pnt : std_ulogic_vector(index_size_f(tx_buffer_entries_c) downto 0); -- read pointer |
match : std_ulogic; |
empty : std_ulogic; |
empty_ff : std_ulogic; |
full : std_ulogic; |
avail : std_ulogic; -- data available? |
free : std_ulogic; -- free entry available? |
free_ff : std_ulogic; |
empty : std_ulogic; |
empty_ff : std_ulogic; |
-- |
data : tx_fifo_t; -- fifo memory |
end record; |
signal tx_buffer : tx_buffer_t; |
signal fifo_clear : std_ulogic; |
signal fifo_wdata : std_ulogic_vector(31+1 downto 0); |
|
-- serial transmission engine -- |
type serial_state_t is (S_IDLE, S_INIT, S_GETBIT, S_PULSE); |
246,37 → 244,32
|
-- TX Buffer (FIFO) ----------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
instr_prefetch_buffer: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- write port -- |
if (ctrl.enable = '0') then |
tx_buffer.w_pnt <= (others => '0'); |
elsif (tx_buffer.we = '1') then |
tx_buffer.w_pnt <= std_ulogic_vector(unsigned(tx_buffer.w_pnt) + 1); |
end if; |
if (tx_buffer.we = '1') then -- write data |
tx_buffer.data(to_integer(unsigned(tx_buffer.w_pnt(tx_buffer.w_pnt'left-1 downto 0)))) <= ctrl.mode & tx_buffer.wdata; |
end if; |
-- read port -- |
if (ctrl.enable = '0') then |
tx_buffer.r_pnt <= (others => '0'); |
elsif (tx_buffer.re = '1') then |
tx_buffer.r_pnt <= std_ulogic_vector(unsigned(tx_buffer.r_pnt) + 1); |
end if; |
tx_buffer.rdata <= tx_buffer.data(to_integer(unsigned(tx_buffer.r_pnt(tx_buffer.r_pnt'left-1 downto 0)))); -- sync read |
-- status buffer -- |
tx_buffer.empty_ff <= tx_buffer.empty; |
tx_buffer.free_ff <= tx_buffer.free; |
end if; |
end process instr_prefetch_buffer; |
tx_data_fifo: neorv32_fifo |
generic map ( |
FIFO_DEPTH => tx_buffer_entries_c, -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH => 32+1, -- size of data elements in fifo |
FIFO_RSYNC => true, -- sync read |
FIFO_SAFE => false -- no safe access required (ensured by FIFO-external control) |
) |
port map ( |
-- control -- |
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => fifo_clear, -- sync reset, high-active |
-- write port -- |
wdata_i => fifo_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 |
); |
|
-- status -- |
tx_buffer.match <= '1' when (tx_buffer.r_pnt(tx_buffer.r_pnt'left-1 downto 0) = tx_buffer.w_pnt(tx_buffer.w_pnt'left-1 downto 0)) else '0'; |
tx_buffer.full <= '1' when (tx_buffer.r_pnt(tx_buffer.r_pnt'left) /= tx_buffer.w_pnt(tx_buffer.w_pnt'left)) and (tx_buffer.match = '1') else '0'; |
tx_buffer.empty <= '1' when (tx_buffer.r_pnt(tx_buffer.r_pnt'left) = tx_buffer.w_pnt(tx_buffer.w_pnt'left)) and (tx_buffer.match = '1') else '0'; |
tx_buffer.free <= not tx_buffer.full; |
tx_buffer.avail <= not tx_buffer.empty; |
-- helper signals -- |
fifo_clear <= not ctrl.enable; |
fifo_wdata <= ctrl.mode & tx_buffer.wdata; |
tx_buffer.empty <= not tx_buffer.avail; |
|
|
-- Buffer Status Flag and IRQ Generator --------------------------------------------------- |
/core/neorv32_package.vhd
45,8 → 45,9
constant dspace_base_c : std_ulogic_vector(31 downto 0) := x"80000000"; -- default data memory address space base address |
|
-- external bus interface -- |
constant wb_pipe_mode_c : boolean := false; -- external bus protocol: false=classic/standard wishbone mode (default), true=pipelined wishbone mode |
constant xbus_big_endian_c : boolean := false; -- external memory access byte order: true=big-endian, false=little-endian (default) |
constant wb_pipe_mode_c : boolean := false; -- protocol: false=classic/standard wishbone mode (default), true=pipelined wishbone mode |
constant wb_big_endian_c : boolean := false; -- byte order: true=big-endian, false=little-endian (default) |
constant wb_rx_buffer_c : boolean := true; -- use register buffer for RX data when true (default) |
|
-- CPU core -- |
constant ipb_entries_c : natural := 4; -- entries in CPU instruction prefetch buffer, has to be a power of 2, default=2 |
66,6 → 67,29
constant jtag_tap_idcode_partid_c : std_ulogic_vector(15 downto 0) := x"cafe"; -- part number |
constant jtag_tap_idcode_manid_c : std_ulogic_vector(10 downto 0) := "00000000000"; -- manufacturer id |
|
-- 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"01050710"; -- no touchy! |
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off! |
constant rf_r0_is_reg_c : boolean := true; -- x0 is a *physical register* that has to be initialized to zero by the CPU |
|
-- External Interface Types --------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
type sdata_8x32_t is array (0 to 7) of std_ulogic_vector(31 downto 0); |
type sdata_8x32r_t is array (0 to 7) of std_logic_vector(31 downto 0); -- resolved type |
|
-- Internal Interface Types --------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
type pmp_ctrl_if_t is array (0 to 63) of std_ulogic_vector(07 downto 0); |
type pmp_addr_if_t is array (0 to 63) of std_ulogic_vector(33 downto 0); |
type cp_data_if_t is array (0 to 3) of std_ulogic_vector(data_width_c-1 downto 0); |
|
-- Internal Memory Types Configuration Types ---------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
type mem32_t is array (natural range <>) of std_ulogic_vector(31 downto 0); -- memory with 32-bit entries |
type mem8_t is array (natural range <>) of std_ulogic_vector(07 downto 0); -- memory with 8-bit entries |
|
-- Helper Functions ----------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
function index_size_f(input : natural) return natural; |
83,21 → 107,14
function bit_rev_f(input : std_ulogic_vector) return std_ulogic_vector; |
function is_power_of_two_f(input : natural) return boolean; |
function bswap32_f(input : std_ulogic_vector) return std_ulogic_vector; |
function char_tolower_f(ch : character) return character; |
function str_equal_f(str0 : string; str1 : string) return boolean; |
impure function mem32_init_f(init : mem32_t; depth : natural) return mem32_t; |
|
-- Architecture Constants (do not modify!) ------------------------------------------------ |
-- Internal (auto-generated) Configurations ----------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
constant data_width_c : natural := 32; -- native data path width - do not change! |
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01050605"; -- no touchy! |
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off! |
constant rf_r0_is_reg_c : boolean := true; -- x0 is a *physical register* that has to be initialized to zero by the CPU |
constant def_rst_val_c : std_ulogic := cond_sel_stdulogic_f(dedicated_reset_c, '0', '-'); |
constant def_rst_val_c : std_ulogic := cond_sel_stdulogic_f(dedicated_reset_c, '0', '-'); |
|
-- Internal Types ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
type pmp_ctrl_if_t is array (0 to 63) of std_ulogic_vector(07 downto 0); |
type pmp_addr_if_t is array (0 to 63) of std_ulogic_vector(33 downto 0); |
type cp_data_if_t is array (0 to 7) of std_ulogic_vector(data_width_c-1 downto 0); |
|
-- Processor-Internal Address Space Layout ------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
-- Internal Instruction Memory (IMEM) and Date Memory (DMEM) -- |
106,13 → 123,13
--> internal data/instruction memory sizes are configured via top's generics |
|
-- Internal Bootloader ROM -- |
-- Actual bootloader size is determined during runtime via the length of the bootloader initialization image |
constant boot_rom_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffff0000"; -- bootloader base address, fixed! |
constant boot_rom_size_c : natural := 4*1024; -- module's address space in bytes |
constant boot_rom_max_size_c : natural := 32*1024; -- max module's address space in bytes, fixed! |
constant boot_rom_max_size_c : natural := 32*1024; -- max module's address space size in bytes, fixed! |
|
-- On-Chip Debugger: Debug Module -- |
constant dm_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffff800"; -- base address, fixed! |
constant dm_size_c : natural := 4*32*4; -- debug ROM address space in bytes, fixed |
constant dm_size_c : natural := 4*32*4; -- debug ROM address space size in bytes, fixed |
constant dm_code_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffff800"; |
constant dm_pbuf_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffff880"; |
constant dm_data_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffff900"; |
121,11 → 138,11
-- IO: Peripheral Devices ("IO") Area -- |
-- Control register(s) (including the device-enable) should be located at the base address of each device |
constant io_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe00"; |
constant io_size_c : natural := 512; -- module's address space in bytes, fixed! |
constant io_size_c : natural := 512; -- IO address space size in bytes, fixed! |
|
-- Custom Functions Subsystem (CFS) -- |
constant cfs_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe00"; -- base address |
constant cfs_size_c : natural := 64*4; -- module's address space in bytes |
constant cfs_size_c : natural := 32*4; -- module's address space in bytes |
constant cfs_reg0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe00"; |
constant cfs_reg1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe04"; |
constant cfs_reg2_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe08"; |
161,7 → 178,7
|
-- Pulse-Width Modulation Controller (PWM) -- |
constant pwm_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe80"; -- base address |
constant pwm_size_c : natural := 16*4; -- module's address space in bytes |
constant pwm_size_c : natural := 16*4; -- module's address space size in bytes |
constant pwm_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe80"; |
constant pwm_duty0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe84"; |
constant pwm_duty1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffe88"; |
179,33 → 196,25
constant pwm_duty13_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffeb8"; |
constant pwm_duty14_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffebc"; |
|
-- reserved -- |
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0"; -- base address |
--constant reserved_size_c : natural := 16*4; -- module's address space in bytes |
-- Stream link interface (SLINK) -- |
constant slink_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"fffffec0"; -- base address |
constant slink_size_c : natural := 16*4; -- module's address space size in bytes |
|
-- reserved -- |
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff00"; -- base address |
--constant reserved_size_c : natural := 32*4; -- module's address space in bytes |
--constant reserved_size_c : natural := 32*4; -- module's address space size in bytes |
|
-- General Purpose Input/Output Unit (GPIO) -- |
constant gpio_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80"; -- base address |
constant gpio_size_c : natural := 2*4; -- module's address space in bytes |
constant gpio_in_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80"; |
constant gpio_out_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff84"; |
-- External Interrupt Controller (XIRQ) -- |
constant xirq_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80"; -- base address |
constant xirq_size_c : natural := 4*4; -- module's address space size in bytes |
constant xirq_enable_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff80"; |
constant xirq_pending_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff84"; |
constant xirq_source_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff88"; |
--constant xirq_res_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff8c"; |
|
-- True Random Number Generator (TRNG) -- |
constant trng_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff88"; -- base address |
constant trng_size_c : natural := 1*4; -- module's address space in bytes |
constant trng_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff88"; |
|
-- Watch Dog Timer (WDT) -- |
constant wdt_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff8c"; -- base address |
constant wdt_size_c : natural := 1*4; -- module's address space in bytes |
constant wdt_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff8c"; |
|
-- Machine System Timer (MTIME) -- |
constant mtime_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff90"; -- base address |
constant mtime_size_c : natural := 4*4; -- module's address space in bytes |
constant mtime_size_c : natural := 4*4; -- module's address space size in bytes |
constant mtime_time_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff90"; |
constant mtime_time_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff94"; |
constant mtime_cmp_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffff98"; |
213,49 → 222,55
|
-- Primary Universal Asynchronous Receiver/Transmitter (UART0) -- |
constant uart0_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa0"; -- base address |
constant uart0_size_c : natural := 2*4; -- module's address space in bytes |
constant uart0_size_c : natural := 2*4; -- module's address space size in bytes |
constant uart0_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa0"; |
constant uart0_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa4"; |
|
-- Serial Peripheral Interface (SPI) -- |
constant spi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa8"; -- base address |
constant spi_size_c : natural := 2*4; -- module's address space in bytes |
constant spi_size_c : natural := 2*4; -- module's address space size in bytes |
constant spi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffa8"; |
constant spi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffac"; |
|
-- Two Wire Interface (TWI) -- |
constant twi_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb0"; -- base address |
constant twi_size_c : natural := 2*4; -- module's address space in bytes |
constant twi_size_c : natural := 2*4; -- module's address space size in bytes |
constant twi_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb0"; |
constant twi_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb4"; |
|
-- True Random Number Generator (TRNG) -- |
constant trng_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb8"; -- base address |
constant trng_size_c : natural := 1*4; -- module's address space size in bytes |
constant trng_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb8"; |
|
-- Watch Dog Timer (WDT) -- |
constant wdt_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffbc"; -- base address |
constant wdt_size_c : natural := 1*4; -- module's address space size in bytes |
constant wdt_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffbc"; |
|
-- reserved -- |
--constant reserved_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffb8"; -- base address |
--constant reserved_size_c : natural := 2*4; -- module's address space in bytes |
constant gpio_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0"; -- base address |
constant gpio_size_c : natural := 4*4; -- module's address space size in bytes |
constant gpio_in_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0"; |
constant gpio_in_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc4"; |
constant gpio_out_lo_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc8"; |
constant gpio_out_hi_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffcc"; |
|
-- Numerically-Controlled Oscillator (NCO) -- |
constant nco_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0"; -- base address |
constant nco_size_c : natural := 4*4; -- module's address space in bytes |
constant nco_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc0"; |
constant nco_ch0_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc4"; |
constant nco_ch1_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffc8"; |
constant nco_ch2_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffcc"; |
|
-- Secondary Universal Asynchronous Receiver/Transmitter (UART1) -- |
constant uart1_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd0"; -- base address |
constant uart1_size_c : natural := 2*4; -- module's address space in bytes |
constant uart1_size_c : natural := 2*4; -- module's address space size in bytes |
constant uart1_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd0"; |
constant uart1_rtx_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd4"; |
|
-- Smart LED (WS2811/WS2812) Interface (NEOLED) -- |
constant neoled_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd8"; -- base address |
constant neoled_size_c : natural := 2*4; -- module's address space in bytes |
constant neoled_size_c : natural := 2*4; -- module's address space size in bytes |
constant neoled_ctrl_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffd8"; |
constant neoled_data_addr_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffdc"; |
|
-- System Information Memory (SYSINFO) -- |
constant sysinfo_base_c : std_ulogic_vector(data_width_c-1 downto 0) := x"ffffffe0"; -- base address |
constant sysinfo_size_c : natural := 8*4; -- module's address space in bytes |
constant sysinfo_size_c : natural := 8*4; -- module's address space size in bytes |
|
-- Main CPU Control Bus ------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
290,57 → 305,59
constant ctrl_alu_unsigned_c : natural := 26; -- is unsigned ALU operation |
constant ctrl_alu_shift_dir_c : natural := 27; -- shift direction (0=left, 1=right) |
constant ctrl_alu_shift_ar_c : natural := 28; -- is arithmetic shift |
constant ctrl_alu_frm0_c : natural := 29; -- FPU rounding mode bit 0 |
constant ctrl_alu_frm1_c : natural := 30; -- FPU rounding mode bit 1 |
constant ctrl_alu_frm2_c : natural := 31; -- FPU rounding mode bit 2 |
-- bus interface -- |
constant ctrl_bus_size_lsb_c : natural := 29; -- transfer size lsb (00=byte, 01=half-word) |
constant ctrl_bus_size_msb_c : natural := 30; -- transfer size msb (10=word, 11=?) |
constant ctrl_bus_rd_c : natural := 31; -- read data request |
constant ctrl_bus_wr_c : natural := 32; -- write data request |
constant ctrl_bus_if_c : natural := 33; -- instruction fetch request |
constant ctrl_bus_mo_we_c : natural := 34; -- memory address and data output register write enable |
constant ctrl_bus_mi_we_c : natural := 35; -- memory data input register write enable |
constant ctrl_bus_unsigned_c : natural := 36; -- is unsigned load |
constant ctrl_bus_ierr_ack_c : natural := 37; -- acknowledge instruction fetch bus exceptions |
constant ctrl_bus_derr_ack_c : natural := 38; -- acknowledge data access bus exceptions |
constant ctrl_bus_fence_c : natural := 39; -- executed fence operation |
constant ctrl_bus_fencei_c : natural := 40; -- executed fencei operation |
constant ctrl_bus_lock_c : natural := 41; -- make atomic/exclusive access lock |
constant ctrl_bus_de_lock_c : natural := 42; -- remove atomic/exclusive access |
constant ctrl_bus_ch_lock_c : natural := 43; -- evaluate atomic/exclusive lock (SC operation) |
constant ctrl_bus_size_lsb_c : natural := 32; -- transfer size lsb (00=byte, 01=half-word) |
constant ctrl_bus_size_msb_c : natural := 33; -- transfer size msb (10=word, 11=?) |
constant ctrl_bus_rd_c : natural := 34; -- read data request |
constant ctrl_bus_wr_c : natural := 35; -- write data request |
constant ctrl_bus_if_c : natural := 36; -- instruction fetch request |
constant ctrl_bus_mo_we_c : natural := 37; -- memory address and data output register write enable |
constant ctrl_bus_mi_we_c : natural := 38; -- memory data input register write enable |
constant ctrl_bus_unsigned_c : natural := 39; -- is unsigned load |
constant ctrl_bus_ierr_ack_c : natural := 40; -- acknowledge instruction fetch bus exceptions |
constant ctrl_bus_derr_ack_c : natural := 41; -- acknowledge data access bus exceptions |
constant ctrl_bus_fence_c : natural := 42; -- executed fence operation |
constant ctrl_bus_fencei_c : natural := 43; -- executed fencei operation |
constant ctrl_bus_lock_c : natural := 44; -- make atomic/exclusive access lock |
constant ctrl_bus_de_lock_c : natural := 45; -- remove atomic/exclusive access |
constant ctrl_bus_ch_lock_c : natural := 46; -- evaluate atomic/exclusive lock (SC operation) |
-- co-processors -- |
constant ctrl_cp_id_lsb_c : natural := 44; -- cp select ID lsb |
constant ctrl_cp_id_hsb_c : natural := 45; -- cp select ID |
constant ctrl_cp_id_msb_c : natural := 46; -- cp select ID msb |
constant ctrl_cp_id_lsb_c : natural := 47; -- cp select ID lsb |
constant ctrl_cp_id_msb_c : natural := 48; -- cp select ID msb |
-- instruction's control blocks (used by cpu co-processors) -- |
constant ctrl_ir_funct3_0_c : natural := 47; -- funct3 bit 0 |
constant ctrl_ir_funct3_1_c : natural := 48; -- funct3 bit 1 |
constant ctrl_ir_funct3_2_c : natural := 49; -- funct3 bit 2 |
constant ctrl_ir_funct12_0_c : natural := 50; -- funct12 bit 0 |
constant ctrl_ir_funct12_1_c : natural := 51; -- funct12 bit 1 |
constant ctrl_ir_funct12_2_c : natural := 52; -- funct12 bit 2 |
constant ctrl_ir_funct12_3_c : natural := 53; -- funct12 bit 3 |
constant ctrl_ir_funct12_4_c : natural := 54; -- funct12 bit 4 |
constant ctrl_ir_funct12_5_c : natural := 55; -- funct12 bit 5 |
constant ctrl_ir_funct12_6_c : natural := 56; -- funct12 bit 6 |
constant ctrl_ir_funct12_7_c : natural := 57; -- funct12 bit 7 |
constant ctrl_ir_funct12_8_c : natural := 58; -- funct12 bit 8 |
constant ctrl_ir_funct12_9_c : natural := 59; -- funct12 bit 9 |
constant ctrl_ir_funct12_10_c : natural := 60; -- funct12 bit 10 |
constant ctrl_ir_funct12_11_c : natural := 61; -- funct12 bit 11 |
constant ctrl_ir_opcode7_0_c : natural := 62; -- opcode7 bit 0 |
constant ctrl_ir_opcode7_1_c : natural := 63; -- opcode7 bit 1 |
constant ctrl_ir_opcode7_2_c : natural := 64; -- opcode7 bit 2 |
constant ctrl_ir_opcode7_3_c : natural := 65; -- opcode7 bit 3 |
constant ctrl_ir_opcode7_4_c : natural := 66; -- opcode7 bit 4 |
constant ctrl_ir_opcode7_5_c : natural := 67; -- opcode7 bit 5 |
constant ctrl_ir_opcode7_6_c : natural := 68; -- opcode7 bit 6 |
constant ctrl_ir_funct3_0_c : natural := 49; -- funct3 bit 0 |
constant ctrl_ir_funct3_1_c : natural := 50; -- funct3 bit 1 |
constant ctrl_ir_funct3_2_c : natural := 51; -- funct3 bit 2 |
constant ctrl_ir_funct12_0_c : natural := 52; -- funct12 bit 0 |
constant ctrl_ir_funct12_1_c : natural := 53; -- funct12 bit 1 |
constant ctrl_ir_funct12_2_c : natural := 54; -- funct12 bit 2 |
constant ctrl_ir_funct12_3_c : natural := 55; -- funct12 bit 3 |
constant ctrl_ir_funct12_4_c : natural := 56; -- funct12 bit 4 |
constant ctrl_ir_funct12_5_c : natural := 57; -- funct12 bit 5 |
constant ctrl_ir_funct12_6_c : natural := 58; -- funct12 bit 6 |
constant ctrl_ir_funct12_7_c : natural := 59; -- funct12 bit 7 |
constant ctrl_ir_funct12_8_c : natural := 60; -- funct12 bit 8 |
constant ctrl_ir_funct12_9_c : natural := 61; -- funct12 bit 9 |
constant ctrl_ir_funct12_10_c : natural := 62; -- funct12 bit 10 |
constant ctrl_ir_funct12_11_c : natural := 63; -- funct12 bit 11 |
constant ctrl_ir_opcode7_0_c : natural := 64; -- opcode7 bit 0 |
constant ctrl_ir_opcode7_1_c : natural := 65; -- opcode7 bit 1 |
constant ctrl_ir_opcode7_2_c : natural := 66; -- opcode7 bit 2 |
constant ctrl_ir_opcode7_3_c : natural := 67; -- opcode7 bit 3 |
constant ctrl_ir_opcode7_4_c : natural := 68; -- opcode7 bit 4 |
constant ctrl_ir_opcode7_5_c : natural := 69; -- opcode7 bit 5 |
constant ctrl_ir_opcode7_6_c : natural := 70; -- opcode7 bit 6 |
-- CPU status -- |
constant ctrl_priv_lvl_lsb_c : natural := 69; -- privilege level lsb |
constant ctrl_priv_lvl_msb_c : natural := 70; -- privilege level msb |
constant ctrl_sleep_c : natural := 71; -- set when CPU is in sleep mode |
constant ctrl_trap_c : natural := 72; -- set when CPU is entering trap execution |
constant ctrl_debug_running_c : natural := 73; -- CPU is in debug mode when set |
constant ctrl_priv_lvl_lsb_c : natural := 71; -- privilege level lsb |
constant ctrl_priv_lvl_msb_c : natural := 72; -- privilege level msb |
constant ctrl_sleep_c : natural := 73; -- set when CPU is in sleep mode |
constant ctrl_trap_c : natural := 74; -- set when CPU is entering trap execution |
constant ctrl_debug_running_c : natural := 75; -- CPU is in debug mode when set |
-- control bus size -- |
constant ctrl_width_c : natural := 74; -- control bus size |
constant ctrl_width_c : natural := 76; -- control bus size |
|
-- Comparator Bus ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
698,69 → 715,9
constant csr_time_c : std_ulogic_vector(11 downto 0) := x"c01"; |
constant csr_instret_c : std_ulogic_vector(11 downto 0) := x"c02"; |
-- |
constant csr_hpmcounter3_c : std_ulogic_vector(11 downto 0) := x"c03"; |
constant csr_hpmcounter4_c : std_ulogic_vector(11 downto 0) := x"c04"; |
constant csr_hpmcounter5_c : std_ulogic_vector(11 downto 0) := x"c05"; |
constant csr_hpmcounter6_c : std_ulogic_vector(11 downto 0) := x"c06"; |
constant csr_hpmcounter7_c : std_ulogic_vector(11 downto 0) := x"c07"; |
constant csr_hpmcounter8_c : std_ulogic_vector(11 downto 0) := x"c08"; |
constant csr_hpmcounter9_c : std_ulogic_vector(11 downto 0) := x"c09"; |
constant csr_hpmcounter10_c : std_ulogic_vector(11 downto 0) := x"c0a"; |
constant csr_hpmcounter11_c : std_ulogic_vector(11 downto 0) := x"c0b"; |
constant csr_hpmcounter12_c : std_ulogic_vector(11 downto 0) := x"c0c"; |
constant csr_hpmcounter13_c : std_ulogic_vector(11 downto 0) := x"c0d"; |
constant csr_hpmcounter14_c : std_ulogic_vector(11 downto 0) := x"c0e"; |
constant csr_hpmcounter15_c : std_ulogic_vector(11 downto 0) := x"c0f"; |
constant csr_hpmcounter16_c : std_ulogic_vector(11 downto 0) := x"c10"; |
constant csr_hpmcounter17_c : std_ulogic_vector(11 downto 0) := x"c11"; |
constant csr_hpmcounter18_c : std_ulogic_vector(11 downto 0) := x"c12"; |
constant csr_hpmcounter19_c : std_ulogic_vector(11 downto 0) := x"c13"; |
constant csr_hpmcounter20_c : std_ulogic_vector(11 downto 0) := x"c14"; |
constant csr_hpmcounter21_c : std_ulogic_vector(11 downto 0) := x"c15"; |
constant csr_hpmcounter22_c : std_ulogic_vector(11 downto 0) := x"c16"; |
constant csr_hpmcounter23_c : std_ulogic_vector(11 downto 0) := x"c17"; |
constant csr_hpmcounter24_c : std_ulogic_vector(11 downto 0) := x"c18"; |
constant csr_hpmcounter25_c : std_ulogic_vector(11 downto 0) := x"c19"; |
constant csr_hpmcounter26_c : std_ulogic_vector(11 downto 0) := x"c1a"; |
constant csr_hpmcounter27_c : std_ulogic_vector(11 downto 0) := x"c1b"; |
constant csr_hpmcounter28_c : std_ulogic_vector(11 downto 0) := x"c1c"; |
constant csr_hpmcounter29_c : std_ulogic_vector(11 downto 0) := x"c1d"; |
constant csr_hpmcounter30_c : std_ulogic_vector(11 downto 0) := x"c1e"; |
constant csr_hpmcounter31_c : std_ulogic_vector(11 downto 0) := x"c1f"; |
-- |
constant csr_cycleh_c : std_ulogic_vector(11 downto 0) := x"c80"; |
constant csr_timeh_c : std_ulogic_vector(11 downto 0) := x"c81"; |
constant csr_instreth_c : std_ulogic_vector(11 downto 0) := x"c82"; |
-- |
constant csr_hpmcounter3h_c : std_ulogic_vector(11 downto 0) := x"c83"; |
constant csr_hpmcounter4h_c : std_ulogic_vector(11 downto 0) := x"c84"; |
constant csr_hpmcounter5h_c : std_ulogic_vector(11 downto 0) := x"c85"; |
constant csr_hpmcounter6h_c : std_ulogic_vector(11 downto 0) := x"c86"; |
constant csr_hpmcounter7h_c : std_ulogic_vector(11 downto 0) := x"c87"; |
constant csr_hpmcounter8h_c : std_ulogic_vector(11 downto 0) := x"c88"; |
constant csr_hpmcounter9h_c : std_ulogic_vector(11 downto 0) := x"c89"; |
constant csr_hpmcounter10h_c : std_ulogic_vector(11 downto 0) := x"c8a"; |
constant csr_hpmcounter11h_c : std_ulogic_vector(11 downto 0) := x"c8b"; |
constant csr_hpmcounter12h_c : std_ulogic_vector(11 downto 0) := x"c8c"; |
constant csr_hpmcounter13h_c : std_ulogic_vector(11 downto 0) := x"c8d"; |
constant csr_hpmcounter14h_c : std_ulogic_vector(11 downto 0) := x"c8e"; |
constant csr_hpmcounter15h_c : std_ulogic_vector(11 downto 0) := x"c8f"; |
constant csr_hpmcounter16h_c : std_ulogic_vector(11 downto 0) := x"c90"; |
constant csr_hpmcounter17h_c : std_ulogic_vector(11 downto 0) := x"c91"; |
constant csr_hpmcounter18h_c : std_ulogic_vector(11 downto 0) := x"c92"; |
constant csr_hpmcounter19h_c : std_ulogic_vector(11 downto 0) := x"c93"; |
constant csr_hpmcounter20h_c : std_ulogic_vector(11 downto 0) := x"c94"; |
constant csr_hpmcounter21h_c : std_ulogic_vector(11 downto 0) := x"c95"; |
constant csr_hpmcounter22h_c : std_ulogic_vector(11 downto 0) := x"c96"; |
constant csr_hpmcounter23h_c : std_ulogic_vector(11 downto 0) := x"c97"; |
constant csr_hpmcounter24h_c : std_ulogic_vector(11 downto 0) := x"c98"; |
constant csr_hpmcounter25h_c : std_ulogic_vector(11 downto 0) := x"c99"; |
constant csr_hpmcounter26h_c : std_ulogic_vector(11 downto 0) := x"c9a"; |
constant csr_hpmcounter27h_c : std_ulogic_vector(11 downto 0) := x"c9b"; |
constant csr_hpmcounter28h_c : std_ulogic_vector(11 downto 0) := x"c9c"; |
constant csr_hpmcounter29h_c : std_ulogic_vector(11 downto 0) := x"c9d"; |
constant csr_hpmcounter30h_c : std_ulogic_vector(11 downto 0) := x"c9e"; |
constant csr_hpmcounter31h_c : std_ulogic_vector(11 downto 0) := x"c9f"; |
-- machine information registers -- |
constant csr_mvendorid_c : std_ulogic_vector(11 downto 0) := x"f11"; |
constant csr_marchid_c : std_ulogic_vector(11 downto 0) := x"f12"; |
771,14 → 728,10
|
-- Co-Processor IDs ----------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
constant cp_sel_csr_rd_c : std_ulogic_vector(2 downto 0) := "000"; -- CSR read access ('Zicsr' extension) |
constant cp_sel_muldiv_c : std_ulogic_vector(2 downto 0) := "001"; -- multiplication/division operations ('M' extension) |
--constant cp_sel_bitmanip_c : std_ulogic_vector(2 downto 0) := "010"; -- bit manipulation ('B' extension) |
constant cp_sel_fpu_c : std_ulogic_vector(2 downto 0) := "011"; -- floating-point unit ('Zfinx' extension) |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "100"; -- reserved |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "101"; -- reserved |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "110"; -- reserved |
--constant cp_sel_reserved_c : std_ulogic_vector(2 downto 0) := "111"; -- reserved |
constant cp_sel_shifter_c : std_ulogic_vector(1 downto 0) := "00"; -- shift operation |
constant cp_sel_muldiv_c : std_ulogic_vector(1 downto 0) := "01"; -- multiplication/division operations ('M' extension) |
--constant cp_sel_bitmanip_c : std_ulogic_vector(1 downto 0) := "10"; -- bit manipulation ('B' extension) |
constant cp_sel_fpu_c : std_ulogic_vector(1 downto 0) := "11"; -- floating-point unit ('Zfinx' extension) |
|
-- ALU Function Codes --------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
793,7 → 746,7
-- function select (actual alu result) -- |
constant alu_func_cmd_arith_c : std_ulogic_vector(1 downto 0) := "00"; -- r <= r.arith |
constant alu_func_cmd_logic_c : std_ulogic_vector(1 downto 0) := "01"; -- r <= r.logic |
constant alu_func_cmd_shift_c : std_ulogic_vector(1 downto 0) := "10"; -- r <= A <</>> B (multi-cycle) |
constant alu_func_cmd_csrr_c : std_ulogic_vector(1 downto 0) := "10"; -- r <= CSR read |
constant alu_func_cmd_copro_c : std_ulogic_vector(1 downto 0) := "11"; -- r <= CP result (multi-cycle) |
|
-- Trap ID Codes -------------------------------------------------------------------------- |
924,9 → 877,9
generic ( |
-- General -- |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
BOOTLOADER_EN : boolean := true; -- implement processor-internal bootloader? |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger |
-- RISC-V CPU Extensions -- |
933,15 → 886,15
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
949,21 → 902,29
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64) |
-- Internal Instruction memory -- |
-- Internal Instruction memory (IMEM) -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes |
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM |
-- Internal Data memory -- |
-- Internal Data memory (DMEM) -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes |
-- Internal Cache memory -- |
-- Internal Cache memory (iCACHE) -- |
ICACHE_EN : boolean := false; -- implement instruction cache |
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
-- External memory interface -- |
-- External memory interface (WISHBONE) -- |
MEM_EXT_EN : boolean := false; -- implement external memory bus interface? |
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled) |
-- Stream link interface (SLINK) -- |
SLINK_NUM_TX : natural := 0; -- number of TX links (0..8) |
SLINK_NUM_RX : natural := 0; -- number of TX links (0..8) |
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two |
SLINK_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two |
-- External Interrupts Controller (XIRQ) -- |
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)? |
978,73 → 939,79
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic |
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits |
IO_NCO_EN : boolean := true; -- implement numerically-controlled oscillator (NCO)? |
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
); |
port ( |
-- Global control -- |
clk_i : in std_ulogic := '0'; -- global clock, rising edge |
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async |
clk_i : in std_ulogic := '0'; -- global clock, rising edge |
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async |
-- JTAG on-chip debugger interface -- |
jtag_trst_i : in std_ulogic := '0'; -- low-active TAP reset (optional) |
jtag_tck_i : in std_ulogic := '0'; -- serial clock |
jtag_tdi_i : in std_ulogic := '0'; -- serial data input |
jtag_tdo_o : out std_ulogic; -- serial data output |
jtag_tms_i : in std_ulogic := '0'; -- mode select |
jtag_trst_i : in std_ulogic := '0'; -- low-active TAP reset (optional) |
jtag_tck_i : in std_ulogic := '0'; -- serial clock |
jtag_tdi_i : in std_ulogic := '0'; -- serial data input |
jtag_tdo_o : out std_ulogic; -- serial data output |
jtag_tms_i : in std_ulogic := '0'; -- mode select |
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_lock_o : out std_ulogic; -- exclusive access request |
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge |
wb_err_i : in std_ulogic := '0'; -- transfer error |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_lock_o : out std_ulogic; -- exclusive access request |
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge |
wb_err_i : in std_ulogic := '0'; -- transfer error |
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o : out std_ulogic; -- indicates an executed FENCE operation |
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation |
fence_o : out std_ulogic; -- indicates an executed FENCE operation |
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation |
-- TX stream interfaces (available if SLINK_NUM_TX > 0) -- |
slink_tx_dat_o : out sdata_8x32_t; -- output data |
slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output |
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- ready to send |
-- RX stream interfaces (available if SLINK_NUM_RX > 0) -- |
slink_rx_dat_i : in sdata_8x32_t := (others => (others => '0')); -- input data |
slink_rx_val_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- valid input |
slink_rx_rdy_o : out std_ulogic_vector(7 downto 0); -- ready to receive |
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o : out std_ulogic_vector(31 downto 0); -- parallel output |
gpio_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- parallel input |
gpio_o : out std_ulogic_vector(63 downto 0); -- parallel output |
gpio_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- parallel input |
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o : out std_ulogic; -- UART0 send data |
uart0_rxd_i : in std_ulogic := '0'; -- UART0 receive data |
uart0_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
uart0_txd_o : out std_ulogic; -- UART0 send data |
uart0_rxd_i : in std_ulogic := '0'; -- UART0 receive data |
uart0_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o : out std_ulogic; -- UART1 send data |
uart1_rxd_i : in std_ulogic := '0'; -- UART1 receive data |
uart1_rts_o : out std_ulogic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i : in std_ulogic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
uart1_txd_o : out std_ulogic; -- UART1 send data |
uart1_rxd_i : in std_ulogic := '0'; -- UART1 receive data |
uart1_rts_o : out std_ulogic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i : in std_ulogic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS |
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io : inout std_logic; -- twi serial data line |
twi_scl_io : inout std_logic; -- twi serial clock line |
twi_sda_io : inout std_logic; -- twi serial data line |
twi_scl_io : inout std_logic; -- twi serial clock line |
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels |
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels |
-- Custom Functions Subsystem IO -- |
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom CFS inputs conduit |
cfs_out_o : out std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom CFS outputs conduit |
-- NCO output (available if IO_NCO_EN = true) -- |
nco_o : out std_ulogic_vector(02 downto 0); -- numerically-controlled oscillator channels |
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom CFS inputs conduit |
cfs_out_o : out std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom CFS outputs conduit |
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o : out std_ulogic; -- async serial data line |
neoled_o : out std_ulogic; -- async serial data line |
-- System time -- |
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true) |
-- Interrupts -- |
nm_irq_i : in std_ulogic := '0'; -- non-maskable interrupt |
soc_firq_i : in std_ulogic_vector(5 downto 0) := (others => '0'); -- fast interrupt channels |
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt |
mext_irq_i : in std_ulogic := '0' -- machine external interrupt |
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true) |
-- External platform interrupts (available if XIRQ_NUM_CH > 0) -- |
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels |
-- CPU Interrupts -- |
nm_irq_i : in std_ulogic := '0'; -- non-maskable interrupt |
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt |
mext_irq_i : in std_ulogic := '0' -- machine external interrupt |
); |
end component; |
|
1060,16 → 1027,16
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode? |
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
1117,7 → 1084,6
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt |
-- fast interrupts (custom) -- |
firq_i : in std_ulogic_vector(15 downto 0) := (others => '0'); |
firq_ack_o : out std_ulogic_vector(15 downto 0); |
-- debug mode (halt) request -- |
db_halt_req_i : in std_ulogic := '0' |
); |
1135,11 → 1101,12
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_DEBUG : boolean := false; -- implement CPU debug mode? |
-- Extension Options -- |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
1156,7 → 1123,7
rstn_i : in std_ulogic; -- global reset, low-active, async |
ctrl_o : out std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus |
-- status input -- |
alu_wait_i : in std_ulogic; -- wait for ALU |
alu_idone_i : in std_ulogic; -- ALU iterative operation done |
bus_i_wait_i : in std_ulogic; -- wait for bus |
bus_d_wait_i : in std_ulogic; -- wait for bus |
excl_state_i : in std_ulogic; -- atomic/exclusive access lock status |
1171,7 → 1138,6
curr_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction) |
csr_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data |
-- FPU interface -- |
fpu_rm_o : out std_ulogic_vector(02 downto 0); -- rounding mode |
fpu_flags_i : in std_ulogic_vector(04 downto 0); -- exception flags |
-- debug mode (halt) request -- |
db_halt_req_i : in std_ulogic; |
1183,7 → 1149,6
mtime_irq_i : in std_ulogic; -- machine timer interrupt |
-- fast interrupts (custom) -- |
firq_i : in std_ulogic_vector(15 downto 0); |
firq_ack_o : out std_ulogic_vector(15 downto 0); |
-- system time input from MTIME -- |
time_i : in std_ulogic_vector(63 downto 0); -- current system time |
-- physical memory protection -- |
1224,9 → 1189,13
-- ------------------------------------------------------------------------------------------- |
component neorv32_cpu_alu |
generic ( |
CPU_EXTENSION_RISCV_M : boolean := true; -- implement muld/div extension? |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
TINY_SHIFT_EN : boolean := false -- use tiny (single-bit) shifter for shift operations |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations |
); |
port ( |
-- global control -- |
1238,23 → 1207,45
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
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 -- |
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 |
-- co-processor interface -- |
cp_start_o : out std_ulogic_vector(7 downto 0); -- trigger co-processor i |
cp_valid_i : in std_ulogic_vector(7 downto 0); -- co-processor i done |
cp_result_i : in cp_data_if_t; -- co-processor result |
fpu_flags_o : out std_ulogic_vector(4 downto 0); -- FPU exception flags |
-- status -- |
wait_o : out std_ulogic -- busy due to iterative processing units |
idone_o : out std_ulogic -- iterative processing units done? |
); |
end component; |
|
-- Component: CPU Co-Processor SHIFTER ---------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_cpu_cp_shifter |
generic ( |
FAST_SHIFT_EN : boolean := false -- use barrel shifter for shift operations |
); |
port ( |
-- global control -- |
clk_i : in std_ulogic; -- global clock, rising edge |
rstn_i : in std_ulogic; -- global reset, low-active, async |
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus |
start_i : in std_ulogic; -- trigger operation |
-- data input -- |
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1 |
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
imm_i : in std_ulogic_vector(data_width_c-1 downto 0); -- immediate |
-- result and status -- |
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result |
valid_o : out std_ulogic -- data output valid |
); |
end component; |
|
-- Component: CPU Co-Processor MULDIV ('M' extension) ------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_cpu_cp_muldiv |
generic ( |
FAST_MUL_EN : boolean := false -- use DSPs for faster multiplication |
FAST_MUL_EN : boolean := false; -- use DSPs for faster multiplication |
DIVISION_EN : boolean := true -- implement divider hardware |
); |
port ( |
-- global control -- |
1281,7 → 1272,6
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus |
start_i : in std_ulogic; -- trigger operation |
-- data input -- |
frm_i : in std_ulogic_vector(2 downto 0); -- rounding mode |
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status |
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1 |
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2 |
1475,10 → 1465,9
-- ------------------------------------------------------------------------------------------- |
component neorv32_imem |
generic ( |
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address |
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes |
IMEM_AS_ROM : boolean := false; -- implement IMEM as read-only memory? |
BOOTLOADER_EN : boolean := true -- implement and use bootloader? |
IMEM_BASE : std_ulogic_vector(31 downto 0) := x"00000000"; -- memory base address |
IMEM_SIZE : natural := 4*1024; -- processor-internal instruction memory size in bytes |
IMEM_AS_IROM : boolean := false -- implement IMEM as pre-initialized read-only memory? |
); |
port ( |
clk_i : in std_ulogic; -- global clock line |
1515,8 → 1504,7
-- ------------------------------------------------------------------------------------------- |
component neorv32_boot_rom |
generic ( |
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000"; -- boot ROM base address |
BOOTROM_SIZE : natural := 4*1024 -- processor-internal boot ROM memory size in bytes |
BOOTROM_BASE : std_ulogic_vector(31 downto 0) := x"FFFF0000" -- boot ROM base address |
); |
port ( |
clk_i : in std_ulogic; -- global clock line |
1559,10 → 1547,8
data_o : out std_ulogic_vector(31 downto 0); -- data out |
ack_o : out std_ulogic; -- transfer acknowledge |
-- parallel io -- |
gpio_o : out std_ulogic_vector(31 downto 0); |
gpio_i : in std_ulogic_vector(31 downto 0); |
-- interrupt -- |
irq_o : out std_ulogic |
gpio_o : out std_ulogic_vector(63 downto 0); |
gpio_i : in std_ulogic_vector(63 downto 0) |
); |
end component; |
|
1708,7 → 1694,6
-- ------------------------------------------------------------------------------------------- |
component neorv32_wishbone |
generic ( |
WB_PIPELINED_MODE : boolean := false; -- false: classic/standard wishbone mode, true: pipelined wishbone mode |
-- Internal instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes |
1774,7 → 1759,6
sleep_i : in std_ulogic; -- set if cpu is in sleep mode |
-- interrupt -- |
irq_o : out std_ulogic; -- interrupt request |
irq_ack_i : in std_ulogic; -- interrupt acknowledge |
-- custom io (conduit) -- |
cfs_in_i : in std_ulogic_vector(CFS_IN_SIZE-1 downto 0); -- custom inputs |
cfs_out_o : out std_ulogic_vector(CFS_OUT_SIZE-1 downto 0) -- custom outputs |
1781,9 → 1765,9
); |
end component; |
|
-- Component: Numerically-Controlled Oscillator (NCO) ------------------------------------- |
-- Component: Smart LED (WS2811/WS2812) Interface (NEOLED) -------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_nco |
component neorv32_neoled |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
1796,33 → 1780,69
-- clock generator -- |
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); |
-- NCO output -- |
nco_o : out std_ulogic_vector(02 downto 0) |
-- interrupt -- |
irq_o : out std_ulogic; -- interrupt request |
-- NEOLED output -- |
neoled_o : out std_ulogic -- serial async data line |
); |
end component; |
|
-- Component: Smart LED (WS2811/WS2812) Interface (NEOLED) -------------------------------- |
-- Component: Stream Link Interface (SLINK) ----------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_neoled |
component neorv32_slink |
generic ( |
SLINK_NUM_TX : natural := 8; -- number of TX links (0..8) |
SLINK_NUM_RX : natural := 8; -- number of TX links (0..8) |
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two |
SLINK_RX_FIFO : natural := 1 -- RX fifo depth, has to be a power of two |
); |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
ack_o : out std_ulogic; -- transfer acknowledge |
-- clock generator -- |
clkgen_en_o : out std_ulogic; -- enable clock generator |
clkgen_i : in std_ulogic_vector(07 downto 0); |
clk_i : in std_ulogic; -- global clock line |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
ack_o : out std_ulogic; -- transfer acknowledge |
-- interrupt -- |
irq_o : out std_ulogic; -- interrupt request |
-- NEOLED output -- |
neoled_o : out std_ulogic -- serial async data line |
irq_tx_o : out std_ulogic; -- transmission done |
irq_rx_o : out std_ulogic; -- data received |
-- TX stream interfaces -- |
slink_tx_dat_o : out sdata_8x32_t; -- output data |
slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output |
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0); -- ready to send |
-- RX stream interfaces -- |
slink_rx_dat_i : in sdata_8x32_t; -- input data |
slink_rx_val_i : in std_ulogic_vector(7 downto 0); -- valid input |
slink_rx_rdy_o : out std_ulogic_vector(7 downto 0) -- ready to receive |
); |
end component; |
|
-- Component: External Interrupt Controller (XIRQ) ---------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_xirq |
generic ( |
XIRQ_NUM_CH : natural := 32; -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1') -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
); |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
ack_o : out std_ulogic; -- transfer acknowledge |
-- external interrupt lines -- |
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
-- CPU interrupt -- |
cpu_irq_o : out std_ulogic |
); |
end component; |
|
-- Component: System Configuration Information Memory (SYSINFO) --------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_sysinfo |
1829,12 → 1849,11
generic ( |
-- General -- |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
BOOTLOADER_EN : boolean := true; -- implement processor-internal bootloader? |
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes |
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM |
-- Internal Data memory -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes |
1858,8 → 1877,9
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)? |
IO_TRNG_EN : boolean := true; -- implement true random number generator (TRNG)? |
IO_CFS_EN : boolean := true; -- implement custom functions subsystem (CFS)? |
IO_NCO_EN : boolean := true; -- implement numerically-controlled oscillator (NCO)? |
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
IO_SLINK_EN : boolean := true; -- implement stream link interface? |
IO_NEOLED_EN : boolean := true; -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
IO_XIRQ_NUM_CH : natural := 32 -- number of external interrupt (XIRQ) channels to implement |
); |
port ( |
-- host access -- |
1871,6 → 1891,31
); |
end component; |
|
-- Component: General Purpose FIFO .............................--------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_fifo |
generic ( |
FIFO_DEPTH : natural := 4; -- number of fifo entries; has to be a power of two; min 1 |
FIFO_WIDTH : natural := 32; -- size of data elements in fifo |
FIFO_RSYNC : boolean := false; -- false = async read; true = sync read |
FIFO_SAFE : boolean := false -- true = allow read/write only if data available |
); |
port ( |
-- control -- |
clk_i : in std_ulogic; -- clock, rising edge |
rstn_i : in std_ulogic; -- async reset, low-active |
clear_i : in std_ulogic; -- sync reset, high-active |
-- write port -- |
wdata_i : in std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- write data |
we_i : in std_ulogic; -- write enable |
free_o : out std_ulogic; -- at least one entry is free when set |
-- read port -- |
re_i : in std_ulogic; -- read enable |
rdata_o : out std_ulogic_vector(FIFO_WIDTH-1 downto 0); -- read data |
avail_o : out std_ulogic -- data available when set |
); |
end component; |
|
-- Component: On-Chip Debugger - Debug Module (DM) ---------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
component neorv32_debug_dm |
2148,4 → 2193,82
return output_v; |
end function bswap32_f; |
|
-- Function: Convert char to lowercase ---------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
function char_tolower_f(ch : character) return character is |
variable res: character; |
begin |
case ch is |
when 'A' => res := 'a'; |
when 'B' => res := 'b'; |
when 'C' => res := 'c'; |
when 'D' => res := 'd'; |
when 'E' => res := 'e'; |
when 'F' => res := 'f'; |
when 'G' => res := 'g'; |
when 'H' => res := 'h'; |
when 'I' => res := 'i'; |
when 'J' => res := 'j'; |
when 'K' => res := 'k'; |
when 'L' => res := 'l'; |
when 'M' => res := 'm'; |
when 'N' => res := 'n'; |
when 'O' => res := 'o'; |
when 'P' => res := 'p'; |
when 'Q' => res := 'q'; |
when 'R' => res := 'r'; |
when 'S' => res := 's'; |
when 'T' => res := 't'; |
when 'U' => res := 'u'; |
when 'V' => res := 'v'; |
when 'W' => res := 'w'; |
when 'X' => res := 'x'; |
when 'Y' => res := 'y'; |
when 'Z' => res := 'z'; |
when others => res := ch; |
end case; |
return res; |
end function char_tolower_f; |
|
-- Function: Compare strings (convert to lower case, check lengths) ----------------------- |
-- ------------------------------------------------------------------------------------------- |
function str_equal_f(str0 : string; str1 : string) return boolean is |
variable tmp0_v : string(str0'range); |
variable tmp1_v : string(str1'range); |
begin |
if (str0'length /= str1'length) then -- equal length? |
return false; |
else |
-- convert to lower case -- |
for i in str0'range loop |
tmp0_v(i) := char_tolower_f(str0(i)); |
end loop; |
for i in str1'range loop |
tmp1_v(i) := char_tolower_f(str1(i)); |
end loop; |
-- compare lowercase strings -- |
if (tmp0_v = tmp1_v) then |
return true; |
else |
return false; |
end if; |
end if; |
end function str_equal_f; |
|
-- Function: Initialize mem32_t array from another mem32_t array -------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- impure function: returns NOT the same result every time it is evaluated with the same arguments since the source file might have changed |
impure function mem32_init_f(init : mem32_t; depth : natural) return mem32_t is |
variable mem_v : mem32_t(0 to depth-1); |
begin |
mem_v := (others => (others => '0')); -- make sure remaining memory entries are set to zero |
if (init'length > depth) then |
return mem_v; |
end if; |
for idx_v in 0 to init'length-1 loop -- init only in range of source data array |
mem_v(idx_v) := init(idx_v); |
end loop; -- idx_v |
return mem_v; |
end function mem32_init_f; |
|
end neorv32_package; |
/core/neorv32_slink.vhd
0,0 → 1,318
-- ################################################################################################# |
-- # << NEORV32 - Stream Link Interface (SLINK) >> # |
-- # ********************************************************************************************* # |
-- # Up to 8 input (RX) and up to 8 output (TX) stream links are supported. Each stream direction # |
-- # provides a global interrupt to indicate that a RX link has received new data or that a TX # |
-- # has finished sending data. Each link is provides an internal FIFO for buffering. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
entity neorv32_slink is |
generic ( |
SLINK_NUM_TX : natural := 8; -- number of TX links (0..8) |
SLINK_NUM_RX : natural := 8; -- number of TX links (0..8) |
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two |
SLINK_RX_FIFO : natural := 1 -- RX fifo depth, has to be a power of two |
); |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
ack_o : out std_ulogic; -- transfer acknowledge |
-- interrupt -- |
irq_tx_o : out std_ulogic; -- transmission done |
irq_rx_o : out std_ulogic; -- data received |
-- TX stream interfaces -- |
slink_tx_dat_o : out sdata_8x32_t; -- output data |
slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output |
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0); -- ready to send |
-- RX stream interfaces -- |
slink_rx_dat_i : in sdata_8x32_t; -- input data |
slink_rx_val_i : in std_ulogic_vector(7 downto 0); -- valid input |
slink_rx_rdy_o : out std_ulogic_vector(7 downto 0) -- ready to receive |
); |
end neorv32_slink; |
|
architecture neorv32_slink_rtl of neorv32_slink is |
|
-- IO space: module base address -- |
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit |
constant lo_abb_c : natural := index_size_f(slink_size_c); -- low address boundary bit |
|
-- control reg bits -- |
constant ctrl_rx0_avail_c : natural := 0; -- r/-: set if TX link 0 is ready to send |
constant ctrl_rx1_avail_c : natural := 1; -- r/-: set if TX link 1 is ready to send |
constant ctrl_rx2_avail_c : natural := 2; -- r/-: set if TX link 2 is ready to send |
constant ctrl_rx3_avail_c : natural := 3; -- r/-: set if TX link 3 is ready to send |
constant ctrl_rx4_avail_c : natural := 4; -- r/-: set if TX link 4 is ready to send |
constant ctrl_rx5_avail_c : natural := 5; -- r/-: set if TX link 5 is ready to send |
constant ctrl_rx6_avail_c : natural := 6; -- r/-: set if TX link 6 is ready to send |
constant ctrl_rx7_avail_c : natural := 7; -- r/-: set if TX link 7 is ready to send |
-- |
constant ctrl_tx0_free_c : natural := 8; -- r/-: set if RX link 0 data available |
constant ctrl_tx1_free_c : natural := 9; -- r/-: set if RX link 1 data available |
constant ctrl_tx2_free_c : natural := 10; -- r/-: set if RX link 2 data available |
constant ctrl_tx3_free_c : natural := 11; -- r/-: set if RX link 3 data available |
constant ctrl_tx4_free_c : natural := 12; -- r/-: set if RX link 4 data available |
constant ctrl_tx5_free_c : natural := 13; -- r/-: set if RX link 5 data available |
constant ctrl_tx6_free_c : natural := 14; -- r/-: set if RX link 6 data available |
constant ctrl_tx7_free_c : natural := 15; -- r/-: set if RX link 7 data available |
-- |
constant ctrl_rx_num0_c : natural := 16; -- r/-: number of implemented RX links -1 bit 0 |
constant ctrl_rx_num1_c : natural := 17; -- r/-: number of implemented RX links -1 bit 1 |
constant ctrl_rx_num2_c : natural := 18; -- r/-: number of implemented RX links -1 bit 2 |
constant ctrl_tx_num0_c : natural := 19; -- r/-: number of implemented TX links -1 bit 0 |
constant ctrl_tx_num1_c : natural := 20; -- r/-: number of implemented TX links -1 bit 1 |
constant ctrl_tx_num2_c : natural := 21; -- r/-: number of implemented TX links -1 bit 2 |
-- |
constant ctrl_rx_size0_c : natural := 22; -- r/-: log2(RX FIFO size) bit 0 |
constant ctrl_rx_size1_c : natural := 23; -- r/-: log2(RX FIFO size) bit 1 |
constant ctrl_rx_size2_c : natural := 24; -- r/-: log2(RX FIFO size) bit 2 |
constant ctrl_rx_size3_c : natural := 25; -- r/-: log2(RX FIFO size) bit 3 |
constant ctrl_tx_size0_c : natural := 26; -- r/-: log2(TX FIFO size) bit 0 |
constant ctrl_tx_size1_c : natural := 27; -- r/-: log2(TX FIFO size) bit 1 |
constant ctrl_tx_size2_c : natural := 28; -- r/-: log2(TX FIFO size) bit 2 |
constant ctrl_tx_size3_c : natural := 29; -- r/-: log2(TX FIFO size) bit 3 |
-- |
constant ctrl_en_c : natural := 31; -- r/w: global enable |
|
-- bus access control -- |
signal ack_read : std_ulogic; |
signal ack_write : std_ulogic; |
signal acc_en : std_ulogic; |
signal addr : std_ulogic_vector(31 downto 0); |
|
-- control register -- |
signal enable : std_ulogic; -- global enable |
|
-- interrupt generator -- |
signal tx_fifo_free_buf : std_ulogic_vector(7 downto 0); |
signal rx_fifo_avail_buf : 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); |
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, tx_fifo_free : std_ulogic_vector(7 downto 0); |
signal rx_fifo_re, rx_fifo_avail : std_ulogic_vector(7 downto 0); |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert not (is_power_of_two_f(SLINK_TX_FIFO) = false) report "NEORV32 PROCESSOR CONFIG ERROR: SLINK <SLINK_TX_FIFO> has to be a power of two." severity error; |
assert not (SLINK_TX_FIFO > 2**15) report "NEORV32 PROCESSOR CONFIG ERROR: SLINK <SLINK_TX_FIFO> has to be 1..32768." severity error; |
-- |
assert not (is_power_of_two_f(SLINK_RX_FIFO) = false) report "NEORV32 PROCESSOR CONFIG ERROR: SLINK <SLINK_RX_FIFO> has to be a power of two." severity error; |
assert not (SLINK_RX_FIFO > 2**15) report "NEORV32 PROCESSOR CONFIG ERROR: SLINK <SLINK_RX_FIFO> has to be 1..32768." severity error; |
-- |
assert not (SLINK_NUM_RX > 8) report "NEORV32 PROCESSOR CONFIG ERROR: SLINK <SLINK_NUM_RX> has to be 0..8." severity error; |
assert not (SLINK_NUM_TX > 8) report "NEORV32 PROCESSOR CONFIG ERROR: SLINK <SLINK_NUM_TX> has to be 0..8." severity error; |
-- |
assert false report "NEORV32 PROCESSOR CONFIG NOTE: Implementing " & integer'image(SLINK_NUM_RX) & " RX and " & |
integer'image(SLINK_NUM_TX) & " TX stream links." severity note; |
|
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = slink_base_c(hi_abb_c downto lo_abb_c)) else '0'; |
addr <= slink_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned |
|
|
-- Read/Write Access ---------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
rw_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- write access -- |
ack_write <= '0'; |
if (acc_en = '1') and (wren_i = '1') then |
if (addr(5) = '0') then -- control register |
enable <= data_i(ctrl_en_c); |
ack_write <= '1'; |
else -- TX links |
ack_write <= or_reduce_f(link_sel and tx_fifo_free); |
end if; |
end if; |
|
-- read access -- |
data_o <= (others => '0'); |
ack_read <= '0'; |
if (acc_en = '1') and (rden_i = '1') then |
if (addr(5) = '0') then -- control register |
data_o(ctrl_rx7_avail_c downto ctrl_rx0_avail_c) <= rx_fifo_avail; |
data_o(ctrl_tx7_free_c downto ctrl_tx0_free_c) <= tx_fifo_free; |
data_o(ctrl_rx_num2_c downto ctrl_rx_num0_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_RX-1, 3)); |
data_o(ctrl_tx_num2_c downto ctrl_tx_num0_c) <= std_ulogic_vector(to_unsigned(SLINK_NUM_TX-1, 3)); |
data_o(ctrl_rx_size3_c downto ctrl_rx_size0_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_RX_FIFO), 4)); |
data_o(ctrl_tx_size3_c downto ctrl_tx_size0_c) <= std_ulogic_vector(to_unsigned(index_size_f(SLINK_TX_FIFO), 4)); |
data_o(ctrl_en_c) <= enable; |
ack_read <= '1'; |
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); |
end if; |
end if; |
end if; |
end process rw_access; |
|
-- bus access acknowledge -- |
ack_o <= ack_write or ack_read; |
|
-- link fifo reset (sync) -- |
fifo_clear <= not enable; |
|
|
-- Interrupt Generator -------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
irq_generator: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- buffer status -- |
tx_fifo_free_buf <= tx_fifo_free; |
rx_fifo_avail_buf <= rx_fifo_avail; |
-- rising edge detector -- |
irq_tx_o <= enable and or_reduce_f(tx_fifo_free and (not tx_fifo_free_buf)); |
irq_rx_o <= enable and or_reduce_f(rx_fifo_avail and (not rx_fifo_avail_buf)); |
end if; |
end process irq_generator; |
|
|
-- Link Select ---------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
link_select: process(addr) |
begin |
case addr(5 downto 2) is -- MSB = data fifo access at all? |
when "1000" => link_sel <= "00000001"; |
when "1001" => link_sel <= "00000010"; |
when "1010" => link_sel <= "00000100"; |
when "1011" => link_sel <= "00001000"; |
when "1100" => link_sel <= "00010000"; |
when "1101" => link_sel <= "00100000"; |
when "1110" => link_sel <= "01000000"; |
when "1111" => link_sel <= "10000000"; |
when others => link_sel <= "00000000"; |
end case; |
end process link_select; |
|
fifo_access_gen: |
for i in 0 to 7 generate |
tx_fifo_we(i) <= link_sel(i) and acc_en and wren_i; |
rx_fifo_re(i) <= link_sel(i) and acc_en and rden_i; |
end generate; |
|
|
-- TX Link FIFOs -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
transmit_fifo_gen: |
for i in 0 to SLINK_NUM_TX-1 generate |
transmit_fifo_inst: neorv32_fifo |
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 data available |
) |
port map ( |
-- control -- |
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => fifo_clear, -- sync reset, high-active |
-- write port -- |
wdata_i => data_i, -- write data |
we_i => tx_fifo_we(i), -- write enable |
free_o => tx_fifo_free(i), -- at least one entry is free when set |
-- read port -- |
re_i => slink_tx_rdy_i(i), -- read enable |
rdata_o => slink_tx_dat_o(i), -- read data |
avail_o => slink_tx_val_o(i) -- data available when set |
); |
end generate; |
|
-- terminate unimplemented links -- |
transmit_fifo_gen_terminate: |
for i in SLINK_NUM_TX to 7 generate |
tx_fifo_free(i) <= '0'; |
slink_tx_dat_o(i) <= (others => '0'); |
slink_tx_val_o(i) <= '0'; |
end generate; |
|
|
-- RX Link FIFOs -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
receive_fifo_gen: |
for i in 0 to SLINK_NUM_RX-1 generate |
receive_fifo_inst: neorv32_fifo |
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 data available |
) |
port map ( |
-- control -- |
clk_i => clk_i, -- clock, rising edge |
rstn_i => '1', -- async reset, low-active |
clear_i => fifo_clear, -- sync reset, high-active |
-- write port -- |
wdata_i => slink_rx_dat_i(i), -- write data |
we_i => slink_rx_val_i(i), -- write enable |
free_o => slink_rx_rdy_o(i), -- at least one entry is free when set |
-- read port -- |
re_i => rx_fifo_re(i), -- read enable |
rdata_o => rx_fifo_rdata(i), -- read data |
avail_o => rx_fifo_avail(i) -- data available when set |
); |
end generate; |
|
-- terminate unimplemented links -- |
receive_fifo_gen_terminate: |
for i in SLINK_NUM_RX to 7 generate |
rx_fifo_avail(i) <= '0'; |
slink_rx_rdy_o(i) <= '0'; |
rx_fifo_rdata(i) <= (others => '0'); |
end generate; |
|
|
end neorv32_slink_rtl; |
/core/neorv32_sysinfo.vhd
46,12 → 46,11
generic ( |
-- General -- |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
BOOTLOADER_EN : boolean := true; -- implement processor-internal bootloader? |
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes |
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM |
-- Internal Data memory -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 4*1024; -- size of processor-internal data memory in bytes |
75,8 → 74,9
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)? |
IO_TRNG_EN : boolean := true; -- implement true random number generator (TRNG)? |
IO_CFS_EN : boolean := true; -- implement custom functions subsystem (CFS)? |
IO_NCO_EN : boolean := true; -- implement numerically-controlled oscillator (NCO)? |
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
IO_SLINK_EN : boolean := true; -- implement stream link interface? |
IO_NEOLED_EN : boolean := true; -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
IO_XIRQ_NUM_CH : natural := 32 -- number of external interrupt (XIRQ) channels to implement |
); |
port ( |
-- host access -- |
125,15 → 125,14
|
-- SYSINFO(2): Implemented processor devices/features -- |
-- Memory -- |
sysinfo_mem(2)(00) <= bool_to_ulogic_f(BOOTLOADER_EN); -- processor-internal bootloader implemented? |
sysinfo_mem(2)(00) <= bool_to_ulogic_f(INT_BOOTLOADER_EN); -- processor-internal bootloader implemented? |
sysinfo_mem(2)(01) <= bool_to_ulogic_f(MEM_EXT_EN); -- external memory bus interface implemented? |
sysinfo_mem(2)(02) <= bool_to_ulogic_f(MEM_INT_IMEM_EN); -- processor-internal instruction memory implemented? |
sysinfo_mem(2)(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- processor-internal instruction memory implemented as ROM? |
sysinfo_mem(2)(04) <= bool_to_ulogic_f(MEM_INT_DMEM_EN); -- processor-internal data memory implemented? |
sysinfo_mem(2)(05) <= bool_to_ulogic_f(xbus_big_endian_c); -- is external memory bus interface using BIG-endian byte-order? |
sysinfo_mem(2)(06) <= bool_to_ulogic_f(ICACHE_EN); -- processor-internal instruction cache implemented? |
sysinfo_mem(2)(03) <= bool_to_ulogic_f(MEM_INT_DMEM_EN); -- processor-internal data memory implemented? |
sysinfo_mem(2)(04) <= bool_to_ulogic_f(wb_big_endian_c); -- is external memory bus interface using BIG-endian byte-order? |
sysinfo_mem(2)(05) <= bool_to_ulogic_f(ICACHE_EN); -- processor-internal instruction cache implemented? |
-- |
sysinfo_mem(2)(13 downto 07) <= (others => '0'); -- reserved |
sysinfo_mem(2)(13 downto 06) <= (others => '0'); -- reserved |
-- Misc -- |
sysinfo_mem(2)(14) <= bool_to_ulogic_f(ON_CHIP_DEBUGGER_EN); -- on-chip debugger implemented? |
sysinfo_mem(2)(15) <= bool_to_ulogic_f(dedicated_reset_c); -- dedicated hardware reset of all core registers? |
147,11 → 146,12
sysinfo_mem(2)(22) <= bool_to_ulogic_f(IO_WDT_EN); -- watch dog timer (WDT) implemented? |
sysinfo_mem(2)(23) <= bool_to_ulogic_f(IO_CFS_EN); -- custom functions subsystem (CFS) implemented? |
sysinfo_mem(2)(24) <= bool_to_ulogic_f(IO_TRNG_EN); -- true random number generator (TRNG) implemented? |
sysinfo_mem(2)(25) <= bool_to_ulogic_f(IO_NCO_EN); -- numerically-controlled oscillator (NCO) implemented? |
sysinfo_mem(2)(25) <= bool_to_ulogic_f(IO_SLINK_EN); -- stream links (SLINK) implemented? |
sysinfo_mem(2)(26) <= bool_to_ulogic_f(IO_UART1_EN); -- secondary universal asynchronous receiver/transmitter (UART1) implemented? |
sysinfo_mem(2)(27) <= bool_to_ulogic_f(IO_NEOLED_EN); -- NeoPixel-compatible smart LED interface (NEOLED) implemented? |
sysinfo_mem(2)(28) <= bool_to_ulogic_f(boolean(IO_XIRQ_NUM_CH > 0)); -- external interrupt controller (XIRQ) implemented? |
-- |
sysinfo_mem(2)(31 downto 28) <= (others => '0'); -- reserved |
sysinfo_mem(2)(31 downto 29) <= (others => '0'); -- reserved |
|
-- SYSINFO(3): Cache configuration -- |
sysinfo_mem(3)(03 downto 00) <= std_ulogic_vector(to_unsigned(index_size_f(ICACHE_BLOCK_SIZE), 4)) when (ICACHE_EN = true) else (others => '0'); -- i-cache: log2(block_size_in_bytes) |
/core/neorv32_top.vhd
3,7 → 3,7
-- # ********************************************************************************************* # |
-- # This is the top entity of the NEORV32 PROCESSOR. Instantiate this unit in your own project # |
-- # and define all the configuration generics according to your needs. Alternatively, you can use # |
-- # one of the alternative top entities provided in the "rtl/top_templates" folder. # |
-- # one of the alternative top entities provided in the "rtl/templates" folder. # |
-- # # |
-- # Check out the processor's documentation for more information. # |
-- # ********************************************************************************************* # |
49,9 → 49,9
generic ( |
-- General -- |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
BOOTLOADER_EN : boolean := true; -- implement processor-internal bootloader? |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
|
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger |
60,16 → 60,16
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul : boolean := false; -- implement multiply-only M sub-extension? |
|
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
TINY_SHIFT_EN : boolean := false; -- use tiny (single-bit) shifter for shift operations |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
|
-- Physical Memory Protection (PMP) -- |
80,25 → 80,35
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64) |
|
-- Internal Instruction memory -- |
-- Internal Instruction memory (IMEM) -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes |
MEM_INT_IMEM_ROM : boolean := false; -- implement processor-internal instruction memory as ROM |
|
-- Internal Data memory -- |
-- Internal Data memory (DMEM) -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes |
|
-- Internal Cache memory -- |
-- Internal Cache memory (iCACHE) -- |
ICACHE_EN : boolean := false; -- implement instruction cache |
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
|
-- External memory interface -- |
-- External memory interface (WISHBONE) -- |
MEM_EXT_EN : boolean := false; -- implement external memory bus interface? |
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled) |
|
-- Stream link interface (SLINK) -- |
SLINK_NUM_TX : natural := 0; -- number of TX links (0..8) |
SLINK_NUM_RX : natural := 0; -- number of TX links (0..8) |
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two |
SLINK_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two |
|
-- External Interrupts Controller (XIRQ) -- |
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
|
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)? |
113,99 → 123,110
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom CFS configuration generic |
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits |
IO_NCO_EN : boolean := true; -- implement numerically-controlled oscillator (NCO)? |
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
); |
port ( |
-- Global control -- |
clk_i : in std_ulogic := '0'; -- global clock, rising edge |
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async |
clk_i : in std_ulogic := '0'; -- global clock, rising edge |
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async |
|
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i : in std_ulogic := '0'; -- low-active TAP reset (optional) |
jtag_tck_i : in std_ulogic := '0'; -- serial clock |
jtag_tdi_i : in std_ulogic := '0'; -- serial data input |
jtag_tdo_o : out std_ulogic; -- serial data output |
jtag_tms_i : in std_ulogic := '0'; -- mode select |
jtag_trst_i : in std_ulogic := '0'; -- low-active TAP reset (optional) |
jtag_tck_i : in std_ulogic := '0'; -- serial clock |
jtag_tdi_i : in std_ulogic := '0'; -- serial data input |
jtag_tdo_o : out std_ulogic; -- serial data output |
jtag_tms_i : in std_ulogic := '0'; -- mode select |
|
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_lock_o : out std_ulogic; -- exclusive access request |
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge |
wb_err_i : in std_ulogic := '0'; -- transfer error |
wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag |
wb_adr_o : out std_ulogic_vector(31 downto 0); -- address |
wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- read data |
wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data |
wb_we_o : out std_ulogic; -- read/write |
wb_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_ulogic; -- strobe |
wb_cyc_o : out std_ulogic; -- valid cycle |
wb_lock_o : out std_ulogic; -- exclusive access request |
wb_ack_i : in std_ulogic := '0'; -- transfer acknowledge |
wb_err_i : in std_ulogic := '0'; -- transfer error |
|
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o : out std_ulogic; -- indicates an executed FENCE operation |
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation |
fence_o : out std_ulogic; -- indicates an executed FENCE operation |
fencei_o : out std_ulogic; -- indicates an executed FENCEI operation |
|
-- TX stream interfaces (available if SLINK_NUM_TX > 0) -- |
slink_tx_dat_o : out sdata_8x32_t; -- output data |
slink_tx_val_o : out std_ulogic_vector(7 downto 0); -- valid output |
slink_tx_rdy_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- ready to send |
|
-- RX stream interfaces (available if SLINK_NUM_RX > 0) -- |
slink_rx_dat_i : in sdata_8x32_t := (others => (others => '0')); -- input data |
slink_rx_val_i : in std_ulogic_vector(7 downto 0) := (others => '0'); -- valid input |
slink_rx_rdy_o : out std_ulogic_vector(7 downto 0); -- ready to receive |
|
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o : out std_ulogic_vector(31 downto 0); -- parallel output |
gpio_i : in std_ulogic_vector(31 downto 0) := (others => '0'); -- parallel input |
gpio_o : out std_ulogic_vector(63 downto 0); -- parallel output |
gpio_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- parallel input |
|
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o : out std_ulogic; -- UART0 send data |
uart0_rxd_i : in std_ulogic := '0'; -- UART0 receive data |
uart0_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
uart0_txd_o : out std_ulogic; -- UART0 send data |
uart0_rxd_i : in std_ulogic := '0'; -- UART0 receive data |
uart0_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
|
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o : out std_ulogic; -- UART1 send data |
uart1_rxd_i : in std_ulogic := '0'; -- UART1 receive data |
uart1_rts_o : out std_ulogic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i : in std_ulogic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
uart1_txd_o : out std_ulogic; -- UART1 send data |
uart1_rxd_i : in std_ulogic := '0'; -- UART1 receive data |
uart1_rts_o : out std_ulogic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i : in std_ulogic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
|
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- chip-select |
spi_sck_o : out std_ulogic; -- SPI serial clock |
spi_sdo_o : out std_ulogic; -- controller data out, peripheral data in |
spi_sdi_i : in std_ulogic := '0'; -- controller data in, peripheral data out |
spi_csn_o : out std_ulogic_vector(07 downto 0); -- chip-select |
|
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io : inout std_logic; -- twi serial data line |
twi_scl_io : inout std_logic; -- twi serial clock line |
twi_sda_io : inout std_logic; -- twi serial data line |
twi_scl_io : inout std_logic; -- twi serial clock line |
|
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels |
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels |
|
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) -- |
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom CFS inputs conduit |
cfs_out_o : out std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom CFS outputs conduit |
cfs_in_i : in std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom CFS inputs conduit |
cfs_out_o : out std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom CFS outputs conduit |
|
-- NCO output (available if IO_NCO_EN = true) -- |
nco_o : out std_ulogic_vector(02 downto 0); -- numerically-controlled oscillator channels |
|
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o : out std_ulogic; -- async serial data line |
neoled_o : out std_ulogic; -- async serial data line |
|
-- System time -- |
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true) |
mtime_i : in std_ulogic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o : out std_ulogic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true) |
|
-- Interrupts -- |
nm_irq_i : in std_ulogic := '0'; -- non-maskable interrupt |
soc_firq_i : in std_ulogic_vector(5 downto 0) := (others => '0'); -- fast interrupt channels |
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt |
mext_irq_i : in std_ulogic := '0' -- machine external interrupt |
-- External platform interrupts (available if XIRQ_NUM_CH > 0) -- |
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels |
|
-- CPU interrupts -- |
nm_irq_i : in std_ulogic := '0'; -- non-maskable interrupt |
mtime_irq_i : in std_ulogic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i : in std_ulogic := '0'; -- machine software interrupt |
mext_irq_i : in std_ulogic := '0' -- machine external interrupt |
); |
end neorv32_top; |
|
architecture neorv32_top_rtl of neorv32_top is |
|
-- CPU boot address -- |
constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(BOOTLOADER_EN, boot_rom_base_c, ispace_base_c); |
-- CPU boot configuration -- |
constant cpu_boot_addr_c : std_ulogic_vector(31 downto 0) := cond_sel_stdulogicvector_f(INT_BOOTLOADER_EN, boot_rom_base_c, ispace_base_c); |
|
-- alignment check for internal memories -- |
constant imem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) := (others => '0'); |
constant dmem_align_check_c : std_ulogic_vector(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) := (others => '0'); |
|
-- helpers -- |
constant io_slink_en_c : boolean := boolean(SLINK_NUM_RX > 0) or boolean(SLINK_NUM_TX > 0); -- implement slink at all? |
|
-- reset generator -- |
signal rstn_gen : std_ulogic_vector(7 downto 0); |
signal ext_rstn : std_ulogic; |
216,7 → 237,7
signal clk_div : std_ulogic_vector(11 downto 0); |
signal clk_div_ff : std_ulogic_vector(11 downto 0); |
signal clk_gen : std_ulogic_vector(07 downto 0); |
signal clk_gen_en : std_ulogic_vector(08 downto 0); |
signal clk_gen_en : std_ulogic_vector(07 downto 0); |
-- |
signal wdt_cg_en : std_ulogic; |
signal uart0_cg_en : std_ulogic; |
225,7 → 246,6
signal twi_cg_en : std_ulogic; |
signal pwm_cg_en : std_ulogic; |
signal cfs_cg_en : std_ulogic; |
signal nco_cg_en : std_ulogic; |
signal neoled_cg_en : std_ulogic; |
|
-- bus interface -- |
279,7 → 299,7
|
-- module response bus - device ID -- |
type resp_bus_id_t is (RESP_IMEM, RESP_DMEM, RESP_BOOTROM, RESP_WISHBONE, RESP_GPIO, RESP_MTIME, RESP_UART0, RESP_UART1, RESP_SPI, |
RESP_TWI, RESP_PWM, RESP_WDT, RESP_TRNG, RESP_CFS, RESP_NCO, RESP_NEOLED, RESP_SYSINFO, RESP_OCD); |
RESP_TWI, RESP_PWM, RESP_WDT, RESP_TRNG, RESP_CFS, RESP_NEOLED, RESP_SYSINFO, RESP_OCD, RESP_SLINK, RESP_XIRQ); |
|
-- module response bus -- |
type resp_bus_t is array (resp_bus_id_t) of resp_bus_entry_t; |
287,9 → 307,7
|
-- IRQs -- |
signal fast_irq : std_ulogic_vector(15 downto 0); |
signal fast_irq_ack : std_ulogic_vector(15 downto 0); |
signal mtime_irq : std_ulogic; |
signal gpio_irq : std_ulogic; |
signal wdt_irq : std_ulogic; |
signal uart0_rxd_irq : std_ulogic; |
signal uart0_txd_irq : std_ulogic; |
298,8 → 316,10
signal spi_irq : std_ulogic; |
signal twi_irq : std_ulogic; |
signal cfs_irq : std_ulogic; |
signal cfs_irq_ack : std_ulogic; |
signal neoled_irq : std_ulogic; |
signal slink_tx_irq : std_ulogic; |
signal slink_rx_irq : std_ulogic; |
signal xirq_irq : std_ulogic; |
|
-- misc -- |
signal mtime_time : std_ulogic_vector(63 downto 0); -- current system time from MTIME |
308,31 → 328,59
|
begin |
|
-- Processor IO/Peripherals Configuration ------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert false report |
"NEORV32 PROCESSOR IO Configuration: " & |
cond_sel_string_f(IO_GPIO_EN, "GPIO ", "") & |
cond_sel_string_f(IO_MTIME_EN, "MTIME ", "") & |
cond_sel_string_f(IO_UART0_EN, "UART0 ", "") & |
cond_sel_string_f(IO_UART1_EN, "UART1 ", "") & |
cond_sel_string_f(IO_SPI_EN, "SPI ", "") & |
cond_sel_string_f(IO_TWI_EN, "TWI ", "") & |
cond_sel_string_f(boolean(IO_PWM_NUM_CH > 0), "PWM ", "") & |
cond_sel_string_f(IO_WDT_EN, "WDT ", "") & |
cond_sel_string_f(IO_TRNG_EN, "TRNG ", "") & |
cond_sel_string_f(IO_CFS_EN, "CFS ", "") & |
cond_sel_string_f(io_slink_en_c, "SLINK ", "") & |
cond_sel_string_f(IO_NEOLED_EN, "NEOLED ", "") & |
cond_sel_string_f(boolean(XIRQ_NUM_CH > 0), "XIRQ ", "") & |
"" |
severity note; |
|
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- clock -- |
assert not (CLOCK_FREQUENCY = 0) report "NEORV32 PROCESSOR CONFIG ERROR! Core clock frequency (CLOCK_FREQUENCY) not specified." severity error; |
-- internal bootloader ROM -- |
assert not ((BOOTLOADER_EN = true) and (boot_rom_size_c > boot_rom_max_size_c)) report "NEORV32 PROCESSOR CONFIG ERROR! Boot ROM size out of range." severity error; |
assert not ((BOOTLOADER_EN = true) and (MEM_INT_IMEM_ROM = true)) report "NEORV32 PROCESSOR CONFIG WARNING! IMEM is configured as read-only. Bootloader will not be able to load new executables." severity warning; |
-- memory system - data/instruction fetch -- |
assert not ((MEM_EXT_EN = false) and (MEM_INT_DMEM_EN = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch data without external memory interface and internal data memory." severity error; |
assert not ((MEM_EXT_EN = false) and (MEM_INT_IMEM_EN = false) and (BOOTLOADER_EN = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch instructions without external memory interface, internal data memory and bootloader." severity error; |
|
-- boot configuration -- |
assert not (INT_BOOTLOADER_EN = true) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Indirect boot via bootloader (processor-internal BOOTROM)." severity note; |
assert not ((INT_BOOTLOADER_EN = false) and (MEM_INT_IMEM_EN = true)) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-internal IMEM)." severity note; |
assert not ((INT_BOOTLOADER_EN = false) and (MEM_INT_IMEM_EN = false)) report "NEORV32 PROCESSOR CONFIG NOTE: Boot configuration: Direct boot from memory (processor-external (I)MEM)." severity note; |
-- |
assert not ((MEM_EXT_EN = false) and (MEM_INT_DMEM_EN = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch data without external memory interface and internal IMEM." severity error; |
assert not ((MEM_EXT_EN = false) and (MEM_INT_IMEM_EN = false) and (INT_BOOTLOADER_EN = false)) report "NEORV32 PROCESSOR CONFIG ERROR! Core cannot fetch instructions without external memory interface, internal IMEM and bootloader." severity error; |
|
-- memory system - size -- |
assert not ((MEM_INT_DMEM_EN = true) and (is_power_of_two_f(MEM_INT_IMEM_SIZE) = false)) report "NEORV32 PROCESSOR CONFIG WARNING! MEM_INT_IMEM_SIZE should be a power of 2 to allow optimal hardware mapping." severity warning; |
assert not ((MEM_INT_IMEM_EN = true) and (is_power_of_two_f(MEM_INT_DMEM_SIZE) = false)) report "NEORV32 PROCESSOR CONFIG WARNING! MEM_INT_DMEM_SIZE should be a power of 2 to allow optimal hardware mapping." severity warning; |
|
-- memory system - alignment -- |
assert not (ispace_base_c(1 downto 0) /= "00") report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address must be 4-byte-aligned." severity error; |
assert not (dspace_base_c(1 downto 0) /= "00") report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address must be 4-byte-aligned." severity error; |
assert not ((ispace_base_c(index_size_f(MEM_INT_IMEM_SIZE)-1 downto 0) /= imem_align_check_c) and (MEM_INT_IMEM_EN = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Instruction memory space base address has to be aligned to IMEM size." severity error; |
assert not ((dspace_base_c(index_size_f(MEM_INT_DMEM_SIZE)-1 downto 0) /= dmem_align_check_c) and (MEM_INT_DMEM_EN = true)) report "NEORV32 PROCESSOR CONFIG ERROR! Data memory space base address has to be aligned to DMEM size." severity error; |
|
-- memory system - layout warning -- |
assert not (ispace_base_c /= x"00000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for instruction address space. Make sure this is sync with the software framework." severity warning; |
assert not (dspace_base_c /= x"80000000") report "NEORV32 PROCESSOR CONFIG WARNING! Non-default base address for data address space. Make sure this is sync with the software framework." severity warning; |
|
-- memory system - the i-cache is intended to accelerate instruction fetch via the external memory interface only -- |
assert not ((ICACHE_EN = true) and (MEM_EXT_EN = false)) report "NEORV32 PROCESSOR CONFIG NOTE. Implementing i-cache without having the external memory interface implemented. The i-cache is intended to accelerate instruction fetch via the external memory interface." severity note; |
|
-- on-chip debugger -- |
assert not (ON_CHIP_DEBUGGER_EN = true) report "NEORV32 PROCESSOR CONFIG NOTE. Implementing on-chip debugger (OCD)." severity note; |
assert not (ON_CHIP_DEBUGGER_EN = true) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing on-chip debugger (OCD)." severity note; |
|
|
-- Reset Generator ------------------------------------------------------------------------ |
372,8 → 420,7
clk_gen_en(4) <= twi_cg_en; |
clk_gen_en(5) <= pwm_cg_en; |
clk_gen_en(6) <= cfs_cg_en; |
clk_gen_en(7) <= nco_cg_en; |
clk_gen_en(8) <= neoled_cg_en; |
clk_gen_en(7) <= neoled_cg_en; |
-- actual clock generator -- |
if (or_reduce_f(clk_gen_en) = '1') then |
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1); |
409,6 → 456,7
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.? |
CPU_EXTENSION_RISCV_Zmmul => CPU_EXTENSION_RISCV_Zmmul, -- implement multiply-only M sub-extension? |
CPU_EXTENSION_RISCV_DEBUG => ON_CHIP_DEBUGGER_EN, -- implement CPU debug mode? |
-- Extension Options -- |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier |
460,7 → 508,6
mtime_irq_i => mtime_irq, -- machine timer interrupt |
-- fast interrupts (custom) -- |
firq_i => fast_irq, -- fast interrupt trigger |
firq_ack_o => fast_irq_ack, -- fast interrupt acknowledge mask |
-- debug mode (halt) request -- |
db_halt_req_i => dci_halt_req |
); |
473,7 → 520,7
fence_o <= cpu_d.fence; -- indicates an executed FENCE operation |
fencei_o <= cpu_i.fence; -- indicates an executed FENCEI operation |
|
-- fast interrupts - processor-internal -- |
-- fast interrupts -- |
fast_irq(00) <= wdt_irq; -- HIGHEST PRIORITY - watchdog timeout |
fast_irq(01) <= cfs_irq; -- custom functions subsystem |
fast_irq(02) <= uart0_rxd_irq; -- primary UART (UART0) data received |
482,26 → 529,14
fast_irq(05) <= uart1_txd_irq; -- secondary UART (UART1) sending done |
fast_irq(06) <= spi_irq; -- SPI transmission done |
fast_irq(07) <= twi_irq; -- TWI transmission done |
fast_irq(08) <= gpio_irq; -- GPIO pin-change |
fast_irq(08) <= xirq_irq; -- external interrupt controller |
fast_irq(09) <= neoled_irq; -- NEOLED buffer free |
fast_irq(10) <= slink_rx_irq; -- SLINK data received |
fast_irq(11) <= slink_tx_irq; -- SLINK data send |
-- |
fast_irq(15 downto 12) <= (others => '0'); -- reserved |
|
-- fast interrupts - platform level (for custom use) -- |
soc_firq_sync: process(clk_i) |
begin |
if rising_edge(clk_i) then -- make sure they are sync |
fast_irq(10) <= soc_firq_i(0); |
fast_irq(11) <= soc_firq_i(1); |
fast_irq(12) <= soc_firq_i(2); |
fast_irq(13) <= soc_firq_i(3); |
fast_irq(14) <= soc_firq_i(4); |
fast_irq(15) <= soc_firq_i(5); |
end if; |
end process soc_firq_sync; |
|
-- CFS IRQ acknowledge -- |
cfs_irq_ack <= fast_irq_ack(1); |
|
|
-- CPU Instruction Cache ------------------------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
neorv32_icache_inst_true: |
656,10 → 691,9
if (MEM_INT_IMEM_EN = true) generate |
neorv32_int_imem_inst: neorv32_imem |
generic map ( |
IMEM_BASE => imem_base_c, -- memory base address |
IMEM_SIZE => MEM_INT_IMEM_SIZE, -- processor-internal instruction memory size in bytes |
IMEM_AS_ROM => MEM_INT_IMEM_ROM, -- implement IMEM as read-only memory? |
BOOTLOADER_EN => BOOTLOADER_EN -- implement and use bootloader? |
IMEM_BASE => imem_base_c, -- memory base address |
IMEM_SIZE => MEM_INT_IMEM_SIZE, -- processor-internal instruction memory size in bytes |
IMEM_AS_IROM => not INT_BOOTLOADER_EN -- implement IMEM as pre-initialized read-only memory? |
) |
port map ( |
clk_i => clk_i, -- global clock line |
711,11 → 745,10
-- Processor-Internal Bootloader ROM (BOOTROM) -------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_boot_rom_inst_true: |
if (BOOTLOADER_EN = true) generate |
if (INT_BOOTLOADER_EN = true) generate |
neorv32_boot_rom_inst: neorv32_boot_rom |
generic map ( |
BOOTROM_BASE => boot_rom_base_c, -- boot ROM base address |
BOOTROM_SIZE => boot_rom_size_c -- processor-internal boot TOM memory size in bytes |
BOOTROM_BASE => boot_rom_base_c -- boot ROM base address |
) |
port map ( |
clk_i => clk_i, -- global clock line |
728,7 → 761,7
end generate; |
|
neorv32_boot_rom_inst_false: |
if (BOOTLOADER_EN = false) generate |
if (INT_BOOTLOADER_EN = false) generate |
resp_bus(RESP_BOOTROM) <= resp_bus_entry_terminate_c; |
end generate; |
|
739,7 → 772,6
if (MEM_EXT_EN = true) generate |
neorv32_wishbone_inst: neorv32_wishbone |
generic map ( |
WB_PIPELINED_MODE => wb_pipe_mode_c, -- false: classic/standard wishbone mode, true: pipelined wishbone mode |
-- Internal instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
809,7 → 841,7
if (IO_CFS_EN = true) generate |
neorv32_cfs_inst: neorv32_cfs |
generic map ( |
CFS_CONFIG => IO_CFS_CONFIG, -- custom CFS configuration generic |
CFS_CONFIG => IO_CFS_CONFIG, -- custom CFS configuration generic |
CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits |
CFS_OUT_SIZE => IO_CFS_OUT_SIZE -- size of CFS output conduit in bits |
) |
830,7 → 862,6
sleep_i => cpu_sleep, -- set if cpu is in sleep mode |
-- interrupt -- |
irq_o => cfs_irq, -- interrupt request |
irq_ack_i => cfs_irq_ack, -- interrupt acknowledge |
-- custom io (conduit) -- |
cfs_in_i => cfs_in_i, -- custom inputs |
cfs_out_o => cfs_out_o -- custom outputs |
863,9 → 894,7
ack_o => resp_bus(RESP_GPIO).ack, -- transfer acknowledge |
-- parallel io -- |
gpio_o => gpio_o, |
gpio_i => gpio_i, |
-- interrupt -- |
irq_o => gpio_irq -- pin-change interrupt |
gpio_i => gpio_i |
); |
resp_bus(RESP_GPIO).err <= '0'; -- no access error possible |
end generate; |
873,8 → 902,7
neorv32_gpio_inst_false: |
if (IO_GPIO_EN = false) generate |
resp_bus(RESP_GPIO) <= resp_bus_entry_terminate_c; |
gpio_o <= (others => '0'); |
gpio_irq <= '0'; |
gpio_o <= (others => '0'); |
end generate; |
|
|
1159,37 → 1187,6
end generate; |
|
|
-- Numerically-Controlled Oscillator (NCO) ------------------------------------------------ |
-- ------------------------------------------------------------------------------------------- |
neorv32_nco_inst_true: |
if (IO_NCO_EN = true) generate |
neorv32_nco_inst: neorv32_nco |
port map ( |
-- host access -- |
clk_i => clk_i, -- global clock line |
addr_i => p_bus.addr, -- address |
rden_i => io_rden, -- read enable |
wren_i => io_wren, -- write enable |
data_i => p_bus.wdata, -- data in |
data_o => resp_bus(RESP_NCO).rdata, -- data out |
ack_o => resp_bus(RESP_NCO).ack, -- transfer acknowledge |
-- clock generator -- |
clkgen_en_o => nco_cg_en, -- enable clock generator |
clkgen_i => clk_gen, |
-- NCO output -- |
nco_o => nco_o |
); |
resp_bus(RESP_NCO).err <= '0'; -- no access error possible |
end generate; |
|
neorv32_nco_inst_false: |
if (IO_NCO_EN = false) generate |
resp_bus(RESP_NCO) <= resp_bus_entry_terminate_c; |
nco_cg_en <= '0'; |
nco_o <= (others => '0'); |
end generate; |
|
|
-- True Random Number Generator (TRNG) ---------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_trng_inst_true: |
1248,6 → 1245,86
end generate; |
|
|
-- Stream Link Interface (SLINK) ---------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_slink_inst_true: |
if (io_slink_en_c = true) generate |
neorv32_slink_inst: neorv32_slink |
generic map ( |
SLINK_NUM_TX => SLINK_NUM_TX, -- number of TX links (0..8) |
SLINK_NUM_RX => SLINK_NUM_RX, -- number of TX links (0..8) |
SLINK_TX_FIFO => SLINK_TX_FIFO, -- TX fifo depth, has to be a power of two |
SLINK_RX_FIFO => SLINK_RX_FIFO -- RX fifo depth, has to be a power of two |
) |
port map ( |
-- host access -- |
clk_i => clk_i, -- global clock line |
addr_i => p_bus.addr, -- address |
rden_i => io_rden, -- read enable |
wren_i => io_wren, -- write enable |
data_i => p_bus.wdata, -- data in |
data_o => resp_bus(RESP_SLINK).rdata, -- data out |
ack_o => resp_bus(RESP_SLINK).ack, -- transfer acknowledge |
-- interrupt -- |
irq_tx_o => slink_tx_irq, -- transmission done |
irq_rx_o => slink_rx_irq, -- data received |
-- TX stream interfaces -- |
slink_tx_dat_o => slink_tx_dat_o, -- output data |
slink_tx_val_o => slink_tx_val_o, -- valid output |
slink_tx_rdy_i => slink_tx_rdy_i, -- ready to send |
-- RX stream interfaces -- |
slink_rx_dat_i => slink_rx_dat_i, -- input data |
slink_rx_val_i => slink_rx_val_i, -- valid input |
slink_rx_rdy_o => slink_rx_rdy_o -- ready to receive |
); |
resp_bus(RESP_SLINK).err <= '0'; -- no access error possible |
end generate; |
|
neorv32_slink_inst_false: |
if (io_slink_en_c = false) generate |
resp_bus(RESP_SLINK) <= resp_bus_entry_terminate_c; |
slink_tx_irq <= '0'; |
slink_rx_irq <= '0'; |
slink_tx_dat_o <= (others => (others => '0')); |
slink_tx_val_o <= (others => '0'); |
slink_rx_rdy_o <= (others => '0'); |
end generate; |
|
|
-- External Interrupt Controller (XIRQ) --------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_xirq_inst_true: |
if (XIRQ_NUM_CH > 0) generate |
neorv32_slink_inst: neorv32_xirq |
generic map ( |
XIRQ_NUM_CH => XIRQ_NUM_CH, -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE => XIRQ_TRIGGER_TYPE, -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY => XIRQ_TRIGGER_POLARITY -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
) |
port map ( |
-- host access -- |
clk_i => clk_i, -- global clock line |
addr_i => p_bus.addr, -- address |
rden_i => io_rden, -- read enable |
wren_i => io_wren, -- write enable |
data_i => p_bus.wdata, -- data in |
data_o => resp_bus(RESP_XIRQ).rdata, -- data out |
ack_o => resp_bus(RESP_XIRQ).ack, -- transfer acknowledge |
-- external interrupt lines -- |
xirq_i => xirq_i, |
-- CPU interrupt -- |
cpu_irq_o => xirq_irq |
); |
resp_bus(RESP_XIRQ).err <= '0'; -- no access error possible |
end generate; |
|
neorv32_xirq_inst_false: |
if (XIRQ_NUM_CH = 0) generate |
resp_bus(RESP_XIRQ) <= resp_bus_entry_terminate_c; |
xirq_irq <= '0'; |
end generate; |
|
|
-- System Configuration Information Memory (SYSINFO) -------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_sysinfo_inst: neorv32_sysinfo |
1254,12 → 1331,11
generic map ( |
-- General -- |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
BOOTLOADER_EN => BOOTLOADER_EN, -- implement processor-internal bootloader? |
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- implement processor-internal bootloader? |
USER_CODE => USER_CODE, -- custom user code |
-- internal Instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
MEM_INT_IMEM_ROM => MEM_INT_IMEM_ROM, -- implement processor-internal instruction memory as ROM |
-- Internal Data memory -- |
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes |
1283,8 → 1359,9
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)? |
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)? |
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)? |
IO_NCO_EN => IO_NCO_EN, -- implement numerically-controlled oscillator (NCO)? |
IO_NEOLED_EN => IO_NEOLED_EN -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
IO_SLINK_EN => io_slink_en_c, -- implement stream link interface? |
IO_NEOLED_EN => IO_NEOLED_EN, -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
IO_XIRQ_NUM_CH => XIRQ_NUM_CH -- number of external interrupt (XIRQ) channels to implement |
) |
port map ( |
-- host access -- |
/core/neorv32_wishbone.vhd
1,20 → 1,19
-- ################################################################################################# |
-- # << NEORV32 - External Bus Interface (WISHBONE) >> # |
-- # ********************************************************************************************* # |
-- # The interface provides registers for all outgoing and for all incoming signals. If the host # |
-- # cancels an active transfer, the Wishbone arbiter still waits some time for the bus system to # |
-- # ACK/ERR the transfer before the arbiter forces termination. # |
-- # All bus accesses from the CPU, which do not target the internal IO region / the internal # |
-- # bootloader / the internal instruction or data memories (if implemented), are delegated via # |
-- # this Wishbone gateway to the external bus interface. Accessed peripherals can have a response # |
-- # latency of up to BUS_TIMEOUT - 1 cycles. # |
-- # # |
-- # Even when all processor-internal memories and IO devices are disabled, the EXTERNAL address # |
-- # space ENDS at address 0xffff0000 (begin of internal BOOTROM address space). # |
-- # # |
-- # All bus accesses from the CPU, which do not target the internal IO region / the internal # |
-- # bootloader / the internal instruction or data memories (if implemented), are delegated via # |
-- # this Wishbone gateway to the external bus interface. Accessed peripherals can have a response # |
-- # latency of up to BUS_TIMEOUT - 2 cycles. # |
-- # The interface uses registers for ALL OUTGOING AND FOR ALL INCOMING signals. Hence, an access # |
-- # latency of (at least) 2 cycles is added. # |
-- # # |
-- # This interface supports classic/standard Wishbone transactions (WB_PIPELINED_MODE = false) # |
-- # and also pipelined transactions (WB_PIPELINED_MODE = true). # |
-- # This interface supports classic/standard Wishbone transactions (pkg.wb_pipe_mode_c = false) # |
-- # and also pipelined transactions (pkg.wb_pipe_mode_c = true). # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
56,7 → 55,6
|
entity neorv32_wishbone is |
generic ( |
WB_PIPELINED_MODE : boolean := false; -- false: classic/standard wishbone mode, true: pipelined wishbone mode |
-- Internal instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes |
109,44 → 107,50
signal xbus_access : std_ulogic; |
|
-- bus arbiter |
type ctrl_state_t is (IDLE, BUSY, RESYNC); |
type ctrl_state_t is (IDLE, BUSY); |
type ctrl_t is record |
state : ctrl_state_t; |
we : std_ulogic; |
rd_req : std_ulogic; |
wr_req : std_ulogic; |
adr : std_ulogic_vector(31 downto 0); |
wdat : std_ulogic_vector(31 downto 0); |
rdat : std_ulogic_vector(31 downto 0); |
sel : std_ulogic_vector(3 downto 0); |
sel : std_ulogic_vector(03 downto 0); |
ack : std_ulogic; |
err : std_ulogic; |
timeout : std_ulogic_vector(index_size_f(BUS_TIMEOUT)-1 downto 0); |
src : std_ulogic; |
lock : std_ulogic; |
priv : std_ulogic_vector(1 downto 0); |
priv : std_ulogic_vector(01 downto 0); |
end record; |
signal ctrl : ctrl_t; |
signal stb_int : std_ulogic; |
signal cyc_int : std_ulogic; |
signal rdata : std_ulogic_vector(31 downto 0); |
|
-- async RX mode -- |
signal ack_gated : std_ulogic; |
signal rdata_gated : std_ulogic_vector(31 downto 0); |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- protocol -- |
assert not (wb_pipe_mode_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing STANDARD Wishbone protocol." severity note; |
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing PIEPLINED Wishbone protocol." severity note; |
|
-- bus timeout -- |
assert not (BUS_TIMEOUT /= 0) report "NEORV32 PROCESSOR CONFIG NOTE: Using auto-timeout for external bus interface (" & integer'image(BUS_TIMEOUT) & " cycles)." severity note; |
assert not (BUS_TIMEOUT = 0) report "NEORV32 PROCESSOR CONFIG NOTE: Using no auto-timeout for external bus interface (might cause permanent CPU stall)." severity note; |
assert not (BUS_TIMEOUT /= 0) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing auto-timeout (" & integer'image(BUS_TIMEOUT) & " cycles)." severity note; |
assert not (BUS_TIMEOUT = 0) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing no auto-timeout (can cause permanent CPU stall!)." severity note; |
|
-- external memory interface protocol + max timeout latency notifier (warning) -- |
assert not (wb_pipe_mode_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing external memory interface using STANDARD Wishbone protocol." severity note; |
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: Implementing external memory interface using PIEPLINED Wishbone protocol." severity note; |
|
-- endianness -- |
assert not (xbus_big_endian_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: Using LITTLE-ENDIAN byte order for external memory interface." severity note; |
assert not (xbus_big_endian_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: Using BIG-ENDIAN byte order for external memory interface." severity note; |
assert not (wb_big_endian_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing LITTLE-endian byte order." severity note; |
assert not (wb_big_endian_c = true) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing BIG-endian byte." severity note; |
|
-- async RC -- |
assert not (wb_rx_buffer_c = false) report "NEORV32 PROCESSOR CONFIG NOTE: External Bus Interface - Implementing ASYNC RX path." severity note; |
|
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
-- access to processor-internal IMEM or DMEM? -- |
157,6 → 161,7
-- actual external bus access? -- |
xbus_access <= (not int_imem_acc) and (not int_dmem_acc) and (not int_boot_acc); |
|
|
-- Bus Arbiter ----------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
bus_arbiter: process(rstn_i, clk_i) |
164,8 → 169,6
if (rstn_i = '0') then |
ctrl.state <= IDLE; |
ctrl.we <= def_rst_val_c; |
ctrl.rd_req <= '0'; |
ctrl.wr_req <= '0'; |
ctrl.adr <= (others => def_rst_val_c); |
ctrl.wdat <= (others => def_rst_val_c); |
ctrl.rdat <= (others => def_rst_val_c); |
178,7 → 181,7
ctrl.priv <= (others => def_rst_val_c); |
elsif rising_edge(clk_i) then |
-- defaults -- |
ctrl.rdat <= (others => '0'); |
ctrl.rdat <= (others => '0'); -- required for internal output gating |
ctrl.ack <= '0'; |
ctrl.err <= '0'; |
ctrl.timeout <= std_ulogic_vector(to_unsigned(BUS_TIMEOUT, index_size_f(BUS_TIMEOUT))); |
188,12 → 191,10
|
when IDLE => -- waiting for host request |
-- ------------------------------------------------------------ |
ctrl.rd_req <= '0'; |
ctrl.wr_req <= '0'; |
-- buffer all outgoing signals -- |
ctrl.we <= wren_i or ctrl.wr_req; |
ctrl.we <= wren_i; |
ctrl.adr <= addr_i; |
if (xbus_big_endian_c = true) then -- big-endian |
if (wb_big_endian_c = true) then -- big-endian |
ctrl.wdat <= bswap32_f(data_i); |
ctrl.sel <= bit_rev_f(ben_i); |
else -- little-endian |
204,7 → 205,7
ctrl.lock <= lock_i; |
ctrl.priv <= priv_i; |
-- valid new or buffered read/write request -- |
if ((xbus_access and (wren_i or ctrl.wr_req or rden_i or ctrl.rd_req)) = '1') then |
if ((xbus_access and (wren_i or rden_i)) = '1') then |
ctrl.state <= BUSY; |
end if; |
|
211,15 → 212,13
when BUSY => -- transfer in progress |
-- ------------------------------------------------------------ |
ctrl.rdat <= wb_dat_i; |
if (wb_err_i = '1') then -- abnormal bus termination |
if (wb_err_i = '1') or -- abnormal bus termination |
((timeout_en_c = true) and (or_reduce_f(ctrl.timeout) = '0')) then -- valid timeout |
ctrl.err <= '1'; |
ctrl.state <= IDLE; |
elsif (wb_ack_i = '1') then -- normal bus termination |
ctrl.ack <= '1'; |
ctrl.state <= IDLE; |
elsif (timeout_en_c = true) and (or_reduce_f(ctrl.timeout) = '0') then -- valid timeout |
ctrl.err <= '1'; |
ctrl.state <= IDLE; |
end if; |
-- timeout counter -- |
if (timeout_en_c = true) then |
226,14 → 225,6
ctrl.timeout <= std_ulogic_vector(unsigned(ctrl.timeout) - 1); -- timeout counter |
end if; |
|
when RESYNC => -- make sure transfer is done! |
-- ------------------------------------------------------------ |
ctrl.wr_req <= ctrl.wr_req or wren_i; -- buffer new request |
ctrl.rd_req <= ctrl.rd_req or rden_i; -- buffer new request |
if (wb_ack_i = '0') then |
ctrl.state <= IDLE; |
end if; |
|
when others => -- undefined |
-- ------------------------------------------------------------ |
ctrl.state <= IDLE; |
243,8 → 234,12
end process bus_arbiter; |
|
-- host access -- |
data_o <= ctrl.rdat when (xbus_big_endian_c = false) else bswap32_f(ctrl.rdat); -- endianness conversion |
ack_o <= ctrl.ack; |
ack_gated <= wb_ack_i when (ctrl.state = BUSY) else '0'; -- CPU ack gate for "async" RX |
rdata_gated <= wb_dat_i when (ctrl.state = BUSY) else (others => '0'); -- CPU read data gate for "async" RX |
rdata <= ctrl.rdat when (wb_rx_buffer_c = true) else rdata_gated; |
|
data_o <= rdata when (wb_big_endian_c = false) else bswap32_f(rdata); -- endianness conversion |
ack_o <= ctrl.ack when (wb_rx_buffer_c = true) else ack_gated; |
err_o <= ctrl.err; |
|
-- wishbone interface -- |
254,15 → 249,15
|
wb_lock_o <= ctrl.lock; -- 1 = exclusive access request |
|
wb_adr_o <= ctrl.adr; |
wb_dat_o <= ctrl.wdat; |
wb_we_o <= ctrl.we; |
wb_sel_o <= ctrl.sel; |
wb_stb_o <= stb_int when (WB_PIPELINED_MODE = true) else cyc_int; |
wb_cyc_o <= cyc_int; |
wb_adr_o <= ctrl.adr; |
wb_dat_o <= ctrl.wdat; |
wb_we_o <= ctrl.we; |
wb_sel_o <= ctrl.sel; |
wb_stb_o <= stb_int when (wb_pipe_mode_c = true) else cyc_int; |
wb_cyc_o <= cyc_int; |
|
stb_int <= '1' when (ctrl.state = BUSY) else '0'; |
cyc_int <= '0' when (ctrl.state = IDLE) or (ctrl.state = RESYNC) else '1'; |
cyc_int <= '1' when (ctrl.state = BUSY) else '0'; |
|
|
end neorv32_wishbone_rtl; |
/core/neorv32_xirq.vhd
0,0 → 1,228
-- ################################################################################################# |
-- # << NEORV32 - External Interrupt Controller (XIRQ) >> # |
-- # ********************************************************************************************* # |
-- # Simple interrupt controller for platform (processor-external) interrupts. Up to 32 channels # |
-- # are supported that get prioritized into a single CPU interrupt. # |
-- # # |
-- # The actual trigger configuration has to be done before synthesis using the XIRQ_TRIGGER_TYPE # |
-- # and XIRQ_TRIGGER_POLARITY generics. These allow to configure channel-independent low-level, # |
-- # high-level, falling-edge and rising-edge triggers. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
entity neorv32_xirq is |
generic ( |
XIRQ_NUM_CH : natural := 32; -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE : std_ulogic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY : std_ulogic_vector(31 downto 0) := (others => '1') -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
); |
port ( |
-- host access -- |
clk_i : in std_ulogic; -- global clock line |
addr_i : in std_ulogic_vector(31 downto 0); -- address |
rden_i : in std_ulogic; -- read enable |
wren_i : in std_ulogic; -- write enable |
data_i : in std_ulogic_vector(31 downto 0); -- data in |
data_o : out std_ulogic_vector(31 downto 0); -- data out |
ack_o : out std_ulogic; -- transfer acknowledge |
-- external interrupt lines -- |
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
-- CPU interrupt -- |
cpu_irq_o : out std_ulogic |
); |
end neorv32_xirq; |
|
architecture neorv32_xirq_rtl of neorv32_xirq is |
|
-- IO space: module base address -- |
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit |
constant lo_abb_c : natural := index_size_f(xirq_size_c); -- low address boundary bit |
|
-- access control -- |
signal acc_en : std_ulogic; -- module access enable |
signal addr : std_ulogic_vector(31 downto 0); -- access address |
|
-- control registers -- |
signal irq_enable : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); -- r/w: interrupt enable |
signal clr_pending : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); -- (r)/w: clear/ack pending IRQs |
|
-- interrupt trigger -- |
signal irq_sync : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
signal irq_sync2 : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
signal irq_trig : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
|
-- interrupt buffer -- |
signal irq_buf : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
signal irq_fire : std_ulogic; |
|
-- interrupt source -- |
signal irq_src, irq_src_nxt : std_ulogic_vector(04 downto 0); |
|
-- arbiter -- |
signal irq_run : std_ulogic; |
signal irq_run_ff : std_ulogic; |
signal host_ack : std_ulogic; |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert not ((XIRQ_NUM_CH < 0) or (XIRQ_NUM_CH > 32)) report "NEORV32 PROCESSOR CONFIG ERROR: Number of XIRQ inputs <XIRQ_NUM_CH> has to be 0..32." severity error; |
|
|
-- Access Control ------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
acc_en <= '1' when (addr_i(hi_abb_c downto lo_abb_c) = xirq_base_c(hi_abb_c downto lo_abb_c)) else '0'; |
addr <= xirq_base_c(31 downto lo_abb_c) & addr_i(lo_abb_c-1 downto 2) & "00"; -- word aligned |
|
|
-- Read/Write Access ---------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
rw_access: process(clk_i) |
begin |
if rising_edge(clk_i) then |
-- bus handshake -- |
ack_o <= acc_en and (rden_i or wren_i); |
|
-- write access -- |
host_ack <= '0'; |
clr_pending <= (others => '0'); |
if ((acc_en and wren_i) = '1') then |
-- channel-enable -- |
if (addr = xirq_enable_addr_c) then |
irq_enable <= data_i(XIRQ_NUM_CH-1 downto 0); |
end if; |
-- clear/ACK pending IRQ -- |
if (addr = xirq_pending_addr_c) then |
host_ack <= '1'; |
clr_pending <= data_i(XIRQ_NUM_CH-1 downto 0); |
end if; |
end if; |
|
-- read access -- |
data_o <= (others => '0'); |
if ((acc_en and rden_i) = '1') then |
case addr is |
when xirq_enable_addr_c => data_o(XIRQ_NUM_CH-1 downto 0) <= irq_enable; -- channel-enable |
when xirq_pending_addr_c => data_o(XIRQ_NUM_CH-1 downto 0) <= irq_buf; -- pending IRQs |
when xirq_source_addr_c => data_o(4 downto 0) <= irq_src; -- source IRQ |
when others => NULL; |
end case; |
end if; |
end if; |
end process rw_access; |
|
|
-- IRQ Trigger -------------------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
irq_trigger: process(clk_i) |
begin |
if rising_edge(clk_i) then |
irq_sync <= xirq_i; |
irq_sync2 <= irq_sync; |
end if; |
end process irq_trigger; |
|
irq_trigger_comb: process(irq_sync, irq_sync2) |
variable sel_v : std_ulogic_vector(1 downto 0); |
begin |
for i in 0 to XIRQ_NUM_CH-1 loop |
sel_v := XIRQ_TRIGGER_TYPE(i) & XIRQ_TRIGGER_POLARITY(i); |
case sel_v is |
when "00" => irq_trig(i) <= not irq_sync(i); -- low-level |
when "01" => irq_trig(i) <= irq_sync(i); -- high-level |
when "10" => irq_trig(i) <= (not irq_sync(i)) and irq_sync2(i); -- falling-edge |
when "11" => irq_trig(i) <= irq_sync(i) and (not irq_sync2(i)); -- rising-edge |
when others => irq_trig(i) <= '0'; |
end case; |
end loop; |
end process irq_trigger_comb; |
|
|
-- IRQ Buffer --------------------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
irq_buffer: process(clk_i) |
begin |
if rising_edge(clk_i) then |
irq_buf <= (irq_buf or (irq_trig and irq_enable)) and (not clr_pending); |
end if; |
end process irq_buffer; |
|
-- anyone firing? -- |
irq_fire <= or_reduce_f(irq_buf); |
|
|
-- IRQ Priority Encoder ----------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
irq_priority: process(irq_buf) |
begin |
irq_src_nxt <= (others => '0'); |
for i in 0 to XIRQ_NUM_CH-1 loop |
if (irq_buf(i) = '1') then |
irq_src_nxt <= std_ulogic_vector(to_unsigned(i, 5)); |
exit; |
end if; |
end loop; |
end process irq_priority; |
|
|
-- IRQ Arbiter -------------------------------------------------------------- |
-- ----------------------------------------------------------------------------- |
irq_arbiter: process(clk_i) |
begin |
if rising_edge(clk_i) then |
irq_run_ff <= irq_run; |
if (irq_run = '0') then -- no active IRQ |
if (irq_fire = '1') then |
irq_run <= '1'; |
irq_src <= irq_src_nxt; |
end if; |
else -- active IRQ, wait for CPU acknowledge |
if (host_ack = '1') then |
irq_run <= '0'; |
end if; |
end if; |
end if; |
end process irq_arbiter; |
|
-- rising-edge detector -- |
cpu_irq_o <= irq_run and (not irq_run_ff); |
|
|
end neorv32_xirq_rtl; |
/templates/processor/neorv32_ProcessorTop_Minimal.vhd
0,0 → 1,248
-- ################################################################################################# |
-- # << NEORV32 - Minimal setup without a bootloader >> # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
|
entity neorv32_ProcessorTop_Minimal is |
generic ( |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
|
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
|
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
CPU_CNT_WIDTH : natural := 34; -- total width of CPU cycle and instret counters (0..64) |
|
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 8*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
|
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64) |
|
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 8*1024; -- size of processor-internal instruction memory in bytes |
|
-- Internal Data memory -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 64*1024; -- size of processor-internal data memory in bytes |
|
-- Internal Cache memory -- |
ICACHE_EN : boolean := false; -- implement instruction cache |
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
|
-- Processor peripherals -- |
IO_MTIME_EN : boolean := false; -- implement machine system timer (MTIME)? |
IO_PWM_NUM_CH : natural := 3; -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN : boolean := false -- implement watch dog timer (WDT)? |
); |
port ( |
clk_i : in std_logic; |
rstn_i : in std_logic; |
|
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0) |
); |
end entity; |
|
architecture neorv32_ProcessorTop_Minimal_rtl of neorv32_ProcessorTop_Minimal is |
|
begin |
|
-- The core of the problem ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_inst: entity neorv32.neorv32_top |
generic map ( |
-- General -- |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN => false, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE => USER_CODE, -- custom user code |
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (32-bit) |
|
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN => false, -- implement on-chip debugger? |
|
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension? |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.? |
|
-- Extension Options -- |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations |
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64) |
|
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64) |
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
|
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64) |
|
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
|
-- Internal Data memory -- |
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes |
|
-- Internal Cache memory -- |
ICACHE_EN => ICACHE_EN, -- implement instruction cache |
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
|
-- External memory interface -- |
MEM_EXT_EN => false, -- implement external memory bus interface? |
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled) |
|
-- Processor peripherals -- |
IO_GPIO_EN => false, -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)? |
IO_UART0_EN => false, -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN => false, -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN => false, -- implement serial peripheral interface (SPI)? |
IO_TWI_EN => false, -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)? |
IO_TRNG_EN => false, -- implement true random number generator (TRNG)? |
IO_CFS_EN => false, -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG => x"00000000", -- custom CFS configuration generic |
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits |
IO_NEOLED_EN => false -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
) |
port map ( |
-- Global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
|
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i => '0', -- low-active TAP reset (optional) |
jtag_tck_i => '0', -- serial clock |
jtag_tdi_i => '0', -- serial data input |
jtag_tdo_o => open, -- serial data output |
jtag_tms_i => '0', -- mode select |
|
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o => open, -- request tag |
wb_adr_o => open, -- address |
wb_dat_i => (others => '0'), -- read data |
wb_dat_o => open, -- write data |
wb_we_o => open, -- read/write |
wb_sel_o => open, -- byte enable |
wb_stb_o => open, -- strobe |
wb_cyc_o => open, -- valid cycle |
wb_lock_o => open, -- exclusive access request |
wb_ack_i => '0', -- transfer acknowledge |
wb_err_i => '0', -- transfer error |
|
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o => open, -- indicates an executed FENCE operation |
fencei_o => open, -- indicates an executed FENCEI operation |
|
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o => open, -- parallel output |
gpio_i => (others => '0'), -- parallel input |
|
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o => open, -- UART0 send data |
uart0_rxd_i => '0', -- UART0 receive data |
uart0_rts_o => open, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i => '0', -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
|
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o => open, -- UART1 send data |
uart1_rxd_i => '0', -- UART1 receive data |
uart1_rts_o => open, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i => '0', -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
|
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o => open, -- SPI serial clock |
spi_sdo_o => open, -- controller data out, peripheral data in |
spi_sdi_i => '0', -- controller data in, peripheral data out |
spi_csn_o => open, -- SPI CS |
|
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io => open, -- twi serial data line |
twi_scl_io => open, -- twi serial clock line |
|
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o => pwm_o, -- pwm channels |
|
-- Custom Functions Subsystem IO -- |
cfs_in_i => (others => '0'), -- custom CFS inputs conduit |
cfs_out_o => open, -- custom CFS outputs conduit |
|
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o => open, -- async serial data line |
|
-- System time -- |
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true) |
|
-- Interrupts -- |
nm_irq_i => '0', -- non-maskable interrupt |
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i => '0', -- machine software interrupt |
mext_irq_i => '0' -- machine external interrupt |
); |
|
end architecture; |
/templates/processor/neorv32_ProcessorTop_MinimalBoot.vhd
0,0 → 1,269
-- ################################################################################################# |
-- # << NEORV32 - Minimal setup with the bootloader enabled >> # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
|
entity neorv32_ProcessorTop_MinimalBoot is |
generic ( |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
|
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A : boolean := true; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := true; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
|
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
CPU_CNT_WIDTH : natural := 34; -- total width of CPU cycle and instret counters (0..64) |
|
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
|
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64) |
|
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 64*1024; -- size of processor-internal instruction memory in bytes |
|
-- Internal Data memory -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 64*1024; -- size of processor-internal data memory in bytes |
|
-- Internal Cache memory -- |
ICACHE_EN : boolean := false; -- implement instruction cache |
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
|
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)? |
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_PWM_NUM_CH : natural := 3; -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN : boolean := true -- implement watch dog timer (WDT)? |
); |
port ( |
clk_i : in std_logic; |
rstn_i : in std_logic; |
|
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o : out std_ulogic_vector(3 downto 0); |
|
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart_txd_o : out std_ulogic; -- UART0 send data |
uart_rxd_i : in std_ulogic := '0'; -- UART0 receive data |
uart_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
|
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0) |
); |
end entity; |
|
architecture neorv32_ProcessorTop_MinimalBoot_rtl of neorv32_ProcessorTop_MinimalBoot is |
|
-- internal IO connection -- |
signal con_gpio_o : std_ulogic_vector(63 downto 0); |
|
begin |
|
-- IO Connection -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
|
-- GPIO -- |
gpio_o <= con_gpio_o(3 downto 0); |
|
-- The core of the problem ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_inst: entity neorv32.neorv32_top |
generic map ( |
-- General -- |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN,-- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE => USER_CODE, -- custom user code |
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (32-bit) |
|
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN => false, -- implement on-chip debugger? |
|
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension? |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.? |
|
-- Extension Options -- |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations |
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64) |
|
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64) |
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
|
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64) |
|
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
|
-- Internal Data memory -- |
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes |
|
-- Internal Cache memory -- |
ICACHE_EN => ICACHE_EN, -- implement instruction cache |
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
|
-- External memory interface -- |
MEM_EXT_EN => false, -- implement external memory bus interface? |
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled) |
|
-- Processor peripherals -- |
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)? |
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN => false, -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN => false, -- implement serial peripheral interface (SPI)? |
IO_TWI_EN => false, -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)? |
IO_TRNG_EN => false, -- implement true random number generator (TRNG)? |
IO_CFS_EN => false, -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG => x"00000000", -- custom CFS configuration generic |
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits |
IO_NEOLED_EN => false -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
) |
port map ( |
-- Global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
|
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i => '0', -- low-active TAP reset (optional) |
jtag_tck_i => '0', -- serial clock |
jtag_tdi_i => '0', -- serial data input |
jtag_tdo_o => open, -- serial data output |
jtag_tms_i => '0', -- mode select |
|
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o => open, -- request tag |
wb_adr_o => open, -- address |
wb_dat_i => (others => '0'), -- read data |
wb_dat_o => open, -- write data |
wb_we_o => open, -- read/write |
wb_sel_o => open, -- byte enable |
wb_stb_o => open, -- strobe |
wb_cyc_o => open, -- valid cycle |
wb_lock_o => open, -- exclusive access request |
wb_ack_i => '0', -- transfer acknowledge |
wb_err_i => '0', -- transfer error |
|
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o => open, -- indicates an executed FENCE operation |
fencei_o => open, -- indicates an executed FENCEI operation |
|
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o => con_gpio_o, -- parallel output |
gpio_i => (others => '0'), -- parallel input |
|
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o => uart_txd_o, -- UART0 send data |
uart0_rxd_i => uart_rxd_i, -- UART0 receive data |
uart0_rts_o => uart_rts_o, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i => uart_cts_i, -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
|
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o => open, -- UART1 send data |
uart1_rxd_i => '0', -- UART1 receive data |
uart1_rts_o => open, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i => '0', -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
|
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o => open, -- SPI serial clock |
spi_sdo_o => open, -- controller data out, peripheral data in |
spi_sdi_i => '0', -- controller data in, peripheral data out |
spi_csn_o => open, -- SPI CS |
|
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io => open, -- twi serial data line |
twi_scl_io => open, -- twi serial clock line |
|
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o => pwm_o, -- pwm channels |
|
-- Custom Functions Subsystem IO -- |
cfs_in_i => (others => '0'), -- custom CFS inputs conduit |
cfs_out_o => open, -- custom CFS outputs conduit |
|
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o => open, -- async serial data line |
|
-- System time -- |
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true) |
|
-- Interrupts -- |
nm_irq_i => '0', -- non-maskable interrupt |
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i => '0', -- machine software interrupt |
mext_irq_i => '0' -- machine external interrupt |
); |
|
end architecture; |
/templates/processor/neorv32_ProcessorTop_Test.vhd
0,0 → 1,194
-- ################################################################################################# |
-- # << NEORV32 - Simple Test Setup >> # |
-- # ********************************************************************************************* # |
-- # This test setup instantiates the NEORV32 processor with a rather small configuration and only # |
-- # propagates the UART and GPIO.out signals to the outer world. # |
-- # Only internal memories are used and the address space for instructions/data is constrained to # |
-- # these memories. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
entity neorv32_ProcessorTop_Test is |
port ( |
-- Global control -- |
clk_i : in std_ulogic := '0'; -- global clock, rising edge |
rstn_i : in std_ulogic := '0'; -- global reset, low-active, async |
-- GPIO -- |
gpio_o : out std_ulogic_vector(7 downto 0); -- parallel output |
-- UART0 -- |
uart0_txd_o : out std_ulogic; -- UART0 send data |
uart0_rxd_i : in std_ulogic := '0' -- UART0 receive data |
); |
end entity; |
|
architecture neorv32_ProcessorTop_Test_rtl of neorv32_ProcessorTop_Test is |
|
-- gpio output -- |
signal gpio_out : std_ulogic_vector(63 downto 0); |
|
begin |
|
-- The Core Of The Problem ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_top_inst: neorv32_top |
generic map ( |
-- General -- |
CLOCK_FREQUENCY => 100000000, -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN => true, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE => x"00000000", -- custom user code |
HW_THREAD_ID => 0, -- hardware thread id (hartid) |
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN => false, -- implement on-chip debugger |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A => false, -- implement atomic extension? |
CPU_EXTENSION_RISCV_C => true, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => false, -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M => true, -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U => true, -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx => false, -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr => true, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => false, -- implement instruction stream sync.? |
-- Extension Options -- |
FAST_MUL_EN => false, -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN => false, -- use barrel shifter for shift operations |
CPU_CNT_WIDTH => 64, -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS => 0, -- number of regions (0..64) |
PMP_MIN_GRANULARITY => 64*1024, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS => 4, -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH => 40, -- total size of HPM counters (0..64) |
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN => true, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => 16*1024, -- size of processor-internal instruction memory in bytes |
-- Internal Data memory -- |
MEM_INT_DMEM_EN => true, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => 8*1024, -- size of processor-internal data memory in bytes |
-- Internal Cache memory -- |
ICACHE_EN => false, -- implement instruction cache |
ICACHE_NUM_BLOCKS => 4, -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE => 64, -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY => 1, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
-- External memory interface -- |
MEM_EXT_EN => false, -- implement external memory bus interface? |
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled) |
-- Processor peripherals -- |
IO_GPIO_EN => true, -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN => true, -- implement machine system timer (MTIME)? |
IO_UART0_EN => true, -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN => false, -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN => false, -- implement serial peripheral interface (SPI)? |
IO_TWI_EN => false, -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH => 0, -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN => true, -- implement watch dog timer (WDT)? |
IO_TRNG_EN => false, -- implement true random number generator (TRNG)? |
IO_CFS_EN => false, -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG => x"00000000", -- custom CFS configuration generic |
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits |
IO_NEOLED_EN => false -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
) |
port map ( |
-- Global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i => '0', -- low-active TAP reset (optional) |
jtag_tck_i => '0', -- serial clock |
jtag_tdi_i => '0', -- serial data input |
jtag_tdo_o => open, -- serial data output |
jtag_tms_i => '0', -- mode select |
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o => open, -- tag |
wb_adr_o => open, -- address |
wb_dat_i => (others => '0'), -- read data |
wb_dat_o => open, -- write data |
wb_we_o => open, -- read/write |
wb_sel_o => open, -- byte enable |
wb_stb_o => open, -- strobe |
wb_cyc_o => open, -- valid cycle |
wb_lock_o => open, -- exclusive access request |
wb_ack_i => '0', -- transfer acknowledge |
wb_err_i => '0', -- transfer error |
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o => open, -- indicates an executed FENCE operation |
fencei_o => open, -- indicates an executed FENCEI operation |
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o => gpio_out, -- parallel output |
gpio_i => (others => '0'), -- parallel input |
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o => uart0_txd_o, -- UART0 send data |
uart0_rxd_i => uart0_rxd_i, -- UART0 receive data |
uart0_rts_o => open, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i => '0', -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o => open, -- UART1 send data |
uart1_rxd_i => '0', -- UART1 receive data |
uart1_rts_o => open, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i => '0', -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o => open, -- SPI serial clock |
spi_sdo_o => open, -- controller data out, peripheral data in |
spi_sdi_i => '0', -- controller data in, peripheral data out |
spi_csn_o => open, -- SPI CS |
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io => open, -- twi serial data line |
twi_scl_io => open, -- twi serial clock line |
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o => open, -- pwm channels |
-- Custom Functions Subsystem IO -- |
cfs_in_i => (others => '0'), -- custom inputs |
cfs_out_o => open, -- custom outputs |
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o => open, -- async serial data line |
-- System time -- |
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true) |
-- Interrupts -- |
nm_irq_i => '0', -- non-maskable interrupt |
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i => '0', -- machine software interrupt |
mext_irq_i => '0' -- machine external interrupt |
); |
|
-- output -- |
gpio_o <= gpio_out(7 downto 0); |
|
|
end architecture; |
/templates/processor/neorv32_ProcessorTop_UP5KDemo.vhd
0,0 → 1,308
-- ################################################################################################# |
-- # << NEORV32 - Example setup for boards with UP5K devices >> # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
|
entity neorv32_ProcessorTop_UP5KDemo is |
generic ( |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
USER_CODE : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom user code |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
|
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger? |
|
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A : boolean := true; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := true; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := true; -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
|
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
CPU_CNT_WIDTH : natural := 34; -- total width of CPU cycle and instret counters (0..64) |
|
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
|
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64) |
|
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 64*1024; -- size of processor-internal instruction memory in bytes |
|
-- Internal Data memory -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 64*1024; -- size of processor-internal data memory in bytes |
|
-- Internal Cache memory -- |
ICACHE_EN : boolean := false; -- implement instruction cache |
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
|
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)? |
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)? |
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH : natural := 3; -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN : boolean := true -- implement watch dog timer (WDT)? |
); |
port ( |
clk_i : in std_logic; |
rstn_i : in std_logic; |
|
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_i : in std_ulogic_vector(3 downto 0); |
gpio_o : out std_ulogic_vector(3 downto 0); |
|
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart_txd_o : out std_ulogic; -- UART0 send data |
uart_rxd_i : in std_ulogic := '0'; -- UART0 receive data |
uart_rts_o : out std_ulogic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart_cts_i : in std_ulogic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
|
-- SPI to on-board flash -- |
flash_sck_o : out std_ulogic; |
flash_sdo_o : out std_ulogic; |
flash_sdi_i : in std_ulogic; |
flash_csn_o : out std_ulogic; -- NEORV32.SPI_CS(0) |
|
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o : out std_ulogic; |
spi_sdo_o : out std_ulogic; |
spi_sdi_i : in std_ulogic; |
spi_csn_o : out std_ulogic; -- NEORV32.SPI_CS(1) |
|
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io : inout std_logic; |
twi_scl_io : inout std_logic; |
|
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o : out std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0) |
); |
end entity; |
|
architecture neorv32_ProcessorTop_UP5KDemo_rtl of neorv32_ProcessorTop_UP5KDemo is |
|
-- internal IO connection -- |
signal con_gpio_o : std_ulogic_vector(63 downto 0); |
signal con_gpio_i : std_ulogic_vector(63 downto 0); |
signal con_spi_sck : std_ulogic; |
signal con_spi_sdi : std_ulogic; |
signal con_spi_sdo : std_ulogic; |
signal con_spi_csn : std_ulogic_vector(07 downto 0); |
|
begin |
|
-- IO Connection -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
|
-- SPI: on-board flash -- |
flash_sck_o <= con_spi_sck; |
flash_sdo_o <= con_spi_sdo; |
flash_csn_o <= con_spi_csn(0); |
|
-- SPI: user port -- |
spi_sck_o <= con_spi_sck; |
spi_sdo_o <= con_spi_sdo; |
spi_csn_o <= con_spi_csn(1); |
con_spi_sdi <= spi_sdi_i; |
|
-- GPIO -- |
gpio_o <= con_gpio_o(3 downto 0); |
con_gpio_i(03 downto 0) <= gpio_i; |
con_gpio_i(63 downto 4) <= (others => '0'); |
|
-- The core of the problem ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_inst: entity neorv32.neorv32_top |
generic map ( |
-- General -- |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN => true, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE => USER_CODE, -- custom user code |
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (32-bit) |
|
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger? |
|
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension? |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement mul/div extension? |
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT regs!) |
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.? |
|
-- Extension Options -- |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations |
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64) |
|
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64) |
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
|
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (1..64) |
|
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
|
-- Internal Data memory -- |
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes |
|
-- Internal Cache memory -- |
ICACHE_EN => ICACHE_EN, -- implement instruction cache |
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
|
-- External memory interface -- |
MEM_EXT_EN => false, -- implement external memory bus interface? |
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled) |
|
-- Processor peripherals -- |
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)? |
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN => false, -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)? |
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)? |
IO_TRNG_EN => false, -- implement true random number generator (TRNG)? |
IO_CFS_EN => false, -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG => x"00000000", -- custom CFS configuration generic |
IO_CFS_IN_SIZE => 32, -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE => 32, -- size of CFS output conduit in bits |
IO_NEOLED_EN => false -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
) |
port map ( |
-- Global control -- |
clk_i => clk_i, -- global clock, rising edge |
rstn_i => rstn_i, -- global reset, low-active, async |
|
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i => '0', -- low-active TAP reset (optional) |
jtag_tck_i => '0', -- serial clock |
jtag_tdi_i => '0', -- serial data input |
jtag_tdo_o => open, -- serial data output |
jtag_tms_i => '0', -- mode select |
|
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o => open, -- request tag |
wb_adr_o => open, -- address |
wb_dat_i => (others => '0'), -- read data |
wb_dat_o => open, -- write data |
wb_we_o => open, -- read/write |
wb_sel_o => open, -- byte enable |
wb_stb_o => open, -- strobe |
wb_cyc_o => open, -- valid cycle |
wb_lock_o => open, -- exclusive access request |
wb_ack_i => '0', -- transfer acknowledge |
wb_err_i => '0', -- transfer error |
|
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o => open, -- indicates an executed FENCE operation |
fencei_o => open, -- indicates an executed FENCEI operation |
|
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o => con_gpio_o, -- parallel output |
gpio_i => con_gpio_i, -- parallel input |
|
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o => uart_txd_o, -- UART0 send data |
uart0_rxd_i => uart_rxd_i, -- UART0 receive data |
uart0_rts_o => uart_rts_o, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i => uart_cts_i, -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
|
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o => open, -- UART1 send data |
uart1_rxd_i => '0', -- UART1 receive data |
uart1_rts_o => open, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i => '0', -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
|
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o => con_spi_sck, -- SPI serial clock |
spi_sdo_o => con_spi_sdo, -- controller data out, peripheral data in |
spi_sdi_i => con_spi_sdi, -- controller data in, peripheral data out |
spi_csn_o => con_spi_csn, -- SPI CS |
|
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io => twi_sda_io, -- twi serial data line |
twi_scl_io => twi_scl_io, -- twi serial clock line |
|
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o => pwm_o, -- pwm channels |
|
-- Custom Functions Subsystem IO -- |
cfs_in_i => (others => '0'), -- custom CFS inputs conduit |
cfs_out_o => open, -- custom CFS outputs conduit |
|
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o => open, -- async serial data line |
|
-- System time -- |
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true) |
|
-- Interrupts -- |
nm_irq_i => '0', -- non-maskable interrupt |
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i => '0', -- machine software interrupt |
mext_irq_i => '0' -- machine external interrupt |
); |
|
end architecture; |
/templates/processor/neorv32_ProcessorTop_stdlogic.vhd
0,0 → 1,466
-- ################################################################################################# |
-- # << NEORV32 - Processor Top Entity with Resolved Port Signals (std_logic/std_logic_vector) >> # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
entity neorv32_ProcessorTop_stdlogic is |
generic ( |
-- General -- |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE : std_logic_vector(31 downto 0) := x"00000000"; -- custom user code |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64) |
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes |
-- Internal Data memory -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes |
-- Internal Cache memory -- |
ICACHE_EN : boolean := false; -- implement instruction cache |
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
-- External memory interface -- |
MEM_EXT_EN : boolean := false; -- implement external memory bus interface? |
MEM_EXT_TIMEOUT : natural := 255; -- cycles after a pending bus access auto-terminates (0 = disabled) |
-- Stream link interface -- |
SLINK_NUM_TX : natural := 0; -- number of TX links (0..8) |
SLINK_NUM_RX : natural := 0; -- number of TX links (0..8) |
SLINK_TX_FIFO : natural := 1; -- TX fifo depth, has to be a power of two |
SLINK_RX_FIFO : natural := 1; -- RX fifo depth, has to be a power of two |
-- External Interrupts Controller (XIRQ) -- |
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE : std_logic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY : std_logic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)? |
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)? |
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)? |
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)? |
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG : std_ulogic_vector(31 downto 0); -- custom CFS configuration generic |
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits |
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
); |
port ( |
-- Global control -- |
clk_i : in std_logic := '0'; -- global clock, rising edge |
rstn_i : in std_logic := '0'; -- global reset, low-active, async |
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i : in std_logic := '0'; -- low-active TAP reset (optional) |
jtag_tck_i : in std_logic := '0'; -- serial clock |
jtag_tdi_i : in std_logic := '0'; -- serial data input |
jtag_tdo_o : out std_logic; -- serial data output |
jtag_tms_i : in std_logic := '0'; -- mode select |
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o : out std_logic_vector(02 downto 0); -- tag |
wb_adr_o : out std_logic_vector(31 downto 0); -- address |
wb_dat_i : in std_logic_vector(31 downto 0) := (others => '0'); -- read data |
wb_dat_o : out std_logic_vector(31 downto 0); -- write data |
wb_we_o : out std_logic; -- read/write |
wb_sel_o : out std_logic_vector(03 downto 0); -- byte enable |
wb_stb_o : out std_logic; -- strobe |
wb_cyc_o : out std_logic; -- valid cycle |
wb_lock_o : out std_logic; -- exclusive access request |
wb_ack_i : in std_logic := '0'; -- transfer acknowledge |
wb_err_i : in std_logic := '0'; -- transfer error |
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o : out std_logic; -- indicates an executed FENCE operation |
fencei_o : out std_logic; -- indicates an executed FENCEI operation |
-- TX stream interfaces (available if SLINK_NUM_TX > 0) -- |
slink_tx_dat_o : out sdata_8x32r_t; -- output data |
slink_tx_val_o : out std_logic_vector(7 downto 0); -- valid output |
slink_tx_rdy_i : in std_logic_vector(7 downto 0) := (others => '0'); -- ready to send |
-- RX stream interfaces (available if SLINK_NUM_RX > 0) -- |
slink_rx_dat_i : in sdata_8x32r_t := (others => (others => '0')); -- input data |
slink_rx_val_i : in std_logic_vector(7 downto 0) := (others => '0'); -- valid input |
slink_rx_rdy_o : out std_logic_vector(7 downto 0); -- ready to receive |
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o : out std_logic_vector(63 downto 0); -- parallel output |
gpio_i : in std_logic_vector(63 downto 0) := (others => '0'); -- parallel input |
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o : out std_logic; -- UART0 send data |
uart0_rxd_i : in std_logic := '0'; -- UART0 receive data |
uart0_rts_o : out std_logic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i : in std_logic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o : out std_logic; -- UART1 send data |
uart1_rxd_i : in std_logic := '0'; -- UART1 receive data |
uart1_rts_o : out std_logic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i : in std_logic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o : out std_logic; -- SPI serial clock |
spi_sdo_o : out std_logic; -- controller data out, peripheral data in |
spi_sdi_i : in std_logic := '0'; -- controller data in, peripheral data out |
spi_csn_o : out std_logic_vector(07 downto 0); -- SPI CS |
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io : inout std_logic; -- twi serial data line |
twi_scl_io : inout std_logic; -- twi serial clock line |
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o : out std_logic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels |
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) -- |
cfs_in_i : in std_logic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom inputs |
cfs_out_o : out std_logic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom outputs |
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o : out std_logic; -- async serial data line |
-- System time -- |
mtime_i : in std_logic_vector(63 downto 0) := (others => '0'); -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o : out std_logic_vector(63 downto 0); -- current system time from int. MTIME (if IO_MTIME_EN = true) |
-- External platform interrupts (available if XIRQ_NUM_CH > 0) -- |
xirq_i : in std_logic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels |
-- CPU Interrupts -- |
nm_irq_i : in std_logic := '0'; -- non-maskable interrupt |
mtime_irq_i : in std_logic := '0'; -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i : in std_logic := '0'; -- machine software interrupt |
mext_irq_i : in std_logic := '0' -- machine external interrupt |
); |
end entity; |
|
architecture neorv32_ProcessorTop_stdlogic_rtl of neorv32_ProcessorTop_stdlogic is |
|
-- type conversion -- |
constant USER_CODE_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(USER_CODE); |
constant IO_CFS_CONFIG_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(IO_CFS_CONFIG); |
constant XIRQ_TRIGGER_TYPE_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_TYPE); |
constant XIRQ_TRIGGER_POLARITY_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_POLARITY); |
-- |
signal clk_i_int : std_ulogic; |
signal rstn_i_int : std_ulogic; |
-- |
signal jtag_trst_i_int :std_ulogic; |
signal jtag_tck_i_int :std_ulogic; |
signal jtag_tdi_i_int :std_ulogic; |
signal jtag_tdo_o_int :std_ulogic; |
signal jtag_tms_i_int :std_ulogic; |
-- |
signal wb_tag_o_int : std_ulogic_vector(02 downto 0); |
signal wb_adr_o_int : std_ulogic_vector(31 downto 0); |
signal wb_dat_i_int : std_ulogic_vector(31 downto 0); |
signal wb_dat_o_int : std_ulogic_vector(31 downto 0); |
signal wb_we_o_int : std_ulogic; |
signal wb_sel_o_int : std_ulogic_vector(03 downto 0); |
signal wb_stb_o_int : std_ulogic; |
signal wb_cyc_o_int : std_ulogic; |
signal wb_lock_o_int : std_ulogic; |
signal wb_ack_i_int : std_ulogic; |
signal wb_err_i_int : std_ulogic; |
-- |
signal fence_o_int : std_ulogic; |
signal fencei_o_int : std_ulogic; |
-- |
signal slink_tx_dat_o_int : sdata_8x32r_t; |
signal slink_tx_val_o_int : std_logic_vector(7 downto 0); |
signal slink_tx_rdy_i_int : std_logic_vector(7 downto 0); |
signal slink_rx_dat_i_int : sdata_8x32r_t; |
signal slink_rx_val_i_int : std_logic_vector(7 downto 0); |
signal slink_rx_rdy_o_int : std_logic_vector(7 downto 0); |
-- |
signal gpio_o_int : std_ulogic_vector(63 downto 0); |
signal gpio_i_int : std_ulogic_vector(63 downto 0); |
-- |
signal uart0_txd_o_int : std_ulogic; |
signal uart0_rxd_i_int : std_ulogic; |
signal uart0_rts_o_int : std_ulogic; |
signal uart0_cts_i_int : std_ulogic; |
-- |
signal uart1_txd_o_int : std_ulogic; |
signal uart1_rxd_i_int : std_ulogic; |
signal uart1_rts_o_int : std_ulogic; |
signal uart1_cts_i_int : std_ulogic; |
-- |
signal spi_sck_o_int : std_ulogic; |
signal spi_sdo_o_int : std_ulogic; |
signal spi_sdi_i_int : std_ulogic; |
signal spi_csn_o_int : std_ulogic_vector(07 downto 0); |
-- |
signal pwm_o_int : std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); |
-- |
signal cfs_in_i_int : std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); |
signal cfs_out_o_int : std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); |
-- |
signal neoled_o_int : std_ulogic; |
-- |
signal mtime_i_int : std_ulogic_vector(63 downto 0); |
signal mtime_o_int : std_ulogic_vector(63 downto 0); |
-- |
signal xirq_i_int : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
-- |
signal nm_irq_i_int : std_ulogic; |
signal mtime_irq_i_int : std_ulogic; |
signal msw_irq_i_int : std_ulogic; |
signal mext_irq_i_int : std_ulogic; |
|
begin |
|
-- The Core Of The Problem ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_top_inst: neorv32_top |
generic map ( |
-- General -- |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE => USER_CODE_INT, -- custom user code |
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (hartid) (32-bit) |
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension? |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.? |
-- Extension Options -- |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations |
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64) |
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (0..64) |
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
-- Internal Data memory -- |
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes |
-- Internal Cache memory -- |
ICACHE_EN => ICACHE_EN, -- implement instruction cache |
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
-- External memory interface -- |
MEM_EXT_EN => MEM_EXT_EN, -- implement external memory bus interface? |
MEM_EXT_TIMEOUT => MEM_EXT_TIMEOUT, -- cycles after a pending bus access auto-terminates (0 = disabled) |
-- Stream link interface -- |
SLINK_NUM_TX => SLINK_NUM_TX, -- number of TX links (0..8) |
SLINK_NUM_RX => SLINK_NUM_RX, -- number of TX links (0..8) |
SLINK_TX_FIFO => SLINK_TX_FIFO, -- TX fifo depth, has to be a power of two |
SLINK_RX_FIFO => SLINK_RX_FIFO, -- RX fifo depth, has to be a power of two |
-- External Interrupts Controller (XIRQ) -- |
XIRQ_NUM_CH => XIRQ_NUM_CH, -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE => XIRQ_TRIGGER_TYPE_INT, -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY => XIRQ_TRIGGER_POLARITY_INT, -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
-- Processor peripherals -- |
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)? |
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN => IO_UART1_EN, -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)? |
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)? |
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)? |
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG => IO_CFS_CONFIG_INT, -- custom CFS configuration generic |
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE => IO_CFS_OUT_SIZE, -- size of CFS output conduit in bits |
IO_NEOLED_EN => IO_NEOLED_EN -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
) |
port map ( |
-- Global control -- |
clk_i => clk_i_int, -- global clock, rising edge |
rstn_i => rstn_i_int, -- global reset, low-active, async |
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i => jtag_trst_i_int, -- low-active TAP reset (optional) |
jtag_tck_i => jtag_tck_i_int, -- serial clock |
jtag_tdi_i => jtag_tdi_i_int, -- serial data input |
jtag_tdo_o => jtag_tdo_o_int, -- serial data output |
jtag_tms_i => jtag_tms_i_int, -- mode select |
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o => wb_tag_o_int, -- tag |
wb_adr_o => wb_adr_o_int, -- address |
wb_dat_i => wb_dat_i_int, -- read data |
wb_dat_o => wb_dat_o_int, -- write data |
wb_we_o => wb_we_o_int, -- read/write |
wb_sel_o => wb_sel_o_int, -- byte enable |
wb_stb_o => wb_stb_o_int, -- strobe |
wb_cyc_o => wb_cyc_o_int, -- valid cycle |
wb_lock_o => wb_lock_o_int, -- exclusive access request |
wb_ack_i => wb_ack_i_int, -- transfer acknowledge |
wb_err_i => wb_err_i_int, -- transfer error |
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o => fence_o_int, -- indicates an executed FENCE operation |
fencei_o => fencei_o_int, -- indicates an executed FENCEI operation |
-- TX stream interfaces (available if SLINK_NUM_TX > 0) -- |
slink_tx_dat_o => slink_tx_dat_o_int, -- output data |
slink_tx_val_o => slink_tx_val_o_int, -- valid output |
slink_tx_rdy_i => slink_tx_rdy_i_int, -- ready to send |
-- RX stream interfaces (available if SLINK_NUM_RX > 0) -- |
slink_rx_dat_i => slink_rx_dat_i_int, -- input data |
slink_rx_val_i => slink_rx_val_i_int, -- valid input |
slink_rx_rdy_o => slink_rx_rdy_o_int, -- ready to receive |
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o => gpio_o_int, -- parallel output |
gpio_i => gpio_i_int, -- parallel input |
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o => uart0_txd_o_int, -- UART0 send data |
uart0_rxd_i => uart0_rxd_i_int, -- UART0 receive data |
uart0_rts_o => uart0_rts_o_int, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i => uart0_cts_i_int, -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o => uart1_txd_o_int, -- UART1 send data |
uart1_rxd_i => uart1_rxd_i_int, -- UART1 receive data |
uart1_rts_o => uart1_rts_o_int, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i => uart1_cts_i_int, -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o => spi_sck_o_int, -- SPI serial clock |
spi_sdo_o => spi_sdo_o_int, -- controller data out, peripheral data in |
spi_sdi_i => spi_sdi_i_int, -- controller data in, peripheral data out |
spi_csn_o => spi_csn_o_int, -- SPI CS |
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io => twi_sda_io, -- twi serial data line |
twi_scl_io => twi_scl_io, -- twi serial clock line |
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o => pwm_o_int, -- pwm channels |
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) -- |
cfs_in_i => cfs_in_i_int, -- custom inputs |
cfs_out_o => cfs_out_o_int, -- custom outputs |
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o => neoled_o_int, -- async serial data line |
-- System time -- |
mtime_i => mtime_i_int, -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o => mtime_o_int, -- current system time from int. MTIME (if IO_MTIME_EN = true) |
-- External platform interrupts (available if XIRQ_NUM_CH > 0) -- |
xirq_i => xirq_i_int, -- IRQ channels |
-- CPU Interrupts -- |
nm_irq_i => nm_irq_i_int, -- non-maskable interrupt |
mtime_irq_i => mtime_irq_i_int, -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i => msw_irq_i_int, -- machine software interrupt |
mext_irq_i => mext_irq_i_int -- machine external interrupt |
); |
|
-- type conversion -- |
clk_i_int <= std_ulogic(clk_i); |
rstn_i_int <= std_ulogic(rstn_i); |
|
jtag_trst_i_int <= std_ulogic(jtag_trst_i); |
jtag_tck_i_int <= std_ulogic(jtag_tck_i); |
jtag_tdi_i_int <= std_ulogic(jtag_tdi_i); |
jtag_tdo_o <= std_logic(jtag_tdo_o_int); |
jtag_tms_i_int <= std_ulogic(jtag_tms_i); |
|
wb_tag_o <= std_logic_vector(wb_tag_o_int); |
wb_adr_o <= std_logic_vector(wb_adr_o_int); |
wb_dat_i_int <= std_ulogic_vector(wb_dat_i); |
wb_dat_o <= std_logic_vector(wb_dat_o_int); |
wb_we_o <= std_logic(wb_we_o_int); |
wb_sel_o <= std_logic_vector(wb_sel_o_int); |
wb_stb_o <= std_logic(wb_stb_o_int); |
wb_cyc_o <= std_logic(wb_cyc_o_int); |
wb_lock_o <= std_logic(wb_lock_o_int); |
wb_ack_i_int <= std_ulogic(wb_ack_i); |
wb_err_i_int <= std_ulogic(wb_err_i); |
|
fence_o <= std_logic(fence_o_int); |
fencei_o <= std_logic(fencei_o_int); |
|
slink_tx_val_o <= std_logic_vector(slink_tx_val_o_int); |
slink_tx_rdy_i_int <= std_ulogic_vector(slink_tx_rdy_i); |
slink_rx_val_i_int <= std_ulogic_vector(slink_rx_val_i); |
slink_rx_rdy_o <= std_logic_vector(slink_rx_rdy_o_int); |
|
slink_conv: |
for i in 0 to 7 generate |
slink_tx_dat_o(i) <= std_logic_vector(slink_tx_dat_o_int(i)); |
slink_rx_dat_i_int(i) <= std_ulogic_vector(slink_rx_dat_i(i)); |
end generate; |
|
gpio_o <= std_logic_vector(gpio_o_int); |
gpio_i_int <= std_ulogic_vector(gpio_i); |
|
uart0_txd_o <= std_logic(uart0_txd_o_int); |
uart0_rxd_i_int <= std_ulogic(uart0_rxd_i); |
uart1_txd_o <= std_logic(uart1_txd_o_int); |
uart1_rxd_i_int <= std_ulogic(uart1_rxd_i); |
|
spi_sck_o <= std_logic(spi_sck_o_int); |
spi_sdo_o <= std_logic(spi_sdo_o_int); |
spi_sdi_i_int <= std_ulogic(spi_sdi_i); |
spi_csn_o <= std_logic_vector(spi_csn_o_int); |
|
pwm_o <= std_logic_vector(pwm_o_int); |
|
cfs_in_i_int <= std_ulogic_vector(cfs_in_i); |
cfs_out_o <= std_logic_vector(cfs_out_o_int); |
|
neoled_o <= std_logic(neoled_o_int); |
|
mtime_i_int <= std_ulogic_vector(mtime_i); |
mtime_o <= std_logic_vector(mtime_o_int); |
|
xirq_i_int <= std_ulogic_vector(xirq_i); |
|
msw_irq_i_int <= std_ulogic(msw_irq_i); |
mext_irq_i_int <= std_ulogic(mext_irq_i); |
|
|
end architecture; |
/templates/system/neorv32_SystemTop_axi4lite.vhd
0,0 → 1,511
-- ################################################################################################# |
-- # << NEORV32 - Processor Top Entity with AXI4-Lite Compatible Master Interface >> # |
-- # ********************************************************************************************* # |
-- # (c) "AXI", "AXI4" and "AXI4-Lite" are trademarks of Arm Holdings plc. # |
-- # Note: External MTIME is not supported. # |
-- # ********************************************************************************************* # |
-- # BSD 3-Clause License # |
-- # # |
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. # |
-- # # |
-- # Redistribution and use in source and binary forms, with or without modification, are # |
-- # permitted provided that the following conditions are met: # |
-- # # |
-- # 1. Redistributions of source code must retain the above copyright notice, this list of # |
-- # conditions and the following disclaimer. # |
-- # # |
-- # 2. Redistributions in binary form must reproduce the above copyright notice, this list of # |
-- # conditions and the following disclaimer in the documentation and/or other materials # |
-- # provided with the distribution. # |
-- # # |
-- # 3. Neither the name of the copyright holder nor the names of its contributors may be used to # |
-- # endorse or promote products derived from this software without specific prior written # |
-- # permission. # |
-- # # |
-- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS # |
-- # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # |
-- # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # |
-- # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # |
-- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE # |
-- # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # |
-- # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # |
-- # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # |
-- # OF THE POSSIBILITY OF SUCH DAMAGE. # |
-- # ********************************************************************************************* # |
-- # The NEORV32 Processor - https://github.com/stnolting/neorv32 (c) Stephan Nolting # |
-- ################################################################################################# |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
library neorv32; |
use neorv32.neorv32_package.all; |
|
entity neorv32_SystemTop_axi4lite is |
generic ( |
-- ------------------------------------------------------------ |
-- Configuration Generics -- |
-- ------------------------------------------------------------ |
-- General -- |
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN : boolean := true; -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE : std_logic_vector(31 downto 0) := x"00000000"; -- custom user code |
HW_THREAD_ID : natural := 0; -- hardware thread id (32-bit) |
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN : boolean := false; -- implement on-chip debugger |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A : boolean := false; -- implement atomic extension? |
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension? |
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M : boolean := false; -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U : boolean := false; -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx : boolean := false; -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr : boolean := true; -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei : boolean := false; -- implement instruction stream sync.? |
-- Extension Options -- |
FAST_MUL_EN : boolean := false; -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN : boolean := false; -- use barrel shifter for shift operations |
CPU_CNT_WIDTH : natural := 64; -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS : natural := 0; -- number of regions (0..64) |
PMP_MIN_GRANULARITY : natural := 64*1024; -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS : natural := 0; -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH : natural := 40; -- total size of HPM counters (0..64) |
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN : boolean := true; -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE : natural := 16*1024; -- size of processor-internal instruction memory in bytes |
-- Internal Data memory -- |
MEM_INT_DMEM_EN : boolean := true; -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE : natural := 8*1024; -- size of processor-internal data memory in bytes |
-- Internal Cache memory -- |
ICACHE_EN : boolean := false; -- implement instruction cache |
ICACHE_NUM_BLOCKS : natural := 4; -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE : natural := 64; -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY : natural := 1; -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
-- External Interrupts Controller (XIRQ) -- |
XIRQ_NUM_CH : natural := 0; -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE : std_logic_vector(31 downto 0) := (others => '1'); -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY : std_logic_vector(31 downto 0) := (others => '1'); -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
-- Processor peripherals -- |
IO_GPIO_EN : boolean := true; -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN : boolean := true; -- implement machine system timer (MTIME)? |
IO_UART0_EN : boolean := true; -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN : boolean := true; -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN : boolean := true; -- implement serial peripheral interface (SPI)? |
IO_TWI_EN : boolean := true; -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH : natural := 4; -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN : boolean := true; -- implement watch dog timer (WDT)? |
IO_TRNG_EN : boolean := false; -- implement true random number generator (TRNG)? |
IO_CFS_EN : boolean := false; -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG : std_logic_vector(31 downto 0); -- custom CFS configuration generic |
IO_CFS_IN_SIZE : positive := 32; -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE : positive := 32; -- size of CFS output conduit in bits |
IO_NEOLED_EN : boolean := true -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
); |
port ( |
-- ------------------------------------------------------------ |
-- AXI4-Lite-Compatible Master Interface -- |
-- ------------------------------------------------------------ |
-- Clock and Reset -- |
m_axi_aclk : in std_logic; |
m_axi_aresetn : in std_logic; |
-- Write Address Channel -- |
m_axi_awaddr : out std_logic_vector(31 downto 0); |
m_axi_awprot : out std_logic_vector(2 downto 0); |
m_axi_awvalid : out std_logic; |
m_axi_awready : in std_logic; |
-- Write Data Channel -- |
m_axi_wdata : out std_logic_vector(31 downto 0); |
m_axi_wstrb : out std_logic_vector(3 downto 0); |
m_axi_wvalid : out std_logic; |
m_axi_wready : in std_logic; |
-- Read Address Channel -- |
m_axi_araddr : out std_logic_vector(31 downto 0); |
m_axi_arprot : out std_logic_vector(2 downto 0); |
m_axi_arvalid : out std_logic; |
m_axi_arready : in std_logic; |
-- Read Data Channel -- |
m_axi_rdata : in std_logic_vector(31 downto 0); |
m_axi_rresp : in std_logic_vector(1 downto 0); |
m_axi_rvalid : in std_logic; |
m_axi_rready : out std_logic; |
-- Write Response Channel -- |
m_axi_bresp : in std_logic_vector(1 downto 0); |
m_axi_bvalid : in std_logic; |
m_axi_bready : out std_logic; |
-- ------------------------------------------------------------ |
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
-- ------------------------------------------------------------ |
jtag_trst_i : in std_logic := '0'; -- low-active TAP reset (optional) |
jtag_tck_i : in std_logic := '0'; -- serial clock |
jtag_tdi_i : in std_logic := '0'; -- serial data input |
jtag_tdo_o : out std_logic; -- serial data output |
jtag_tms_i : in std_logic := '0'; -- mode select |
-- ------------------------------------------------------------ |
-- Processor IO -- |
-- ------------------------------------------------------------ |
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o : out std_logic_vector(63 downto 0); -- parallel output |
gpio_i : in std_logic_vector(63 downto 0) := (others => '0'); -- parallel input |
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o : out std_logic; -- UART0 send data |
uart0_rxd_i : in std_logic := '0'; -- UART0 receive data |
uart0_rts_o : out std_logic; -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i : in std_logic := '0'; -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o : out std_logic; -- UART1 send data |
uart1_rxd_i : in std_logic := '0'; -- UART1 receive data |
uart1_rts_o : out std_logic; -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i : in std_logic := '0'; -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o : out std_logic; -- SPI serial clock |
spi_sdo_o : out std_logic; -- controller data out, peripheral data in |
spi_sdi_i : in std_logic := '0'; -- controller data in, peripheral data out |
spi_csn_o : out std_logic_vector(07 downto 0); -- SPI CS |
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io : inout std_logic; -- twi serial data line |
twi_scl_io : inout std_logic; -- twi serial clock line |
-- PWM (available if IO_PWM_NUM_CH > 0) -- |
pwm_o : out std_logic_vector(IO_PWM_NUM_CH-1 downto 0); -- pwm channels |
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) -- |
cfs_in_i : in std_logic_vector(IO_CFS_IN_SIZE-1 downto 0); -- custom inputs |
cfs_out_o : out std_logic_vector(IO_CFS_OUT_SIZE-1 downto 0); -- custom outputs |
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o : out std_logic; -- async serial data line |
-- External platform interrupts (available if XIRQ_NUM_CH > 0) -- |
xirq_i : in std_logic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0'); -- IRQ channels |
-- CPU Interrupts -- |
nm_irq_i : in std_logic := '0'; -- non-maskable interrupt |
msw_irq_i : in std_logic := '0'; -- machine software interrupt |
mext_irq_i : in std_logic := '0' -- machine external interrupt |
); |
end entity; |
|
architecture neorv32_SystemTop_axi4lite_rtl of neorv32_SystemTop_axi4lite is |
|
-- type conversion -- |
constant USER_CODE_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(USER_CODE); |
constant IO_CFS_CONFIG_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(IO_CFS_CONFIG); |
constant XIRQ_TRIGGER_TYPE_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_TYPE); |
constant XIRQ_TRIGGER_POLARITY_INT : std_ulogic_vector(31 downto 0) := std_ulogic_vector(XIRQ_TRIGGER_POLARITY); |
-- |
signal clk_i_int : std_ulogic; |
signal rstn_i_int : std_ulogic; |
-- |
signal jtag_trst_i_int :std_ulogic; |
signal jtag_tck_i_int :std_ulogic; |
signal jtag_tdi_i_int :std_ulogic; |
signal jtag_tdo_o_int :std_ulogic; |
signal jtag_tms_i_int :std_ulogic; |
-- |
signal gpio_o_int : std_ulogic_vector(63 downto 0); |
signal gpio_i_int : std_ulogic_vector(63 downto 0); |
-- |
signal uart0_txd_o_int : std_ulogic; |
signal uart0_rxd_i_int : std_ulogic; |
signal uart0_rts_o_int : std_ulogic; |
signal uart0_cts_i_int : std_ulogic; |
-- |
signal uart1_txd_o_int : std_ulogic; |
signal uart1_rxd_i_int : std_ulogic; |
signal uart1_rts_o_int : std_ulogic; |
signal uart1_cts_i_int : std_ulogic; |
-- |
signal spi_sck_o_int : std_ulogic; |
signal spi_sdo_o_int : std_ulogic; |
signal spi_sdi_i_int : std_ulogic; |
signal spi_csn_o_int : std_ulogic_vector(07 downto 0); |
-- |
signal pwm_o_int : std_ulogic_vector(IO_PWM_NUM_CH-1 downto 0); |
-- |
signal cfs_in_i_int : std_ulogic_vector(IO_CFS_IN_SIZE-1 downto 0); |
signal cfs_out_o_int : std_ulogic_vector(IO_CFS_OUT_SIZE-1 downto 0); |
-- |
signal neoled_o_int : std_ulogic; |
-- |
signal xirq_i_int : std_ulogic_vector(XIRQ_NUM_CH-1 downto 0); |
-- |
signal nm_irq_i_int : std_ulogic; |
signal msw_irq_i_int : std_ulogic; |
signal mext_irq_i_int : std_ulogic; |
|
-- internal wishbone bus -- |
type wb_bus_t is record |
adr : std_ulogic_vector(31 downto 0); -- address |
di : std_ulogic_vector(31 downto 0); -- processor input data |
do : std_ulogic_vector(31 downto 0); -- processor output data |
we : std_ulogic; -- write enable |
sel : std_ulogic_vector(03 downto 0); -- byte enable |
stb : std_ulogic; -- strobe |
cyc : std_ulogic; -- valid cycle |
ack : std_ulogic; -- transfer acknowledge |
err : std_ulogic; -- transfer error |
tag : std_ulogic_vector(02 downto 0); -- tag |
lock : std_ulogic; -- exclusive access request |
end record; |
signal wb_core : wb_bus_t; |
|
-- AXI bridge control -- |
type ctrl_t is record |
radr_received : std_ulogic; |
wadr_received : std_ulogic; |
wdat_received : std_ulogic; |
end record; |
signal ctrl : ctrl_t; |
|
signal ack_read, ack_write : std_ulogic; -- normal transfer termination |
signal err_read, err_write : std_ulogic; -- error transfer termination |
|
begin |
|
-- Sanity Checks -------------------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
assert not (wb_pipe_mode_c = true) report "NEORV32 PROCESSOR CONFIG ERROR: AXI4-Lite bridge requires STANDARD/CLASSIC Wishbone mode (package.wb_pipe_mode_c = false)." severity error; |
assert not (CPU_EXTENSION_RISCV_A = true) report "NEORV32 PROCESSOR CONFIG WARNING: AXI4-Lite provides NO support for atomic memory operations. LR/SC access via AXI will raise a bus exception." severity warning; |
|
|
-- The Core Of The Problem ---------------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
neorv32_top_inst: neorv32_top |
generic map ( |
-- General -- |
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz |
INT_BOOTLOADER_EN => INT_BOOTLOADER_EN, -- boot configuration: true = boot explicit bootloader; false = boot from int/ext (I)MEM |
USER_CODE => USER_CODE_INT, -- custom user code |
HW_THREAD_ID => HW_THREAD_ID, -- hardware thread id (hartid) |
-- On-Chip Debugger (OCD) -- |
ON_CHIP_DEBUGGER_EN => ON_CHIP_DEBUGGER_EN, -- implement on-chip debugger |
-- RISC-V CPU Extensions -- |
CPU_EXTENSION_RISCV_A => CPU_EXTENSION_RISCV_A, -- implement atomic extension? |
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension? |
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension? |
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M, -- implement muld/div extension? |
CPU_EXTENSION_RISCV_U => CPU_EXTENSION_RISCV_U, -- implement user mode extension? |
CPU_EXTENSION_RISCV_Zfinx => CPU_EXTENSION_RISCV_Zfinx, -- implement 32-bit floating-point extension (using INT reg!) |
CPU_EXTENSION_RISCV_Zicsr => CPU_EXTENSION_RISCV_Zicsr, -- implement CSR system? |
CPU_EXTENSION_RISCV_Zifencei => CPU_EXTENSION_RISCV_Zifencei, -- implement instruction stream sync.? |
-- Extension Options -- |
FAST_MUL_EN => FAST_MUL_EN, -- use DSPs for M extension's multiplier |
FAST_SHIFT_EN => FAST_SHIFT_EN, -- use barrel shifter for shift operations |
CPU_CNT_WIDTH => CPU_CNT_WIDTH, -- total width of CPU cycle and instret counters (0..64) |
-- Physical Memory Protection (PMP) -- |
PMP_NUM_REGIONS => PMP_NUM_REGIONS, -- number of regions (0..64) |
PMP_MIN_GRANULARITY => PMP_MIN_GRANULARITY, -- minimal region granularity in bytes, has to be a power of 2, min 8 bytes |
-- Hardware Performance Monitors (HPM) -- |
HPM_NUM_CNTS => HPM_NUM_CNTS, -- number of implemented HPM counters (0..29) |
HPM_CNT_WIDTH => HPM_CNT_WIDTH, -- total size of HPM counters (0..64) |
-- Internal Instruction memory -- |
MEM_INT_IMEM_EN => MEM_INT_IMEM_EN, -- implement processor-internal instruction memory |
MEM_INT_IMEM_SIZE => MEM_INT_IMEM_SIZE, -- size of processor-internal instruction memory in bytes |
-- Internal Data memory -- |
MEM_INT_DMEM_EN => MEM_INT_DMEM_EN, -- implement processor-internal data memory |
MEM_INT_DMEM_SIZE => MEM_INT_DMEM_SIZE, -- size of processor-internal data memory in bytes |
-- Internal Cache memory -- |
ICACHE_EN => ICACHE_EN, -- implement instruction cache |
ICACHE_NUM_BLOCKS => ICACHE_NUM_BLOCKS, -- i-cache: number of blocks (min 1), has to be a power of 2 |
ICACHE_BLOCK_SIZE => ICACHE_BLOCK_SIZE, -- i-cache: block size in bytes (min 4), has to be a power of 2 |
ICACHE_ASSOCIATIVITY => ICACHE_ASSOCIATIVITY, -- i-cache: associativity / number of sets (1=direct_mapped), has to be a power of 2 |
-- External memory interface -- |
MEM_EXT_EN => true, -- implement external memory bus interface? |
MEM_EXT_TIMEOUT => 0, -- cycles after a pending bus access auto-terminates (0 = disabled) |
-- External Interrupts Controller (XIRQ) -- |
XIRQ_NUM_CH => XIRQ_NUM_CH, -- number of external IRQ channels (0..32) |
XIRQ_TRIGGER_TYPE => XIRQ_TRIGGER_TYPE_INT, -- trigger type: 0=level, 1=edge |
XIRQ_TRIGGER_POLARITY => XIRQ_TRIGGER_POLARITY_INT, -- trigger polarity: 0=low-level/falling-edge, 1=high-level/rising-edge |
-- Processor peripherals -- |
IO_GPIO_EN => IO_GPIO_EN, -- implement general purpose input/output port unit (GPIO)? |
IO_MTIME_EN => IO_MTIME_EN, -- implement machine system timer (MTIME)? |
IO_UART0_EN => IO_UART0_EN, -- implement primary universal asynchronous receiver/transmitter (UART0)? |
IO_UART1_EN => IO_UART1_EN, -- implement secondary universal asynchronous receiver/transmitter (UART1)? |
IO_SPI_EN => IO_SPI_EN, -- implement serial peripheral interface (SPI)? |
IO_TWI_EN => IO_TWI_EN, -- implement two-wire interface (TWI)? |
IO_PWM_NUM_CH => IO_PWM_NUM_CH, -- number of PWM channels to implement (0..60); 0 = disabled |
IO_WDT_EN => IO_WDT_EN, -- implement watch dog timer (WDT)? |
IO_TRNG_EN => IO_TRNG_EN, -- implement true random number generator (TRNG)? |
IO_CFS_EN => IO_CFS_EN, -- implement custom functions subsystem (CFS)? |
IO_CFS_CONFIG => IO_CFS_CONFIG_INT, -- custom CFS configuration generic |
IO_CFS_IN_SIZE => IO_CFS_IN_SIZE, -- size of CFS input conduit in bits |
IO_CFS_OUT_SIZE => IO_CFS_OUT_SIZE, -- size of CFS output conduit in bits |
IO_NEOLED_EN => IO_NEOLED_EN -- implement NeoPixel-compatible smart LED interface (NEOLED)? |
) |
port map ( |
-- Global control -- |
clk_i => clk_i_int, -- global clock, rising edge |
rstn_i => rstn_i_int, -- global reset, low-active, async |
-- JTAG on-chip debugger interface (available if ON_CHIP_DEBUGGER_EN = true) -- |
jtag_trst_i => jtag_trst_i_int, -- low-active TAP reset (optional) |
jtag_tck_i => jtag_tck_i_int, -- serial clock |
jtag_tdi_i => jtag_tdi_i_int, -- serial data input |
jtag_tdo_o => jtag_tdo_o_int, -- serial data output |
jtag_tms_i => jtag_tms_i_int, -- mode select |
-- Wishbone bus interface (available if MEM_EXT_EN = true) -- |
wb_tag_o => wb_core.tag, -- tag |
wb_adr_o => wb_core.adr, -- address |
wb_dat_i => wb_core.di, -- read data |
wb_dat_o => wb_core.do, -- write data |
wb_we_o => wb_core.we, -- read/write |
wb_sel_o => wb_core.sel, -- byte enable |
wb_stb_o => wb_core.stb, -- strobe |
wb_cyc_o => wb_core.cyc, -- valid cycle |
wb_lock_o => wb_core.lock, -- exclusive access request |
wb_ack_i => wb_core.ack, -- transfer acknowledge |
wb_err_i => wb_core.err, -- transfer error |
-- Advanced memory control signals (available if MEM_EXT_EN = true) -- |
fence_o => open, -- indicates an executed FENCE operation |
fencei_o => open, -- indicates an executed FENCEI operation |
-- GPIO (available if IO_GPIO_EN = true) -- |
gpio_o => gpio_o_int, -- parallel output |
gpio_i => gpio_i_int, -- parallel input |
-- primary UART0 (available if IO_UART0_EN = true) -- |
uart0_txd_o => uart0_txd_o_int, -- UART0 send data |
uart0_rxd_i => uart0_rxd_i_int, -- UART0 receive data |
uart0_rts_o => uart0_rts_o_int, -- hw flow control: UART0.RX ready to receive ("RTR"), low-active, optional |
uart0_cts_i => uart0_cts_i_int, -- hw flow control: UART0.TX allowed to transmit, low-active, optional |
-- secondary UART1 (available if IO_UART1_EN = true) -- |
uart1_txd_o => uart1_txd_o_int, -- UART1 send data |
uart1_rxd_i => uart1_rxd_i_int, -- UART1 receive data |
uart1_rts_o => uart1_rts_o_int, -- hw flow control: UART1.RX ready to receive ("RTR"), low-active, optional |
uart1_cts_i => uart1_cts_i_int, -- hw flow control: UART1.TX allowed to transmit, low-active, optional |
-- SPI (available if IO_SPI_EN = true) -- |
spi_sck_o => spi_sck_o_int, -- SPI serial clock |
spi_sdo_o => spi_sdo_o_int, -- controller data out, peripheral data in |
spi_sdi_i => spi_sdi_i_int, -- controller data in, peripheral data out |
spi_csn_o => spi_csn_o_int, -- SPI CS |
-- TWI (available if IO_TWI_EN = true) -- |
twi_sda_io => twi_sda_io, -- twi serial data line |
twi_scl_io => twi_scl_io, -- twi serial clock line |
-- PWM available if IO_PWM_NUM_CH > 0) -- |
pwm_o => pwm_o_int, -- pwm channels |
-- Custom Functions Subsystem IO (available if IO_CFS_EN = true) -- |
cfs_in_i => cfs_in_i_int, -- custom inputs |
cfs_out_o => cfs_out_o_int, -- custom outputs |
-- NeoPixel-compatible smart LED interface (available if IO_NEOLED_EN = true) -- |
neoled_o => neoled_o_int, -- async serial data line |
-- System time -- |
mtime_i => (others => '0'), -- current system time from ext. MTIME (if IO_MTIME_EN = false) |
mtime_o => open, -- current system time from int. MTIME (if IO_MTIME_EN = true) |
-- External platform interrupts (available if XIRQ_NUM_CH > 0) -- |
xirq_i => xirq_i_int, -- IRQ channels |
-- CPU Interrupts -- |
nm_irq_i => nm_irq_i_int, -- non-maskable interrupt |
mtime_irq_i => '0', -- machine timer interrupt, available if IO_MTIME_EN = false |
msw_irq_i => msw_irq_i_int, -- machine software interrupt |
mext_irq_i => mext_irq_i_int -- machine external interrupt |
); |
|
-- type conversion -- |
gpio_o <= std_logic_vector(gpio_o_int); |
gpio_i_int <= std_ulogic_vector(gpio_i); |
|
jtag_trst_i_int <= std_ulogic(jtag_trst_i); |
jtag_tck_i_int <= std_ulogic(jtag_tck_i); |
jtag_tdi_i_int <= std_ulogic(jtag_tdi_i); |
jtag_tdo_o <= std_logic(jtag_tdo_o_int); |
jtag_tms_i_int <= std_ulogic(jtag_tms_i); |
|
uart0_txd_o <= std_logic(uart0_txd_o_int); |
uart0_rxd_i_int <= std_ulogic(uart0_rxd_i); |
uart1_txd_o <= std_logic(uart0_txd_o_int); |
uart1_rxd_i_int <= std_ulogic(uart0_rxd_i); |
|
spi_sck_o <= std_logic(spi_sck_o_int); |
spi_sdo_o <= std_logic(spi_sdo_o_int); |
spi_sdi_i_int <= std_ulogic(spi_sdi_i); |
spi_csn_o <= std_logic_vector(spi_csn_o_int); |
|
pwm_o <= std_logic_vector(pwm_o_int); |
|
cfs_in_i_int <= std_ulogic_vector(cfs_in_i); |
cfs_out_o <= std_logic_vector(cfs_out_o_int); |
|
neoled_o <= std_logic(neoled_o_int); |
|
mext_irq_i_int <= std_ulogic(mext_irq_i); |
|
|
-- Wishbone to AXI4-Lite Bridge ----------------------------------------------------------- |
-- ------------------------------------------------------------------------------------------- |
|
-- access arbiter -- |
axi_access_arbiter: process(rstn_i_int, clk_i_int) |
begin |
if (rstn_i_int = '0') then |
ctrl.radr_received <= '0'; |
ctrl.wadr_received <= '0'; |
ctrl.wdat_received <= '0'; |
elsif rising_edge(clk_i_int) then |
if (wb_core.cyc = '0') then -- idle |
ctrl.radr_received <= '0'; |
ctrl.wadr_received <= '0'; |
ctrl.wdat_received <= '0'; |
else -- busy |
-- "read address received" flag -- |
if (wb_core.we = '0') then -- pending READ |
if (m_axi_arready = '1') then -- read address received by interconnect? |
ctrl.radr_received <= '1'; |
end if; |
end if; |
-- "write address received" flag -- |
if (wb_core.we = '1') then -- pending WRITE |
if (m_axi_awready = '1') then -- write address received by interconnect? |
ctrl.wadr_received <= '1'; |
end if; |
end if; |
-- "write data received" flag -- |
if (wb_core.we = '1') then -- pending WRITE |
if (m_axi_wready = '1') then -- write data received by interconnect? |
ctrl.wdat_received <= '1'; |
end if; |
end if; |
end if; |
end if; |
end process axi_access_arbiter; |
|
|
-- AXI4-Lite Global Signals -- |
clk_i_int <= std_ulogic(m_axi_aclk); |
rstn_i_int <= std_ulogic(m_axi_aresetn); |
|
|
-- AXI4-Lite Read Address Channel -- |
m_axi_araddr <= std_logic_vector(wb_core.adr); |
m_axi_arvalid <= std_logic((wb_core.cyc and (not wb_core.we)) and (not ctrl.radr_received)); |
--m_axi_arprot <= "000"; -- recommended by Xilinx |
m_axi_arprot(0) <= wb_core.tag(0); -- 0:unprivileged access, 1:privileged access |
m_axi_arprot(1) <= wb_core.tag(1); -- 0:secure access, 1:non-secure access |
m_axi_arprot(2) <= wb_core.tag(2); -- 0:data access, 1:instruction access |
|
-- AXI4-Lite Read Data Channel -- |
m_axi_rready <= std_logic(wb_core.cyc and (not wb_core.we)); |
wb_core.di <= std_ulogic_vector(m_axi_rdata); |
ack_read <= std_ulogic(m_axi_rvalid); |
err_read <= '0' when (m_axi_rresp = "00") else '1'; -- read response = ok? check this signal only when m_axi_rvalid = '1' |
|
|
-- AXI4-Lite Write Address Channel -- |
m_axi_awaddr <= std_logic_vector(wb_core.adr); |
m_axi_awvalid <= std_logic((wb_core.cyc and wb_core.we) and (not ctrl.wadr_received)); |
--m_axi_awprot <= "000"; -- recommended by Xilinx |
m_axi_awprot(0) <= wb_core.tag(0); -- 0:unprivileged access, 1:privileged access |
m_axi_awprot(1) <= wb_core.tag(1); -- 0:secure access, 1:non-secure access |
m_axi_awprot(2) <= wb_core.tag(2); -- 0:data access, 1:instruction access |
|
-- AXI4-Lite Write Data Channel -- |
m_axi_wdata <= std_logic_vector(wb_core.do); |
m_axi_wvalid <= std_logic((wb_core.cyc and wb_core.we) and (not ctrl.wdat_received)); |
m_axi_wstrb <= std_logic_vector(wb_core.sel); -- byte-enable |
|
-- AXI4-Lite Write Response Channel -- |
m_axi_bready <= std_logic(wb_core.cyc and wb_core.we); |
ack_write <= std_ulogic(m_axi_bvalid); |
err_write <= '0' when (m_axi_bresp = "00") else '1'; -- write response = ok? check this signal only when m_axi_bvalid = '1' |
|
|
-- Wishbone transfer termination -- |
wb_core.ack <= ack_read or ack_write; |
wb_core.err <= (ack_read and err_read) or (ack_write and err_write) or wb_core.lock; |
|
|
end architecture; |
/templates/README.md
0,0 → 1,36
# Top Templates |
|
The top entity of the NEORV32 processor is `rtl/core/neorv32_top.vhd`. This folder provides additional |
top entities/wrappers that instantiate the processor's top entity to provide a different interface. |
|
If you want to use one of the provided top entities from this folder, *also* add the according file to the project's |
HDL file list and select the according top_template file as top entity or instatiate the top_template within in your design. |
|
## Processor |
|
### [`neorv32_ProcessorTop_Minimal.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Minimal.vhd) |
|
This setup provides the minimal I/O, for testing the smallest possible design on new boards. |
|
### [`neorv32_ProcessorTop_Small.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Small.vhd) |
|
This processor setup provides 64kB of data and instruction memory, an RTOS-capable CPU (privileged architecture) and a set of standard peripherals like UART, TWI and SPI. |
|
### [`neorv32_ProcessorTop_Test.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_Test.vhd) |
|
This entity is intended as "FPGA hello world" example for playing with the NEORV32. It uses only some of the |
provided peripherals and provides a very simple and basic interface - only the clock, reset, UART and a subset |
of the GPIO output port are propagated to the outer world. |
|
### [`neorv32_ProcessorTop_stdlogic.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/processor/neorv32_ProcessorTop_stdlogic.vhd) |
|
Same entity (generics and interface ports) as the default NEORV32 Processor top entity (`rtl/core/neorv32_top.vhd`), |
but with _resolved_ port signals: All ports are of type `std_logic` or `std_logic_vector`, respectively. |
|
## System |
|
### [`neorv32_ProcessorTop_axi4lite.vhd`](https://github.com/stnolting/neorv32/blob/master/rtl/templates/system/neorv32_ProcessorTop_axi4lite) |
|
This setup provides all the peripheal/IO signals of the default processor top entity, but features an **AXI4-Lite**-compatible bus interface |
instead of the default Wishbone b4 interface. The AXI signal naming corresponds to the Xilinx user guide. The Xilinx Vivado IP packer |
is able to automatically detect the AXI interface ports. All ports signals of this top entity are of type `std_logic` or `std_logic_vector`, respectively. |
/README.md
2,10 → 2,10
|
### [`core`](https://github.com/stnolting/neorv32/tree/master/rtl/core) |
|
This folder contains the core VHDL files for the NEORV32 CPU and the NEORV32 Processor. When creating a new synthesis/simulation project make |
sure that all `*.vhd` files from this folder are added to a *new design library* called `neorv32`. |
This folder contains the core VHDL files for the NEORV32 CPU and the NEORV32 Processor. |
When creating a new synthesis/simulation project make sure that all `*.vhd` files from this folder are added to a |
*new design library* called `neorv32`. |
|
### [`top_templates`](https://github.com/stnolting/neorv32/tree/master/rtl/top_templates) |
### [templates`](https://github.com/stnolting/neorv32/tree/master/rtl/templates) |
|
Alternative top entities for the NEORV32 Processor. Actually, these *alternative* top entities are wrappers, which instantiate the *real* top entity of |
processor/CPU and provide a different interface. |
Alternative top entities / wrappers for the NEORV32 Processor. |