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

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/rtl/core
    from Rev 5 to Rev 6
    Reverse comparison

Rev 5 → Rev 6

/neorv32_bootloader_image.vhd
51,13 → 51,13
00000040 => x"01612823",
00000041 => x"01712623",
00000042 => x"01812423",
00000043 => x"4e9000ef",
00000044 => x"4ad000ef",
00000045 => x"415000ef",
00000046 => x"285000ef",
00000047 => x"4c5000ef",
00000048 => x"26d000ef",
00000049 => x"fc101473",
00000043 => x"4fd000ef",
00000044 => x"4c1000ef",
00000045 => x"429000ef",
00000046 => x"299000ef",
00000047 => x"4d9000ef",
00000048 => x"281000ef",
00000049 => x"fc102473",
00000050 => x"026267b7",
00000051 => x"9ff78793",
00000052 => x"00000713",
67,954 → 67,961
00000056 => x"00200513",
00000057 => x"0087f463",
00000058 => x"00400513",
00000059 => x"391000ef",
00000059 => x"3a5000ef",
00000060 => x"00005537",
00000061 => x"00000613",
00000062 => x"00000593",
00000063 => x"b0050513",
00000064 => x"279000ef",
00000065 => x"251000ef",
00000064 => x"28d000ef",
00000065 => x"265000ef",
00000066 => x"00245793",
00000067 => x"00a78533",
00000068 => x"00f537b3",
00000069 => x"00b785b3",
00000070 => x"249000ef",
00000070 => x"25d000ef",
00000071 => x"ffff07b7",
00000072 => x"41478793",
00000072 => x"42878793",
00000073 => x"30579073",
00000074 => x"08000793",
00000075 => x"30479073",
00000076 => x"441000ef",
00000076 => x"455000ef",
00000077 => x"00100513",
00000078 => x"41d000ef",
00000078 => x"431000ef",
00000079 => x"00000793",
00000080 => x"34079073",
00000081 => x"ffff1537",
00000082 => x"ed850513",
00000083 => x"2d9000ef",
00000084 => x"3bc000ef",
00000082 => x"eec50513",
00000083 => x"2ed000ef",
00000084 => x"3d0000ef",
00000085 => x"ffff1537",
00000086 => x"f1050513",
00000087 => x"2c9000ef",
00000088 => x"fc101573",
00000089 => x"240000ef",
00000086 => x"f2450513",
00000087 => x"2dd000ef",
00000088 => x"fc102573",
00000089 => x"254000ef",
00000090 => x"ffff1537",
00000091 => x"f1850513",
00000092 => x"2b5000ef",
00000093 => x"30101573",
00000094 => x"22c000ef",
00000091 => x"f2c50513",
00000092 => x"2c9000ef",
00000093 => x"f1402573",
00000094 => x"240000ef",
00000095 => x"ffff1537",
00000096 => x"f2450513",
00000097 => x"2a1000ef",
00000098 => x"fc001573",
00000099 => x"218000ef",
00000096 => x"f3850513",
00000097 => x"2b5000ef",
00000098 => x"30102573",
00000099 => x"22c000ef",
00000100 => x"ffff1537",
00000101 => x"f2c50513",
00000102 => x"28d000ef",
00000103 => x"fc601573",
00000104 => x"ffff14b7",
00000105 => x"200000ef",
00000106 => x"f3448513",
00000107 => x"279000ef",
00000108 => x"fc401573",
00000109 => x"1f0000ef",
00000110 => x"ffff1537",
00000111 => x"f4050513",
00000112 => x"265000ef",
00000113 => x"fc701573",
00000114 => x"1dc000ef",
00000115 => x"f3448513",
00000116 => x"255000ef",
00000117 => x"fc501573",
00000118 => x"1cc000ef",
00000119 => x"ffff1537",
00000120 => x"f4850513",
00000121 => x"241000ef",
00000122 => x"00341413",
00000123 => x"00000493",
00000124 => x"ffff1937",
00000125 => x"fa402783",
00000126 => x"0607d063",
00000127 => x"ffff1537",
00000128 => x"f7850513",
00000129 => x"221000ef",
00000130 => x"ffff1937",
00000131 => x"0f4000ef",
00000132 => x"ffff19b7",
00000133 => x"07200a13",
00000134 => x"06800a93",
00000135 => x"07500b13",
00000136 => x"07300b93",
00000137 => x"ffff14b7",
00000138 => x"ffff1c37",
00000139 => x"f8490513",
00000140 => x"1f5000ef",
00000141 => x"1e1000ef",
00000142 => x"00050413",
00000143 => x"1c9000ef",
00000144 => x"f7498513",
00000145 => x"1e1000ef",
00000146 => x"09440263",
00000147 => x"03541863",
00000148 => x"0b0000ef",
00000149 => x"fd9ff06f",
00000150 => x"0fd000ef",
00000151 => x"00b49463",
00000152 => x"f8856ae3",
00000153 => x"00100513",
00000154 => x"508000ef",
00000155 => x"f7490513",
00000156 => x"1b5000ef",
00000157 => x"098000ef",
00000158 => x"f7dff06f",
00000159 => x"00000513",
00000160 => x"01640e63",
00000161 => x"01741663",
00000162 => x"72c000ef",
00000163 => x"fa1ff06f",
00000164 => x"06c00793",
00000165 => x"00f41863",
00000166 => x"00100513",
00000167 => x"4d4000ef",
00000168 => x"f8dff06f",
00000169 => x"06500793",
00000170 => x"00f41663",
00000171 => x"060000ef",
00000172 => x"f7dff06f",
00000173 => x"03f00793",
00000174 => x"f8cc0513",
00000175 => x"00f40463",
00000176 => x"fa048513",
00000177 => x"161000ef",
00000178 => x"f65ff06f",
00000179 => x"02c12083",
00000180 => x"02812403",
00000181 => x"02412483",
00000182 => x"02012903",
00000183 => x"01c12983",
00000184 => x"01812a03",
00000185 => x"01412a83",
00000186 => x"01012b03",
00000187 => x"00c12b83",
00000188 => x"00812c03",
00000189 => x"00000513",
00000190 => x"03010113",
00000191 => x"00008067",
00000192 => x"ffff1537",
00000193 => x"da850513",
00000194 => x"11d0006f",
00000195 => x"340017f3",
00000196 => x"00079863",
00000101 => x"f4050513",
00000102 => x"2a1000ef",
00000103 => x"fc002573",
00000104 => x"218000ef",
00000105 => x"ffff1537",
00000106 => x"f4850513",
00000107 => x"28d000ef",
00000108 => x"fc602573",
00000109 => x"ffff14b7",
00000110 => x"200000ef",
00000111 => x"f5048513",
00000112 => x"279000ef",
00000113 => x"fc402573",
00000114 => x"1f0000ef",
00000115 => x"ffff1537",
00000116 => x"f5c50513",
00000117 => x"265000ef",
00000118 => x"fc702573",
00000119 => x"1dc000ef",
00000120 => x"f5048513",
00000121 => x"255000ef",
00000122 => x"fc502573",
00000123 => x"1cc000ef",
00000124 => x"ffff1537",
00000125 => x"f6450513",
00000126 => x"241000ef",
00000127 => x"00341413",
00000128 => x"00000493",
00000129 => x"ffff1937",
00000130 => x"fa402783",
00000131 => x"0607d063",
00000132 => x"ffff1537",
00000133 => x"f9450513",
00000134 => x"221000ef",
00000135 => x"ffff1937",
00000136 => x"0f4000ef",
00000137 => x"ffff19b7",
00000138 => x"07200a13",
00000139 => x"06800a93",
00000140 => x"07500b13",
00000141 => x"07300b93",
00000142 => x"ffff14b7",
00000143 => x"ffff1c37",
00000144 => x"fa090513",
00000145 => x"1f5000ef",
00000146 => x"1e1000ef",
00000147 => x"00050413",
00000148 => x"1c9000ef",
00000149 => x"f9098513",
00000150 => x"1e1000ef",
00000151 => x"09440263",
00000152 => x"03541863",
00000153 => x"0b0000ef",
00000154 => x"fd9ff06f",
00000155 => x"0fd000ef",
00000156 => x"00b49463",
00000157 => x"f8856ae3",
00000158 => x"00100513",
00000159 => x"508000ef",
00000160 => x"f9090513",
00000161 => x"1b5000ef",
00000162 => x"098000ef",
00000163 => x"f7dff06f",
00000164 => x"00000513",
00000165 => x"01640e63",
00000166 => x"01741663",
00000167 => x"72c000ef",
00000168 => x"fa1ff06f",
00000169 => x"06c00793",
00000170 => x"00f41863",
00000171 => x"00100513",
00000172 => x"4d4000ef",
00000173 => x"f8dff06f",
00000174 => x"06500793",
00000175 => x"00f41663",
00000176 => x"060000ef",
00000177 => x"f7dff06f",
00000178 => x"03f00793",
00000179 => x"fa8c0513",
00000180 => x"00f40463",
00000181 => x"fbc48513",
00000182 => x"161000ef",
00000183 => x"f65ff06f",
00000184 => x"02c12083",
00000185 => x"02812403",
00000186 => x"02412483",
00000187 => x"02012903",
00000188 => x"01c12983",
00000189 => x"01812a03",
00000190 => x"01412a83",
00000191 => x"01012b03",
00000192 => x"00c12b83",
00000193 => x"00812c03",
00000194 => x"00000513",
00000195 => x"03010113",
00000196 => x"00008067",
00000197 => x"ffff1537",
00000198 => x"e0c50513",
00000199 => x"1090006f",
00000200 => x"ff010113",
00000201 => x"00112623",
00000202 => x"251000ef",
00000203 => x"00000793",
00000204 => x"30479073",
00000205 => x"ffff1537",
00000206 => x"e2850513",
00000207 => x"0e9000ef",
00000208 => x"fa002783",
00000209 => x"fe07cee3",
00000210 => x"fc4017f3",
00000211 => x"00078067",
00000212 => x"ff9ff06f",
00000213 => x"ff010113",
00000214 => x"00812423",
00000215 => x"00050413",
00000216 => x"ffff1537",
00000217 => x"e3850513",
00000218 => x"00112623",
00000219 => x"0b9000ef",
00000220 => x"00500793",
00000221 => x"0287e063",
00000222 => x"03040513",
00000223 => x"0ff57513",
00000224 => x"085000ef",
00000225 => x"1f5000ef",
00000226 => x"00100513",
00000227 => x"1c9000ef",
00000228 => x"0000006f",
00000229 => x"ffff1537",
00000230 => x"e4050513",
00000231 => x"089000ef",
00000232 => x"fe5ff06f",
00000233 => x"fe010113",
00000234 => x"01212823",
00000235 => x"00050913",
00000236 => x"ffff1537",
00000237 => x"00912a23",
00000238 => x"e4850513",
00000239 => x"ffff14b7",
00000240 => x"00812c23",
00000241 => x"01312623",
00000242 => x"00112e23",
00000243 => x"01c00413",
00000244 => x"055000ef",
00000245 => x"fac48493",
00000246 => x"ffc00993",
00000247 => x"008957b3",
00000248 => x"00f7f793",
00000249 => x"00f487b3",
00000250 => x"0007c503",
00000251 => x"ffc40413",
00000252 => x"015000ef",
00000253 => x"ff3414e3",
00000254 => x"01c12083",
00000255 => x"01812403",
00000256 => x"01412483",
00000257 => x"01012903",
00000258 => x"00c12983",
00000259 => x"02010113",
00000260 => x"00008067",
00000261 => x"fb010113",
00000262 => x"04112623",
00000263 => x"04512423",
00000264 => x"04612223",
00000265 => x"04712023",
00000266 => x"02812e23",
00000267 => x"02a12c23",
00000268 => x"02b12a23",
00000269 => x"02c12823",
00000270 => x"02d12623",
00000271 => x"02e12423",
00000272 => x"02f12223",
00000273 => x"03012023",
00000274 => x"01112e23",
00000275 => x"01c12c23",
00000276 => x"01d12a23",
00000277 => x"01e12823",
00000278 => x"01f12623",
00000279 => x"34201473",
00000280 => x"800007b7",
00000281 => x"00778793",
00000282 => x"02f40a63",
00000283 => x"ffff1537",
00000284 => x"e4c50513",
00000285 => x"7b0000ef",
00000286 => x"00040513",
00000287 => x"f29ff0ef",
00000198 => x"dbc50513",
00000199 => x"11d0006f",
00000200 => x"340027f3",
00000201 => x"00079863",
00000202 => x"ffff1537",
00000203 => x"e2050513",
00000204 => x"1090006f",
00000205 => x"ff010113",
00000206 => x"00112623",
00000207 => x"251000ef",
00000208 => x"00000793",
00000209 => x"30479073",
00000210 => x"ffff1537",
00000211 => x"e3c50513",
00000212 => x"0e9000ef",
00000213 => x"fa002783",
00000214 => x"fe07cee3",
00000215 => x"fc4027f3",
00000216 => x"00078067",
00000217 => x"ff9ff06f",
00000218 => x"ff010113",
00000219 => x"00812423",
00000220 => x"00050413",
00000221 => x"ffff1537",
00000222 => x"e4c50513",
00000223 => x"00112623",
00000224 => x"0b9000ef",
00000225 => x"00500793",
00000226 => x"0287e063",
00000227 => x"03040513",
00000228 => x"0ff57513",
00000229 => x"085000ef",
00000230 => x"1f5000ef",
00000231 => x"00100513",
00000232 => x"1c9000ef",
00000233 => x"0000006f",
00000234 => x"ffff1537",
00000235 => x"e5450513",
00000236 => x"089000ef",
00000237 => x"fe5ff06f",
00000238 => x"fe010113",
00000239 => x"01212823",
00000240 => x"00050913",
00000241 => x"ffff1537",
00000242 => x"00912a23",
00000243 => x"e5c50513",
00000244 => x"ffff14b7",
00000245 => x"00812c23",
00000246 => x"01312623",
00000247 => x"00112e23",
00000248 => x"01c00413",
00000249 => x"055000ef",
00000250 => x"fc848493",
00000251 => x"ffc00993",
00000252 => x"008957b3",
00000253 => x"00f7f793",
00000254 => x"00f487b3",
00000255 => x"0007c503",
00000256 => x"ffc40413",
00000257 => x"015000ef",
00000258 => x"ff3414e3",
00000259 => x"01c12083",
00000260 => x"01812403",
00000261 => x"01412483",
00000262 => x"01012903",
00000263 => x"00c12983",
00000264 => x"02010113",
00000265 => x"00008067",
00000266 => x"fb010113",
00000267 => x"04112623",
00000268 => x"04512423",
00000269 => x"04612223",
00000270 => x"04712023",
00000271 => x"02812e23",
00000272 => x"02a12c23",
00000273 => x"02b12a23",
00000274 => x"02c12823",
00000275 => x"02d12623",
00000276 => x"02e12423",
00000277 => x"02f12223",
00000278 => x"03012023",
00000279 => x"01112e23",
00000280 => x"01c12c23",
00000281 => x"01d12a23",
00000282 => x"01e12823",
00000283 => x"01f12623",
00000284 => x"34202473",
00000285 => x"800007b7",
00000286 => x"00778793",
00000287 => x"02f40a63",
00000288 => x"ffff1537",
00000289 => x"e5c50513",
00000290 => x"79c000ef",
00000291 => x"34101573",
00000292 => x"f15ff0ef",
00000293 => x"00500513",
00000294 => x"ebdff0ef",
00000295 => x"00000513",
00000296 => x"095000ef",
00000297 => x"6b0000ef",
00000298 => x"fc1017f3",
00000299 => x"0027d793",
00000300 => x"00a78533",
00000301 => x"00f537b3",
00000302 => x"00b785b3",
00000303 => x"6a4000ef",
00000304 => x"03c12403",
00000305 => x"04c12083",
00000306 => x"04812283",
00000307 => x"04412303",
00000308 => x"04012383",
00000309 => x"03812503",
00000310 => x"03412583",
00000311 => x"03012603",
00000312 => x"02c12683",
00000313 => x"02812703",
00000314 => x"02412783",
00000315 => x"02012803",
00000316 => x"01c12883",
00000317 => x"01812e03",
00000318 => x"01412e83",
00000319 => x"01012f03",
00000320 => x"00c12f83",
00000321 => x"05010113",
00000322 => x"30200073",
00000323 => x"fe010113",
00000324 => x"00112e23",
00000325 => x"00812c23",
00000326 => x"00912a23",
00000327 => x"01212823",
00000328 => x"01312623",
00000329 => x"01412423",
00000330 => x"01512223",
00000331 => x"f1301973",
00000332 => x"00000a93",
00000333 => x"00900993",
00000334 => x"00300a13",
00000335 => x"00400493",
00000336 => x"41500433",
00000337 => x"00341413",
00000338 => x"01840413",
00000339 => x"00895433",
00000340 => x"0ff47413",
00000341 => x"00000513",
00000342 => x"0489ec63",
00000343 => x"00050863",
00000344 => x"03050513",
00000345 => x"0ff57513",
00000346 => x"69c000ef",
00000347 => x"03040513",
00000348 => x"0ff57513",
00000349 => x"690000ef",
00000350 => x"014a8663",
00000351 => x"02e00513",
00000352 => x"684000ef",
00000353 => x"001a8a93",
00000354 => x"fa9a9ce3",
00000355 => x"01c12083",
00000356 => x"01812403",
00000357 => x"01412483",
00000358 => x"01012903",
00000359 => x"00c12983",
00000360 => x"00812a03",
00000361 => x"00412a83",
00000362 => x"02010113",
00000363 => x"00008067",
00000364 => x"ff640413",
00000365 => x"00150513",
00000366 => x"0ff47413",
00000367 => x"0ff57513",
00000368 => x"f99ff06f",
00000369 => x"ff010113",
00000370 => x"00000513",
00000371 => x"00112623",
00000372 => x"00812423",
00000373 => x"708000ef",
00000374 => x"00500513",
00000375 => x"744000ef",
00000376 => x"00000513",
00000377 => x"73c000ef",
00000378 => x"00050413",
00000379 => x"00000513",
00000380 => x"70c000ef",
00000381 => x"00c12083",
00000382 => x"0ff47513",
00000383 => x"00812403",
00000384 => x"01010113",
00000385 => x"00008067",
00000386 => x"ff010113",
00000387 => x"00000513",
00000388 => x"00112623",
00000389 => x"00812423",
00000390 => x"6c4000ef",
00000391 => x"09e00513",
00000392 => x"700000ef",
00000393 => x"00000513",
00000394 => x"6f8000ef",
00000395 => x"00050413",
00000396 => x"00000513",
00000397 => x"6c8000ef",
00000398 => x"00c12083",
00000399 => x"0ff47513",
00000400 => x"00812403",
00000401 => x"01010113",
00000402 => x"00008067",
00000403 => x"ff010113",
00000404 => x"00000513",
00000405 => x"00112623",
00000406 => x"684000ef",
00000407 => x"00600513",
00000408 => x"6c0000ef",
00000409 => x"00c12083",
00000410 => x"00000513",
00000411 => x"01010113",
00000412 => x"68c0006f",
00000413 => x"ff010113",
00000414 => x"00812423",
00000415 => x"00050413",
00000416 => x"01055513",
00000417 => x"0ff57513",
00000418 => x"00112623",
00000419 => x"694000ef",
00000420 => x"00845513",
00000421 => x"0ff57513",
00000422 => x"688000ef",
00000423 => x"0ff47513",
00000424 => x"00812403",
00000425 => x"00c12083",
00000426 => x"01010113",
00000427 => x"6740006f",
00000428 => x"ff010113",
00000429 => x"00812423",
00000430 => x"00050413",
00000431 => x"00000513",
00000432 => x"00112623",
00000433 => x"618000ef",
00000434 => x"00300513",
00000435 => x"654000ef",
00000436 => x"00040513",
00000437 => x"fa1ff0ef",
00000438 => x"00000513",
00000439 => x"644000ef",
00000440 => x"00050413",
00000441 => x"00000513",
00000442 => x"614000ef",
00000443 => x"00c12083",
00000444 => x"0ff47513",
00000445 => x"00812403",
00000446 => x"01010113",
00000447 => x"00008067",
00000448 => x"fd010113",
00000449 => x"02812423",
00000450 => x"02912223",
00000451 => x"03212023",
00000452 => x"01312e23",
00000453 => x"02112623",
00000454 => x"00050493",
00000455 => x"00300413",
00000456 => x"00358913",
00000457 => x"fff00993",
00000458 => x"02049e63",
00000459 => x"4e8000ef",
00000460 => x"00c10793",
00000461 => x"008787b3",
00000462 => x"00a78023",
00000463 => x"fff40413",
00000464 => x"ff3414e3",
00000465 => x"02c12083",
00000466 => x"02812403",
00000467 => x"00c12503",
00000468 => x"02412483",
00000469 => x"02012903",
00000470 => x"01c12983",
00000471 => x"03010113",
00000472 => x"00008067",
00000473 => x"40890533",
00000474 => x"f49ff0ef",
00000475 => x"fc5ff06f",
00000476 => x"fd010113",
00000477 => x"02112623",
00000478 => x"02812423",
00000479 => x"02912223",
00000480 => x"03212023",
00000481 => x"01312e23",
00000482 => x"01412c23",
00000483 => x"01512a23",
00000484 => x"01612823",
00000485 => x"01712623",
00000486 => x"fc001473",
00000487 => x"00847413",
00000488 => x"00040663",
00000489 => x"00400513",
00000490 => x"badff0ef",
00000491 => x"00050493",
00000492 => x"02051863",
00000493 => x"ffff1537",
00000494 => x"e6450513",
00000495 => x"468000ef",
00000496 => x"000405b7",
00000497 => x"00048513",
00000498 => x"f39ff0ef",
00000499 => x"4788d7b7",
00000500 => x"afe78793",
00000501 => x"02f50463",
00000502 => x"00000513",
00000503 => x"fcdff06f",
00000504 => x"ffff1537",
00000505 => x"e8450513",
00000506 => x"43c000ef",
00000507 => x"e1dff0ef",
00000508 => x"fc0518e3",
00000509 => x"00300513",
00000510 => x"fb1ff06f",
00000511 => x"00040a37",
00000512 => x"004a0593",
00000513 => x"00048513",
00000514 => x"ef9ff0ef",
00000515 => x"00050913",
00000516 => x"008a0593",
00000517 => x"00048513",
00000518 => x"ee9ff0ef",
00000519 => x"00050a93",
00000520 => x"fc6017f3",
00000521 => x"00100513",
00000522 => x"f927e0e3",
00000523 => x"fc401bf3",
00000524 => x"00000993",
00000525 => x"ffc97b13",
00000526 => x"00ca0a13",
00000527 => x"014985b3",
00000528 => x"053b1663",
00000529 => x"01540433",
00000530 => x"00200513",
00000531 => x"f4041ee3",
00000532 => x"ffff1537",
00000533 => x"e9050513",
00000534 => x"3cc000ef",
00000535 => x"34091073",
00000536 => x"02c12083",
00000537 => x"02812403",
00000538 => x"02412483",
00000539 => x"02012903",
00000540 => x"01c12983",
00000541 => x"01812a03",
00000542 => x"01412a83",
00000543 => x"01012b03",
00000544 => x"00c12b83",
00000545 => x"03010113",
00000546 => x"00008067",
00000547 => x"00048513",
00000548 => x"e71ff0ef",
00000549 => x"017987b3",
00000550 => x"00a40433",
00000551 => x"00a7a023",
00000552 => x"00498993",
00000553 => x"f99ff06f",
00000554 => x"ff010113",
00000555 => x"00112623",
00000556 => x"00812423",
00000557 => x"00912223",
00000558 => x"00058413",
00000559 => x"00050493",
00000560 => x"d8dff0ef",
00000561 => x"00000513",
00000562 => x"414000ef",
00000563 => x"00200513",
00000564 => x"450000ef",
00000565 => x"00048513",
00000566 => x"d9dff0ef",
00000567 => x"00040513",
00000568 => x"440000ef",
00000569 => x"00000513",
00000570 => x"414000ef",
00000571 => x"cd9ff0ef",
00000572 => x"00157513",
00000573 => x"fe051ce3",
00000574 => x"00c12083",
00000575 => x"00812403",
00000576 => x"00412483",
00000577 => x"01010113",
00000578 => x"00008067",
00000579 => x"fe010113",
00000580 => x"00812c23",
00000581 => x"00912a23",
00000582 => x"01212823",
00000583 => x"00112e23",
00000584 => x"00b12623",
00000585 => x"00300413",
00000586 => x"00350493",
00000587 => x"fff00913",
00000588 => x"00c10793",
00000589 => x"008787b3",
00000590 => x"0007c583",
00000591 => x"40848533",
00000592 => x"fff40413",
00000593 => x"f65ff0ef",
00000594 => x"ff2414e3",
00000595 => x"01c12083",
00000596 => x"01812403",
00000597 => x"01412483",
00000598 => x"01012903",
00000599 => x"02010113",
00000600 => x"00008067",
00000601 => x"ff010113",
00000602 => x"00112623",
00000603 => x"00812423",
00000604 => x"00050413",
00000605 => x"cd9ff0ef",
00000606 => x"00000513",
00000607 => x"360000ef",
00000608 => x"0d800513",
00000609 => x"39c000ef",
00000610 => x"00040513",
00000611 => x"ce9ff0ef",
00000612 => x"00000513",
00000613 => x"368000ef",
00000614 => x"c2dff0ef",
00000615 => x"00157513",
00000616 => x"fe051ce3",
00000617 => x"00c12083",
00000618 => x"00812403",
00000619 => x"01010113",
00000620 => x"00008067",
00000621 => x"fe010113",
00000622 => x"00112e23",
00000623 => x"00812c23",
00000624 => x"00912a23",
00000625 => x"01212823",
00000626 => x"01312623",
00000627 => x"01412423",
00000628 => x"01512223",
00000629 => x"34001473",
00000630 => x"02041863",
00000631 => x"ffff1537",
00000632 => x"e0c50513",
00000633 => x"01812403",
00000634 => x"01c12083",
00000635 => x"01412483",
00000636 => x"01012903",
00000637 => x"00c12983",
00000638 => x"00812a03",
00000639 => x"00412a83",
00000640 => x"02010113",
00000641 => x"2200006f",
00000642 => x"ffff1537",
00000643 => x"e9450513",
00000644 => x"214000ef",
00000645 => x"00040513",
00000646 => x"98dff0ef",
00000289 => x"e6050513",
00000290 => x"7b0000ef",
00000291 => x"00040513",
00000292 => x"f29ff0ef",
00000293 => x"ffff1537",
00000294 => x"e7050513",
00000295 => x"79c000ef",
00000296 => x"34102573",
00000297 => x"f15ff0ef",
00000298 => x"00500513",
00000299 => x"ebdff0ef",
00000300 => x"00000513",
00000301 => x"095000ef",
00000302 => x"6b0000ef",
00000303 => x"fc1027f3",
00000304 => x"0027d793",
00000305 => x"00a78533",
00000306 => x"00f537b3",
00000307 => x"00b785b3",
00000308 => x"6a4000ef",
00000309 => x"03c12403",
00000310 => x"04c12083",
00000311 => x"04812283",
00000312 => x"04412303",
00000313 => x"04012383",
00000314 => x"03812503",
00000315 => x"03412583",
00000316 => x"03012603",
00000317 => x"02c12683",
00000318 => x"02812703",
00000319 => x"02412783",
00000320 => x"02012803",
00000321 => x"01c12883",
00000322 => x"01812e03",
00000323 => x"01412e83",
00000324 => x"01012f03",
00000325 => x"00c12f83",
00000326 => x"05010113",
00000327 => x"30200073",
00000328 => x"fe010113",
00000329 => x"00112e23",
00000330 => x"00812c23",
00000331 => x"00912a23",
00000332 => x"01212823",
00000333 => x"01312623",
00000334 => x"01412423",
00000335 => x"01512223",
00000336 => x"f1302973",
00000337 => x"00000a93",
00000338 => x"00900993",
00000339 => x"00300a13",
00000340 => x"00400493",
00000341 => x"41500433",
00000342 => x"00341413",
00000343 => x"01840413",
00000344 => x"00895433",
00000345 => x"0ff47413",
00000346 => x"00000513",
00000347 => x"0489ec63",
00000348 => x"00050863",
00000349 => x"03050513",
00000350 => x"0ff57513",
00000351 => x"69c000ef",
00000352 => x"03040513",
00000353 => x"0ff57513",
00000354 => x"690000ef",
00000355 => x"014a8663",
00000356 => x"02e00513",
00000357 => x"684000ef",
00000358 => x"001a8a93",
00000359 => x"fa9a9ce3",
00000360 => x"01c12083",
00000361 => x"01812403",
00000362 => x"01412483",
00000363 => x"01012903",
00000364 => x"00c12983",
00000365 => x"00812a03",
00000366 => x"00412a83",
00000367 => x"02010113",
00000368 => x"00008067",
00000369 => x"ff640413",
00000370 => x"00150513",
00000371 => x"0ff47413",
00000372 => x"0ff57513",
00000373 => x"f99ff06f",
00000374 => x"ff010113",
00000375 => x"00000513",
00000376 => x"00112623",
00000377 => x"00812423",
00000378 => x"708000ef",
00000379 => x"00500513",
00000380 => x"744000ef",
00000381 => x"00000513",
00000382 => x"73c000ef",
00000383 => x"00050413",
00000384 => x"00000513",
00000385 => x"70c000ef",
00000386 => x"00c12083",
00000387 => x"0ff47513",
00000388 => x"00812403",
00000389 => x"01010113",
00000390 => x"00008067",
00000391 => x"ff010113",
00000392 => x"00000513",
00000393 => x"00112623",
00000394 => x"00812423",
00000395 => x"6c4000ef",
00000396 => x"09e00513",
00000397 => x"700000ef",
00000398 => x"00000513",
00000399 => x"6f8000ef",
00000400 => x"00050413",
00000401 => x"00000513",
00000402 => x"6c8000ef",
00000403 => x"00c12083",
00000404 => x"0ff47513",
00000405 => x"00812403",
00000406 => x"01010113",
00000407 => x"00008067",
00000408 => x"ff010113",
00000409 => x"00000513",
00000410 => x"00112623",
00000411 => x"684000ef",
00000412 => x"00600513",
00000413 => x"6c0000ef",
00000414 => x"00c12083",
00000415 => x"00000513",
00000416 => x"01010113",
00000417 => x"68c0006f",
00000418 => x"ff010113",
00000419 => x"00812423",
00000420 => x"00050413",
00000421 => x"01055513",
00000422 => x"0ff57513",
00000423 => x"00112623",
00000424 => x"694000ef",
00000425 => x"00845513",
00000426 => x"0ff57513",
00000427 => x"688000ef",
00000428 => x"0ff47513",
00000429 => x"00812403",
00000430 => x"00c12083",
00000431 => x"01010113",
00000432 => x"6740006f",
00000433 => x"ff010113",
00000434 => x"00812423",
00000435 => x"00050413",
00000436 => x"00000513",
00000437 => x"00112623",
00000438 => x"618000ef",
00000439 => x"00300513",
00000440 => x"654000ef",
00000441 => x"00040513",
00000442 => x"fa1ff0ef",
00000443 => x"00000513",
00000444 => x"644000ef",
00000445 => x"00050413",
00000446 => x"00000513",
00000447 => x"614000ef",
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"02112623",
00000459 => x"00050493",
00000460 => x"00300413",
00000461 => x"00358913",
00000462 => x"fff00993",
00000463 => x"02049e63",
00000464 => x"4e8000ef",
00000465 => x"00c10793",
00000466 => x"008787b3",
00000467 => x"00a78023",
00000468 => x"fff40413",
00000469 => x"ff3414e3",
00000470 => x"02c12083",
00000471 => x"02812403",
00000472 => x"00c12503",
00000473 => x"02412483",
00000474 => x"02012903",
00000475 => x"01c12983",
00000476 => x"03010113",
00000477 => x"00008067",
00000478 => x"40890533",
00000479 => x"f49ff0ef",
00000480 => x"fc5ff06f",
00000481 => x"fd010113",
00000482 => x"02112623",
00000483 => x"02812423",
00000484 => x"02912223",
00000485 => x"03212023",
00000486 => x"01312e23",
00000487 => x"01412c23",
00000488 => x"01512a23",
00000489 => x"01612823",
00000490 => x"01712623",
00000491 => x"fc002473",
00000492 => x"00847413",
00000493 => x"00040663",
00000494 => x"00400513",
00000495 => x"badff0ef",
00000496 => x"00050493",
00000497 => x"02051863",
00000498 => x"ffff1537",
00000499 => x"e7850513",
00000500 => x"468000ef",
00000501 => x"000405b7",
00000502 => x"00048513",
00000503 => x"f39ff0ef",
00000504 => x"4788d7b7",
00000505 => x"afe78793",
00000506 => x"02f50463",
00000507 => x"00000513",
00000508 => x"fcdff06f",
00000509 => x"ffff1537",
00000510 => x"e9850513",
00000511 => x"43c000ef",
00000512 => x"e1dff0ef",
00000513 => x"fc0518e3",
00000514 => x"00300513",
00000515 => x"fb1ff06f",
00000516 => x"00040a37",
00000517 => x"004a0593",
00000518 => x"00048513",
00000519 => x"ef9ff0ef",
00000520 => x"00050913",
00000521 => x"008a0593",
00000522 => x"00048513",
00000523 => x"ee9ff0ef",
00000524 => x"00050a93",
00000525 => x"fc6027f3",
00000526 => x"00100513",
00000527 => x"f927e0e3",
00000528 => x"fc402bf3",
00000529 => x"00000993",
00000530 => x"ffc97b13",
00000531 => x"00ca0a13",
00000532 => x"014985b3",
00000533 => x"053b1663",
00000534 => x"01540433",
00000535 => x"00200513",
00000536 => x"f4041ee3",
00000537 => x"ffff1537",
00000538 => x"ea450513",
00000539 => x"3cc000ef",
00000540 => x"34091073",
00000541 => x"02c12083",
00000542 => x"02812403",
00000543 => x"02412483",
00000544 => x"02012903",
00000545 => x"01c12983",
00000546 => x"01812a03",
00000547 => x"01412a83",
00000548 => x"01012b03",
00000549 => x"00c12b83",
00000550 => x"03010113",
00000551 => x"00008067",
00000552 => x"00048513",
00000553 => x"e71ff0ef",
00000554 => x"017987b3",
00000555 => x"00a40433",
00000556 => x"00a7a023",
00000557 => x"00498993",
00000558 => x"f99ff06f",
00000559 => x"ff010113",
00000560 => x"00112623",
00000561 => x"00812423",
00000562 => x"00912223",
00000563 => x"00058413",
00000564 => x"00050493",
00000565 => x"d8dff0ef",
00000566 => x"00000513",
00000567 => x"414000ef",
00000568 => x"00200513",
00000569 => x"450000ef",
00000570 => x"00048513",
00000571 => x"d9dff0ef",
00000572 => x"00040513",
00000573 => x"440000ef",
00000574 => x"00000513",
00000575 => x"414000ef",
00000576 => x"cd9ff0ef",
00000577 => x"00157513",
00000578 => x"fe051ce3",
00000579 => x"00c12083",
00000580 => x"00812403",
00000581 => x"00412483",
00000582 => x"01010113",
00000583 => x"00008067",
00000584 => x"fe010113",
00000585 => x"00812c23",
00000586 => x"00912a23",
00000587 => x"01212823",
00000588 => x"00112e23",
00000589 => x"00b12623",
00000590 => x"00300413",
00000591 => x"00350493",
00000592 => x"fff00913",
00000593 => x"00c10793",
00000594 => x"008787b3",
00000595 => x"0007c583",
00000596 => x"40848533",
00000597 => x"fff40413",
00000598 => x"f65ff0ef",
00000599 => x"ff2414e3",
00000600 => x"01c12083",
00000601 => x"01812403",
00000602 => x"01412483",
00000603 => x"01012903",
00000604 => x"02010113",
00000605 => x"00008067",
00000606 => x"ff010113",
00000607 => x"00112623",
00000608 => x"00812423",
00000609 => x"00050413",
00000610 => x"cd9ff0ef",
00000611 => x"00000513",
00000612 => x"360000ef",
00000613 => x"0d800513",
00000614 => x"39c000ef",
00000615 => x"00040513",
00000616 => x"ce9ff0ef",
00000617 => x"00000513",
00000618 => x"368000ef",
00000619 => x"c2dff0ef",
00000620 => x"00157513",
00000621 => x"fe051ce3",
00000622 => x"00c12083",
00000623 => x"00812403",
00000624 => x"01010113",
00000625 => x"00008067",
00000626 => x"fe010113",
00000627 => x"00112e23",
00000628 => x"00812c23",
00000629 => x"00912a23",
00000630 => x"01212823",
00000631 => x"01312623",
00000632 => x"01412423",
00000633 => x"01512223",
00000634 => x"34002473",
00000635 => x"02041863",
00000636 => x"ffff1537",
00000637 => x"e2050513",
00000638 => x"01812403",
00000639 => x"01c12083",
00000640 => x"01412483",
00000641 => x"01012903",
00000642 => x"00c12983",
00000643 => x"00812a03",
00000644 => x"00412a83",
00000645 => x"02010113",
00000646 => x"2200006f",
00000647 => x"ffff1537",
00000648 => x"ea050513",
00000649 => x"200000ef",
00000650 => x"00040537",
00000651 => x"979ff0ef",
00000648 => x"ea850513",
00000649 => x"214000ef",
00000650 => x"00040513",
00000651 => x"98dff0ef",
00000652 => x"ffff1537",
00000653 => x"ebc50513",
00000654 => x"1ec000ef",
00000655 => x"1d8000ef",
00000656 => x"00050493",
00000657 => x"1c0000ef",
00000658 => x"07900793",
00000659 => x"0af49e63",
00000660 => x"bb9ff0ef",
00000661 => x"00051663",
00000662 => x"00300513",
00000663 => x"8f9ff0ef",
00000664 => x"ffff1537",
00000665 => x"ec850513",
00000666 => x"01045493",
00000667 => x"1b8000ef",
00000668 => x"00148493",
00000669 => x"00040937",
00000670 => x"fff00993",
00000671 => x"00010a37",
00000672 => x"fff48493",
00000673 => x"07349063",
00000674 => x"4788d5b7",
00000675 => x"afe58593",
00000676 => x"00040537",
00000677 => x"e79ff0ef",
00000678 => x"00040537",
00000679 => x"00040593",
00000680 => x"00450513",
00000681 => x"e69ff0ef",
00000682 => x"fc401a73",
00000683 => x"000409b7",
00000684 => x"ffc47413",
00000685 => x"00000493",
00000686 => x"00000913",
00000687 => x"00c98a93",
00000688 => x"01548533",
00000689 => x"014487b3",
00000690 => x"02849663",
00000691 => x"00898513",
00000692 => x"412005b3",
00000693 => x"e39ff0ef",
00000694 => x"ffff1537",
00000695 => x"e9050513",
00000696 => x"f05ff06f",
00000697 => x"00090513",
00000698 => x"e7dff0ef",
00000699 => x"01490933",
00000700 => x"f91ff06f",
00000701 => x"0007a583",
00000702 => x"00448493",
00000703 => x"00b90933",
00000704 => x"e0dff0ef",
00000705 => x"fbdff06f",
00000706 => x"01c12083",
00000707 => x"01812403",
00000708 => x"01412483",
00000709 => x"01012903",
00000710 => x"00c12983",
00000711 => x"00812a03",
00000712 => x"00412a83",
00000713 => x"02010113",
00000714 => x"00008067",
00000715 => x"000047b7",
00000716 => x"70078793",
00000717 => x"f8f02623",
00000718 => x"00008067",
00000719 => x"fc000713",
00000720 => x"00072783",
00000721 => x"00179793",
00000722 => x"0017d793",
00000723 => x"00f72023",
00000724 => x"00008067",
00000725 => x"f9002503",
00000726 => x"f9402583",
00000727 => x"00008067",
00000728 => x"f9800693",
00000729 => x"fff00613",
00000730 => x"00c6a023",
00000731 => x"00a6a023",
00000732 => x"00b6a223",
00000733 => x"00008067",
00000734 => x"fa002023",
00000735 => x"fc1016f3",
00000736 => x"00000713",
00000737 => x"00151513",
00000738 => x"04a6f263",
00000739 => x"000016b7",
00000740 => x"00000793",
00000741 => x"ffe68693",
00000742 => x"04e6e463",
00000743 => x"00167613",
00000744 => x"0015f593",
00000745 => x"01879793",
00000746 => x"01e61613",
00000747 => x"00c7e7b3",
00000748 => x"01d59593",
00000749 => x"00b7e7b3",
00000750 => x"00e7e7b3",
00000751 => x"10000737",
00000752 => x"00e7e7b3",
00000753 => x"faf02023",
00000754 => x"00008067",
00000755 => x"00170793",
00000756 => x"01079713",
00000757 => x"40a686b3",
00000758 => x"01075713",
00000759 => x"fadff06f",
00000760 => x"ffe78513",
00000761 => x"0fd57513",
00000762 => x"00051a63",
00000763 => x"00375713",
00000764 => x"00178793",
00000765 => x"0ff7f793",
00000766 => x"fa1ff06f",
00000767 => x"00175713",
00000768 => x"ff1ff06f",
00000769 => x"fa002783",
00000770 => x"fe07cee3",
00000771 => x"faa02223",
00000772 => x"00008067",
00000773 => x"fa402503",
00000774 => x"fe055ee3",
00000775 => x"0ff57513",
00000776 => x"00008067",
00000777 => x"ff010113",
00000778 => x"00812423",
00000779 => x"01212023",
00000780 => x"00112623",
00000781 => x"00912223",
00000782 => x"00050413",
00000783 => x"00a00913",
00000784 => x"00044483",
00000785 => x"00140413",
00000786 => x"00049e63",
00000787 => x"00c12083",
00000788 => x"00812403",
00000789 => x"00412483",
00000790 => x"00012903",
00000791 => x"01010113",
00000792 => x"00008067",
00000793 => x"01249663",
00000794 => x"00d00513",
00000795 => x"f99ff0ef",
00000796 => x"00048513",
00000797 => x"f91ff0ef",
00000798 => x"fc9ff06f",
00000799 => x"00757513",
00000800 => x"00177793",
00000801 => x"01079793",
00000802 => x"0036f693",
00000803 => x"00a51513",
00000804 => x"00f56533",
00000805 => x"00167613",
00000806 => x"00e69793",
00000807 => x"0015f593",
00000808 => x"00f567b3",
00000809 => x"00d61613",
00000810 => x"00c7e7b3",
00000811 => x"00959593",
00000812 => x"fa800813",
00000813 => x"00b7e7b3",
00000814 => x"00082023",
00000815 => x"1007e793",
00000816 => x"00f82023",
00000817 => x"00008067",
00000818 => x"fa800713",
00000819 => x"00072783",
00000820 => x"eff7f793",
00000821 => x"00f72023",
00000653 => x"eb450513",
00000654 => x"200000ef",
00000655 => x"00040537",
00000656 => x"979ff0ef",
00000657 => x"ffff1537",
00000658 => x"ed050513",
00000659 => x"1ec000ef",
00000660 => x"1d8000ef",
00000661 => x"00050493",
00000662 => x"1c0000ef",
00000663 => x"07900793",
00000664 => x"0af49e63",
00000665 => x"bb9ff0ef",
00000666 => x"00051663",
00000667 => x"00300513",
00000668 => x"8f9ff0ef",
00000669 => x"ffff1537",
00000670 => x"edc50513",
00000671 => x"01045493",
00000672 => x"1b8000ef",
00000673 => x"00148493",
00000674 => x"00040937",
00000675 => x"fff00993",
00000676 => x"00010a37",
00000677 => x"fff48493",
00000678 => x"07349063",
00000679 => x"4788d5b7",
00000680 => x"afe58593",
00000681 => x"00040537",
00000682 => x"e79ff0ef",
00000683 => x"00040537",
00000684 => x"00040593",
00000685 => x"00450513",
00000686 => x"e69ff0ef",
00000687 => x"fc402a73",
00000688 => x"000409b7",
00000689 => x"ffc47413",
00000690 => x"00000493",
00000691 => x"00000913",
00000692 => x"00c98a93",
00000693 => x"01548533",
00000694 => x"014487b3",
00000695 => x"02849663",
00000696 => x"00898513",
00000697 => x"412005b3",
00000698 => x"e39ff0ef",
00000699 => x"ffff1537",
00000700 => x"ea450513",
00000701 => x"f05ff06f",
00000702 => x"00090513",
00000703 => x"e7dff0ef",
00000704 => x"01490933",
00000705 => x"f91ff06f",
00000706 => x"0007a583",
00000707 => x"00448493",
00000708 => x"00b90933",
00000709 => x"e0dff0ef",
00000710 => x"fbdff06f",
00000711 => x"01c12083",
00000712 => x"01812403",
00000713 => x"01412483",
00000714 => x"01012903",
00000715 => x"00c12983",
00000716 => x"00812a03",
00000717 => x"00412a83",
00000718 => x"02010113",
00000719 => x"00008067",
00000720 => x"000047b7",
00000721 => x"70078793",
00000722 => x"f8f02623",
00000723 => x"00008067",
00000724 => x"fc000713",
00000725 => x"00072783",
00000726 => x"00179793",
00000727 => x"0017d793",
00000728 => x"00f72023",
00000729 => x"00008067",
00000730 => x"f9002503",
00000731 => x"f9402583",
00000732 => x"00008067",
00000733 => x"f9800693",
00000734 => x"fff00613",
00000735 => x"00c6a023",
00000736 => x"00a6a023",
00000737 => x"00b6a223",
00000738 => x"00008067",
00000739 => x"fa002023",
00000740 => x"fc1026f3",
00000741 => x"00000713",
00000742 => x"00151513",
00000743 => x"04a6f263",
00000744 => x"000016b7",
00000745 => x"00000793",
00000746 => x"ffe68693",
00000747 => x"04e6e463",
00000748 => x"00167613",
00000749 => x"0015f593",
00000750 => x"01879793",
00000751 => x"01e61613",
00000752 => x"00c7e7b3",
00000753 => x"01d59593",
00000754 => x"00b7e7b3",
00000755 => x"00e7e7b3",
00000756 => x"10000737",
00000757 => x"00e7e7b3",
00000758 => x"faf02023",
00000759 => x"00008067",
00000760 => x"00170793",
00000761 => x"01079713",
00000762 => x"40a686b3",
00000763 => x"01075713",
00000764 => x"fadff06f",
00000765 => x"ffe78513",
00000766 => x"0fd57513",
00000767 => x"00051a63",
00000768 => x"00375713",
00000769 => x"00178793",
00000770 => x"0ff7f793",
00000771 => x"fa1ff06f",
00000772 => x"00175713",
00000773 => x"ff1ff06f",
00000774 => x"fa002783",
00000775 => x"fe07cee3",
00000776 => x"faa02223",
00000777 => x"00008067",
00000778 => x"fa402503",
00000779 => x"fe055ee3",
00000780 => x"0ff57513",
00000781 => x"00008067",
00000782 => x"ff010113",
00000783 => x"00812423",
00000784 => x"01212023",
00000785 => x"00112623",
00000786 => x"00912223",
00000787 => x"00050413",
00000788 => x"00a00913",
00000789 => x"00044483",
00000790 => x"00140413",
00000791 => x"00049e63",
00000792 => x"00c12083",
00000793 => x"00812403",
00000794 => x"00412483",
00000795 => x"00012903",
00000796 => x"01010113",
00000797 => x"00008067",
00000798 => x"01249663",
00000799 => x"00d00513",
00000800 => x"f99ff0ef",
00000801 => x"00048513",
00000802 => x"f91ff0ef",
00000803 => x"fc9ff06f",
00000804 => x"00757513",
00000805 => x"00177793",
00000806 => x"01079793",
00000807 => x"0036f693",
00000808 => x"00a51513",
00000809 => x"00f56533",
00000810 => x"00167613",
00000811 => x"00e69793",
00000812 => x"0015f593",
00000813 => x"00f567b3",
00000814 => x"00d61613",
00000815 => x"00c7e7b3",
00000816 => x"00959593",
00000817 => x"fa800813",
00000818 => x"00b7e7b3",
00000819 => x"00082023",
00000820 => x"1007e793",
00000821 => x"00f82023",
00000822 => x"00008067",
00000823 => x"fa800713",
00000824 => x"00072683",
00000825 => x"00757793",
00000826 => x"00100513",
00000827 => x"00f51533",
00000828 => x"00d56533",
00000829 => x"00a72023",
00000830 => x"00008067",
00000831 => x"fa800713",
00000832 => x"00072683",
00000833 => x"00757513",
00000834 => x"00100793",
00000835 => x"00a797b3",
00000836 => x"fff7c793",
00000837 => x"00d7f7b3",
00000838 => x"00f72023",
00000839 => x"00008067",
00000840 => x"faa02623",
00000841 => x"fa802783",
00000842 => x"fe07cee3",
00000843 => x"fac02503",
00000824 => x"00072783",
00000825 => x"eff7f793",
00000826 => x"00f72023",
00000827 => x"00008067",
00000828 => x"fa800713",
00000829 => x"00072683",
00000830 => x"00757793",
00000831 => x"00100513",
00000832 => x"00f51533",
00000833 => x"00d56533",
00000834 => x"00a72023",
00000835 => x"00008067",
00000836 => x"fa800713",
00000837 => x"00072683",
00000838 => x"00757513",
00000839 => x"00100793",
00000840 => x"00a797b3",
00000841 => x"fff7c793",
00000842 => x"00d7f7b3",
00000843 => x"00f72023",
00000844 => x"00008067",
00000845 => x"f8400713",
00000846 => x"00072683",
00000847 => x"00f57793",
00000848 => x"00100513",
00000849 => x"00f51533",
00000850 => x"00d54533",
00000851 => x"00a72023",
00000852 => x"00008067",
00000853 => x"f8a02223",
00000854 => x"00008067",
00000855 => x"fb800713",
00000856 => x"00072783",
00000857 => x"ffe7f793",
00000858 => x"00f72023",
00000845 => x"faa02623",
00000846 => x"fa802783",
00000847 => x"fe07cee3",
00000848 => x"fac02503",
00000849 => x"00008067",
00000850 => x"f8400713",
00000851 => x"00072683",
00000852 => x"00f57793",
00000853 => x"00100513",
00000854 => x"00f51533",
00000855 => x"00d54533",
00000856 => x"00a72023",
00000857 => x"00008067",
00000858 => x"f8a02223",
00000859 => x"00008067",
00000860 => x"30046073",
00000861 => x"00008067",
00000862 => x"30047073",
00000863 => x"00008067",
00000864 => x"fb000713",
00000865 => x"00072783",
00000866 => x"ff77f793",
00000867 => x"00f72023",
00000860 => x"fb800713",
00000861 => x"00072783",
00000862 => x"ffe7f793",
00000863 => x"00f72023",
00000864 => x"00008067",
00000865 => x"30046073",
00000866 => x"00008067",
00000867 => x"30047073",
00000868 => x"00008067",
00000869 => x"f8800713",
00000869 => x"fb000713",
00000870 => x"00072783",
00000871 => x"fef7f793",
00000871 => x"ff77f793",
00000872 => x"00f72023",
00000873 => x"00008067",
00000874 => x"69617641",
00000875 => x"6c62616c",
00000876 => x"4d432065",
00000877 => x"0a3a7344",
00000878 => x"203a6820",
00000879 => x"706c6548",
00000880 => x"3a72200a",
00000881 => x"73655220",
00000882 => x"74726174",
00000883 => x"3a75200a",
00000884 => x"6c705520",
00000885 => x"0a64616f",
00000886 => x"203a7320",
00000887 => x"726f7453",
00000888 => x"6f742065",
00000889 => x"616c6620",
00000890 => x"200a6873",
00000891 => x"4c203a6c",
00000892 => x"2064616f",
00000893 => x"6d6f7266",
00000874 => x"f8800713",
00000875 => x"00072783",
00000876 => x"fef7f793",
00000877 => x"00f72023",
00000878 => x"00008067",
00000879 => x"69617641",
00000880 => x"6c62616c",
00000881 => x"4d432065",
00000882 => x"0a3a7344",
00000883 => x"203a6820",
00000884 => x"706c6548",
00000885 => x"3a72200a",
00000886 => x"73655220",
00000887 => x"74726174",
00000888 => x"3a75200a",
00000889 => x"6c705520",
00000890 => x"0a64616f",
00000891 => x"203a7320",
00000892 => x"726f7453",
00000893 => x"6f742065",
00000894 => x"616c6620",
00000895 => x"200a6873",
00000896 => x"45203a65",
00000897 => x"75636578",
00000898 => x"00006574",
00000899 => x"65206f4e",
00000900 => x"75636578",
00000901 => x"6c626174",
00000902 => x"76612065",
00000903 => x"616c6961",
00000904 => x"2e656c62",
00000905 => x"00000000",
00000906 => x"746f6f42",
00000907 => x"2e676e69",
00000908 => x"0a0a2e2e",
00000909 => x"00000000",
00000910 => x"52450a07",
00000911 => x"00005f52",
00000912 => x"6e6b6e75",
00000913 => x"006e776f",
00000914 => x"00007830",
00000915 => x"58450a0a",
00000916 => x"54504543",
00000917 => x"3a4e4f49",
00000918 => x"00000020",
00000919 => x"30204020",
00000920 => x"00000078",
00000921 => x"69617741",
00000922 => x"676e6974",
00000923 => x"6f656e20",
00000924 => x"32337672",
00000925 => x"6578655f",
00000926 => x"6e69622e",
00000927 => x"202e2e2e",
00000928 => x"00000000",
00000929 => x"64616f4c",
00000930 => x"2e676e69",
00000931 => x"00202e2e",
00000932 => x"00004b4f",
00000933 => x"74697257",
00000934 => x"78302065",
00000935 => x"00000000",
00000936 => x"74796220",
00000937 => x"74207365",
00000938 => x"5053206f",
00000939 => x"6c662049",
00000940 => x"20687361",
00000941 => x"78302040",
00000942 => x"00000000",
00000943 => x"7928203f",
00000944 => x"20296e2f",
00000945 => x"00000000",
00000946 => x"616c460a",
00000947 => x"6e696873",
00000948 => x"2e2e2e67",
00000949 => x"00000020",
00000950 => x"0a0a0a0a",
00000951 => x"4e203c3c",
00000952 => x"56524f45",
00000953 => x"42203233",
00000954 => x"6c746f6f",
00000955 => x"6564616f",
00000956 => x"3e3e2072",
00000957 => x"4c420a0a",
00000958 => x"203a5644",
00000959 => x"206e754a",
00000960 => x"32203732",
00000961 => x"0a303230",
00000962 => x"3a565748",
00000963 => x"00002020",
00000964 => x"4b4c430a",
00000965 => x"0020203a",
00000966 => x"0a7a4820",
00000967 => x"4153494d",
00000968 => x"0000203a",
00000969 => x"4e4f430a",
00000970 => x"00203a46",
00000971 => x"454d490a",
00000972 => x"00203a4d",
00000973 => x"74796220",
00000974 => x"40207365",
00000975 => x"00000020",
00000976 => x"454d440a",
00000977 => x"00203a4d",
00000978 => x"75410a0a",
00000979 => x"6f626f74",
00000980 => x"6920746f",
00000981 => x"3828206e",
00000982 => x"202e7329",
00000983 => x"73657250",
00000984 => x"656b2073",
00000985 => x"6f742079",
00000986 => x"6f626120",
00000987 => x"0a2e7472",
00000988 => x"00000000",
00000989 => x"0000000a",
00000990 => x"726f6241",
00000991 => x"2e646574",
00000992 => x"00000a0a",
00000993 => x"444d430a",
00000994 => x"00203e3a",
00000995 => x"53207962",
00000996 => x"68706574",
00000997 => x"4e206e61",
00000998 => x"69746c6f",
00000999 => x"0000676e",
00001000 => x"61766e49",
00001001 => x"2064696c",
00001002 => x"00444d43",
00001003 => x"33323130",
00001004 => x"37363534",
00001005 => x"42413938",
00001006 => x"46454443",
00000896 => x"4c203a6c",
00000897 => x"2064616f",
00000898 => x"6d6f7266",
00000899 => x"616c6620",
00000900 => x"200a6873",
00000901 => x"45203a65",
00000902 => x"75636578",
00000903 => x"00006574",
00000904 => x"65206f4e",
00000905 => x"75636578",
00000906 => x"6c626174",
00000907 => x"76612065",
00000908 => x"616c6961",
00000909 => x"2e656c62",
00000910 => x"00000000",
00000911 => x"746f6f42",
00000912 => x"2e676e69",
00000913 => x"0a0a2e2e",
00000914 => x"00000000",
00000915 => x"52450a07",
00000916 => x"00005f52",
00000917 => x"6e6b6e75",
00000918 => x"006e776f",
00000919 => x"00007830",
00000920 => x"58450a0a",
00000921 => x"54504543",
00000922 => x"3a4e4f49",
00000923 => x"00000020",
00000924 => x"30204020",
00000925 => x"00000078",
00000926 => x"69617741",
00000927 => x"676e6974",
00000928 => x"6f656e20",
00000929 => x"32337672",
00000930 => x"6578655f",
00000931 => x"6e69622e",
00000932 => x"202e2e2e",
00000933 => x"00000000",
00000934 => x"64616f4c",
00000935 => x"2e676e69",
00000936 => x"00202e2e",
00000937 => x"00004b4f",
00000938 => x"74697257",
00000939 => x"78302065",
00000940 => x"00000000",
00000941 => x"74796220",
00000942 => x"74207365",
00000943 => x"5053206f",
00000944 => x"6c662049",
00000945 => x"20687361",
00000946 => x"78302040",
00000947 => x"00000000",
00000948 => x"7928203f",
00000949 => x"20296e2f",
00000950 => x"00000000",
00000951 => x"616c460a",
00000952 => x"6e696873",
00000953 => x"2e2e2e67",
00000954 => x"00000020",
00000955 => x"0a0a0a0a",
00000956 => x"4e203c3c",
00000957 => x"56524f45",
00000958 => x"42203233",
00000959 => x"6c746f6f",
00000960 => x"6564616f",
00000961 => x"3e3e2072",
00000962 => x"4c420a0a",
00000963 => x"203a5644",
00000964 => x"206c754a",
00000965 => x"32203520",
00000966 => x"0a303230",
00000967 => x"3a565748",
00000968 => x"00002020",
00000969 => x"4b4c430a",
00000970 => x"0020203a",
00000971 => x"0a7a4820",
00000972 => x"4449484d",
00000973 => x"0000203a",
00000974 => x"53494d0a",
00000975 => x"00203a41",
00000976 => x"4e4f430a",
00000977 => x"00203a46",
00000978 => x"454d490a",
00000979 => x"00203a4d",
00000980 => x"74796220",
00000981 => x"40207365",
00000982 => x"00000020",
00000983 => x"454d440a",
00000984 => x"00203a4d",
00000985 => x"75410a0a",
00000986 => x"6f626f74",
00000987 => x"6920746f",
00000988 => x"3828206e",
00000989 => x"202e7329",
00000990 => x"73657250",
00000991 => x"656b2073",
00000992 => x"6f742079",
00000993 => x"6f626120",
00000994 => x"0a2e7472",
00000995 => x"00000000",
00000996 => x"0000000a",
00000997 => x"726f6241",
00000998 => x"2e646574",
00000999 => x"00000a0a",
00001000 => x"444d430a",
00001001 => x"00203e3a",
00001002 => x"53207962",
00001003 => x"68706574",
00001004 => x"4e206e61",
00001005 => x"69746c6f",
00001006 => x"0000676e",
00001007 => x"61766e49",
00001008 => x"2064696c",
00001009 => x"00444d43",
00001010 => x"33323130",
00001011 => x"37363534",
00001012 => x"42413938",
00001013 => x"46454443",
others => x"00000000"
);
 
/neorv32_cpu.vhd
53,6 → 53,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
109,8 → 110,6
signal ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
signal alu_cmp : std_ulogic_vector(1 downto 0); -- alu comparator result
signal imm : std_ulogic_vector(data_width_c-1 downto 0); -- immediate
signal pc : std_ulogic_vector(data_width_c-1 downto 0); -- current program counter
signal pc_delayed : std_ulogic_vector(data_width_c-1 downto 0); -- delayed program counter
signal instr : std_ulogic_vector(data_width_c-1 downto 0); -- new instruction
signal rs1, rs2 : std_ulogic_vector(data_width_c-1 downto 0); -- source registers
signal alu_res : std_ulogic_vector(data_width_c-1 downto 0); -- alu result
127,6 → 126,10
signal be_load : std_ulogic; -- bus error on load data access
signal be_store : std_ulogic; -- bus error on store data access
signal bus_exc_ack : std_ulogic; -- bus exception error acknowledge
signal bus_busy : std_ulogic; -- bus unit is busy
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 next_pc : std_ulogic_vector(data_width_c-1 downto 0); -- next pc (for current executed instruction)
 
-- co-processor interface --
signal cp0_data, cp1_data : std_ulogic_vector(data_width_c-1 downto 0);
139,9 → 142,10
neorv32_cpu_control_inst: neorv32_cpu_control
generic map (
-- General --
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
HART_ID => HART_ID, -- custom hardware thread ID
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader?
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
HART_ID => HART_ID, -- custom hardware thread ID
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader?
CSR_COUNTERS_USE => CSR_COUNTERS_USE, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
186,8 → 190,9
alu_add_i => alu_add, -- ALU.add result
-- data output --
imm_o => imm, -- immediate
pc_o => pc, -- current PC
alu_pc_o => pc_delayed, -- delayed PC for ALU
fetch_pc_o => fetch_pc, -- PC for instruction fetch
curr_pc_o => curr_pc, -- current PC (corresponding to current instruction)
next_pc_o => next_pc, -- next PC (corresponding to current instruction)
-- csr interface --
csr_wdata_i => alu_res, -- CSR write data
csr_rdata_o => csr_rdata, -- CSR read data
202,7 → 207,8
be_instr_i => be_instr, -- bus error on instruction access
be_load_i => be_load, -- bus error on load data access
be_store_i => be_store, -- bus error on store data access
bus_exc_ack_o => bus_exc_ack -- bus exception error acknowledge
bus_exc_ack_o => bus_exc_ack, -- bus exception error acknowledge
bus_busy_i => bus_busy -- bus unit is busy
);
 
 
220,7 → 226,7
mem_i => rdata, -- memory read data
alu_i => alu_res, -- ALU result
csr_i => csr_rdata, -- CSR read data
pc_i => pc, -- current pc
pc_i => next_pc, -- next pc
-- data output --
rs1_o => rs1, -- operand 1
rs2_o => rs2 -- operand 2
230,10 → 236,6
-- ALU ------------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_alu_inst: neorv32_cpu_alu
generic map (
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_M => CPU_EXTENSION_RISCV_M -- implement mul/div extension?
)
port map (
-- global control --
clk_i => clk_i, -- global clock, rising edge
242,8 → 244,7
-- data input --
rs1_i => rs1, -- rf source 1
rs2_i => rs2, -- rf source 2
pc_i => pc, -- current PC
pc2_i => pc_delayed, -- delayed PC
pc2_i => curr_pc, -- delayed PC
imm_i => imm, -- immediate
csr_i => csr_rdata, -- csr read data
-- data output --
296,8 → 297,7
-- -------------------------------------------------------------------------------------------
neorv32_cpu_bus_inst: neorv32_cpu_bus
generic map (
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
MEM_EXT_TIMEOUT => MEM_EXT_TIMEOUT -- cycles after which a valid bus access will timeout
MEM_EXT_TIMEOUT => MEM_EXT_TIMEOUT -- cycles after which a valid bus access will timeout
)
port map (
-- global control --
306,7 → 306,7
ctrl_i => ctrl, -- main control bus
-- data input --
wdata_i => rs2, -- write data
pc_i => pc, -- current PC
pc_i => fetch_pc, -- current PC for instruction fetch
alu_i => alu_res, -- ALU result
-- data output --
instr_o => instr, -- instruction
320,6 → 320,7
be_load_o => be_load, -- bus error on load data access
be_store_o => be_store, -- bus error on store data access
bus_wait_o => bus_wait, -- wait for bus operation to finish
bus_busy_o => bus_busy, -- bus unit is busy
exc_ack_i => bus_exc_ack, -- exception controller ACK
-- bus system --
bus_addr_o => bus_addr_o, -- bus access address
/neorv32_cpu_alu.vhd
42,10 → 42,6
use neorv32.neorv32_package.all;
 
entity neorv32_cpu_alu is
generic (
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_M : boolean := false -- implement mul/div extension?
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
54,7 → 50,6
-- 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
pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- current PC
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
75,7 → 70,7
architecture neorv32_cpu_cpu_rtl of neorv32_cpu_alu is
 
-- operands --
signal opa, opb, opc, pc_inc : std_ulogic_vector(data_width_c-1 downto 0);
signal opa, opb, opc : std_ulogic_vector(data_width_c-1 downto 0);
 
-- results --
signal add_res : std_ulogic_vector(data_width_c-1 downto 0);
109,22 → 104,28
 
-- Operand Mux ----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
input_op_mux: process(ctrl_i, csr_i, pc2_i, pc_i, rs1_i, rs2_i, imm_i, pc_inc)
input_op_mux: process(ctrl_i, csr_i, pc2_i, rs1_i, rs2_i, imm_i)
begin
-- opa (first ALU input operand) --
case ctrl_i(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) is
when "00" => opa <= rs1_i;
when "01" => opa <= pc2_i;
when "10" => opa <= csr_i;
when others => opa <= pc_i;
end case;
if (ctrl_i(ctrl_alu_opa_mux_msb_c) = '0') then
if (ctrl_i(ctrl_alu_opa_mux_lsb_c) = '0') then
opa <= rs1_i;
else
opa <= pc2_i;
end if;
else
opa <= csr_i;
end if;
-- opb (second ALU input operand) --
case ctrl_i(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) is
when "00" => opb <= rs2_i;
when "01" => opb <= imm_i;
when "10" => opb <= rs1_i;
when others => opb <= pc_inc;
end case;
if (ctrl_i(ctrl_alu_opb_mux_msb_c) = '0') then
if (ctrl_i(ctrl_alu_opb_mux_lsb_c) = '0') then
opb <= rs2_i;
else
opb <= imm_i;
end if;
else
opb <= rs1_i;
end if;
-- opc (second operand for comparison (and SUB)) --
if (ctrl_i(ctrl_alu_opc_mux_c) = '0') then
opc <= imm_i;
133,10 → 134,7
end if;
end process input_op_mux;
 
-- PC increment --
pc_inc <= x"00000002" when (CPU_EXTENSION_RISCV_C = true) else x"00000004";
 
 
-- Comparator Unit ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- less than (x < y) --
202,7 → 200,7
cp_rb_ff0 <= '0';
cp_rb_ff1 <= '0';
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_M = true) then
if (ctrl_i(ctrl_sys_m_ext_en_c) = '1') then
cp_cmd_ff <= ctrl_i(ctrl_cp_use_c);
cp_rb_ff0 <= '0';
cp_rb_ff1 <= cp_rb_ff0;
/neorv32_cpu_bus.vhd
43,8 → 43,7
 
entity neorv32_cpu_bus is
generic (
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
);
port (
-- global control --
67,6 → 66,7
be_load_o : out std_ulogic; -- bus error on load data access
be_store_o : out std_ulogic; -- bus error on store data access
bus_wait_o : out std_ulogic; -- wait for bus operation to finish
bus_busy_o : out std_ulogic; -- bus unit is busy
exc_ack_i : in std_ulogic; -- exception controller ACK
-- bus system --
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
113,7 → 113,7
end process mem_adr_reg;
 
-- address output --
bus_addr_o <= pc_i when (ctrl_i(ctrl_bus_if_c) = '1') else mar; -- is instruction fetch?
bus_addr_o <= pc_i when ((bus_if_req or ctrl_i(ctrl_bus_if_c)) = '1') else mar; -- is instruction fetch?
mar_o <= mar;
 
-- write request output --
120,7 → 120,7
bus_we_o <= ctrl_i(ctrl_bus_wr_c) and (not misaligned_data);
 
-- read request output (also used for instruction fetch) --
bus_re_o <= (ctrl_i(ctrl_bus_rd_c) and (not misaligned_data)) or (ctrl_i(ctrl_bus_if_c) and (not misaligned_instr));
bus_re_o <= (ctrl_i(ctrl_bus_rd_c) and (not misaligned_data)) or ((bus_if_req or ctrl_i(ctrl_bus_if_c)) and (not misaligned_instr));
 
 
-- Write Data -----------------------------------------------------------------------------
263,6 → 263,7
ma_store_o <= bus_wr_req and align_err;
 
-- wait for bus --
bus_busy_o <= bus_busy;
bus_wait_o <= bus_busy and (not bus_ack_i); -- FIXME: 'async' ack
 
 
290,11 → 291,9
begin
-- check instruction access --
misaligned_instr <= '0'; -- default
if (CPU_EXTENSION_RISCV_C = true) then -- 16-bit instruction access only
if (pc_i(0) /= '0') then
misaligned_instr <= '1';
end if;
else -- 32-bit instruction access only
if (ctrl_i(ctrl_sys_c_ext_en_c) = '1') then -- 16-bit and 32-bit instruction accesses
misaligned_instr <= '0';
else -- 32-bit instruction accesses only
if (pc_i(1 downto 0) /= "00") then
misaligned_instr <= '1';
end if;
/neorv32_cpu_control.vhd
1,8 → 1,9
-- #################################################################################################
-- # << NEORV32 - CPU Control >> #
-- # ********************************************************************************************* #
-- # FSM to control CPU operations. This unit also includes the control and status registers (CSR) #
-- # and the interrupt and exception controller. #
-- # CPU operation is split into a fetch engine (responsible for fetching an decompressing instr- #
-- # uctions), an execute engine (responsible for actually executing the instructions), an inter- #
-- # rupt and exception handling controller and the RISC-V status and control registers (CSRs). #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
48,6 → 49,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
92,8 → 94,9
alu_add_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU.add result
-- data output --
imm_o : out std_ulogic_vector(data_width_c-1 downto 0); -- immediate
pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC
alu_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC for ALU
fetch_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
curr_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction)
next_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- next PC (corresponding to current instruction)
-- csr data interface --
csr_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- CSR write data
csr_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data
108,90 → 111,151
be_instr_i : in std_ulogic; -- bus error on instruction access
be_load_i : in std_ulogic; -- bus error on load data access
be_store_i : in std_ulogic; -- bus error on store data access
bus_exc_ack_o : out std_ulogic -- bus exception error acknowledge
bus_exc_ack_o : out std_ulogic; -- bus exception error acknowledge
bus_busy_i : in std_ulogic -- bus unit is busy
);
end neorv32_cpu_control;
 
architecture neorv32_cpu_control_rtl of neorv32_cpu_control is
 
-- state machine --
type state_t is (IFETCH_0, IFETCH_1, IFETCH_2, IFETCH_3, IFETCH_4, IFETCH_5, IFETCH_6, EXECUTE,
ALU_WAIT, STORE_0, LOAD_0, LOADSTORE_0, LOADSTORE_1, CSR_ACCESS, SLEEP);
signal state, state_nxt : state_t;
signal ctrl_nxt, ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0);
signal hw_control : std_ulogic_vector(data_width_c-1 downto 0);
-- instruction fetch enginge --
type fetch_engine_state_t is (IFETCH_RESET, IFETCH_0, IFETCH_1, IFETCH_2, IFETCH_3);
type fetch_engine_t is record
state : fetch_engine_state_t;
state_nxt : fetch_engine_state_t;
i_buf : std_ulogic_vector(33 downto 0);
i_buf_nxt : std_ulogic_vector(33 downto 0);
i_buf2 : std_ulogic_vector(33 downto 0);
i_buf2_nxt : std_ulogic_vector(33 downto 0);
ci_reg : std_ulogic_vector(17 downto 0);
ci_reg_nxt : std_ulogic_vector(17 downto 0);
i_buf_state : std_ulogic_vector(01 downto 0);
i_buf_state_nxt : std_ulogic_vector(01 downto 0);
pc_real : std_ulogic_vector(data_width_c-1 downto 0);
pc_real_add : std_ulogic_vector(data_width_c-1 downto 0);
pc_fetch : std_ulogic_vector(data_width_c-1 downto 0);
pc_fetch_add : std_ulogic_vector(data_width_c-1 downto 0);
ci_return : std_ulogic;
ci_return_nxt : std_ulogic;
reset : std_ulogic;
bus_err_ack : std_ulogic;
end record;
signal fetch_engine : fetch_engine_t;
 
-- pre-decoder --
signal ci_instr32 : std_ulogic_vector(31 downto 0);
signal ci_valid : std_ulogic;
signal ci_illegal : std_ulogic;
 
-- instruction register --
signal i_reg, i_reg_nxt : std_ulogic_vector(31 downto 0);
signal i_buf, i_buf_nxt : std_ulogic_vector(15 downto 0);
signal ci_reg, ci_reg_nxt : std_ulogic_vector(15 downto 0);
signal iavail, iavail_nxt : std_ulogic;
signal is_ci, is_ci_nxt : std_ulogic; -- current instruction is COMPRESSED instruction flag
-- instrucion prefetch buffer (IPB) --
type ipb_t is record
wdata : std_ulogic_vector(34 downto 0);
rdata : std_ulogic_vector(34 downto 0);
waddr : std_ulogic_vector(31 downto 0);
raddr : std_ulogic_vector(31 downto 0);
status : std_ulogic;
free : std_ulogic;
avail : std_ulogic;
we : std_ulogic;
re : std_ulogic;
clear : std_ulogic;
end record;
signal ipb : ipb_t;
 
-- immediates --
signal imm_reg : std_ulogic_vector(data_width_c-1 downto 0);
-- instruction execution engine --
type execute_engine_state_t is (IDLE, DISPATCH, TRAP, EXECUTE, ALU_WAIT, BRANCH, STORE, LOAD, LOADSTORE_0, LOADSTORE_1, CSR_ACCESS);
type execute_engine_t is record
state : execute_engine_state_t;
state_nxt : execute_engine_state_t;
state_prev : execute_engine_state_t;
i_reg : std_ulogic_vector(31 downto 0);
i_reg_nxt : std_ulogic_vector(31 downto 0);
is_ci : std_ulogic; -- current instruction is de-compressed instruction
is_ci_nxt : std_ulogic;
is_jump : std_ulogic; -- current instruction is jump instruction
is_jump_nxt : std_ulogic;
branch_taken : std_ulogic; -- branch condition fullfilled
pc : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC, corresponding to current executed instruction
pc_nxt : std_ulogic_vector(data_width_c-1 downto 0);
next_pc : std_ulogic_vector(data_width_c-1 downto 0); -- next PC, corresponding to next instruction to be executed
last_pc : std_ulogic_vector(data_width_c-1 downto 0); -- PC of last executed instruction
end record;
signal execute_engine : execute_engine_t;
 
-- branch system --
signal is_branch : std_ulogic;
signal is_branch_nxt : std_ulogic;
signal branch_taken : std_ulogic;
-- trap controller --
type trap_ctrl_t is record
exc_buf : std_ulogic_vector(exception_width_c-1 downto 0);
exc_fire : std_ulogic; -- set if there is a valid source in the exception buffer
irq_buf : std_ulogic_vector(interrupt_width_c-1 downto 0);
irq_fire : std_ulogic; -- set if there is a valid source in the interrupt buffer
exc_ack : std_ulogic; -- acknowledge all exceptions
irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0); -- acknowledge specific interrupt
irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0);
cause : std_ulogic_vector(data_width_c-1 downto 0); -- trap ID (for "mcause")
cause_nxt : std_ulogic_vector(data_width_c-1 downto 0);
instr : std_ulogic_vector(31 downto 0); -- faulting instruction
exc_src : std_ulogic_vector(exception_width_c-1 downto 0);
--
env_start : std_ulogic; -- start trap handler env
env_start_ack : std_ulogic; -- start of trap handler acknowledged
env_end : std_ulogic; -- end trap handler env
--
instr_be : std_ulogic; -- instruction fetch bus error
instr_ma : std_ulogic; -- instruction fetch misaligned address
instr_il : std_ulogic; -- illegal instruction
env_call : std_ulogic;
break_point : std_ulogic;
end record;
signal trap_ctrl : trap_ctrl_t;
-- CPU control signals --
signal ctrl_nxt, ctrl : std_ulogic_vector(ctrl_width_c-1 downto 0);
 
-- program counter --
signal pc_reg : std_ulogic_vector(data_width_c-1 downto 0); -- actual PC
signal pc_backup_reg : std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC (for ALU operations)
signal pc_backup2_reg : std_ulogic_vector(data_width_c-1 downto 0); -- delayed delayed PC (for exception handling)
signal mepc : std_ulogic_vector(data_width_c-1 downto 0); -- exception PC
-- fast bus access --
signal bus_fast_ir : std_ulogic;
signal bus_fast_rd : std_ulogic;
signal bus_fast_wr : std_ulogic;
 
-- irq controller --
signal exc_buf : std_ulogic_vector(exception_width_c-1 downto 0);
signal exc_ack : std_ulogic;
signal exc_src : std_ulogic_vector(exception_width_c-1 downto 0);
signal exc_fire : std_ulogic;
signal irq_buf : std_ulogic_vector(interrupt_width_c-1 downto 0);
signal irq_ack : std_ulogic_vector(interrupt_width_c-1 downto 0);
signal irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0);
signal irq_fire : std_ulogic;
signal exc_cpu_start : std_ulogic; -- starting exception env
signal exc_cpu_ack : std_ulogic; -- starting of exception env acknowledge
signal exc_cpu_end : std_ulogic; -- exiting eception env
signal exc_cause : std_ulogic_vector(data_width_c-1 downto 0);
signal exc_cause_nxt : std_ulogic_vector(data_width_c-1 downto 0);
-- RISC-V control and status registers (CSRs) --
type csr_t is record
we : std_ulogic; -- write enable
we_nxt : std_ulogic;
re : std_ulogic; -- read enable
re_nxt : std_ulogic;
mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W)
mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-)
mip_msip : std_ulogic; -- mip.MSIP: machine software interrupt pending (R/W)
mie_msie : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
mie_meie : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
mie_mtie : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W)
mepc : std_ulogic_vector(data_width_c-1 downto 0); -- mepc: machine exception pc (R/W)
mcause : std_ulogic_vector(data_width_c-1 downto 0); -- mcause: machine trap cause (R/-)
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W)
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/-)
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
mtinst : std_ulogic_vector(data_width_c-1 downto 0); -- mtinst: machine trap instruction (transformed) (R/-)
cycle : std_ulogic_vector(32 downto 0); -- cycle, mtime (R/-), plus carry bit
instret : std_ulogic_vector(32 downto 0); -- instret (R/-), plus carry bit
cycleh : std_ulogic_vector(31 downto 0); -- cycleh, mtimeh (R/-)
instreth : std_ulogic_vector(31 downto 0); -- instreth (R/-)
misa_c_en : std_ulogic; -- misa: C extension enable bit (R/W)
misa_m_en : std_ulogic; -- misa: M extension enable bit (R/W)
end record;
signal csr : csr_t;
 
-- RISC-V CSRs --
signal mstatus_mie : std_ulogic; -- mstatus.MIE: global IRQ enable (R/W)
signal mstatus_mpie : std_ulogic; -- mstatus.MPIE: previous global IRQ enable (R/-)
signal mip_msip : std_ulogic; -- mip.MSIP: machine software interrupt pending (R/W)
signal mie_msie : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
signal mie_meie : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
signal mie_mtie : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W)
signal mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W)
signal mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/-)
signal mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
signal mtinst : std_ulogic_vector(data_width_c-1 downto 0); -- mtinst: machine trap instruction (transformed) (R/-)
signal cycle_lo : std_ulogic_vector(32 downto 0); -- cycle, mtime (R/-)
signal instret_lo : std_ulogic_vector(32 downto 0); -- instret (R/-)
signal cycle_hi : std_ulogic_vector(15 downto 0); -- cycleh, mtimeh (R/-) - only 16-bit wide
signal instret_hi : std_ulogic_vector(15 downto 0); -- instreth (R/-) - only 16-bit wide
signal cycle_lo_msb : std_ulogic;
signal instret_lo_msb : std_ulogic;
signal cycle_msb : std_ulogic;
signal instret_msb : std_ulogic;
 
-- illegal instruction check ..
-- illegal instruction check --
signal illegal_instruction : std_ulogic;
signal illegal_register : std_ulogic; -- only for E-extension
signal illegal_compressed : std_ulogic; -- only fir C-extension
 
-- synchronous exceptions trigger --
signal illegal_instr_exc : std_ulogic;
signal env_call : std_ulogic;
signal break_point : std_ulogic;
 
begin
 
-- ****************************************************************************************************************************
-- Instruction Fetch
-- ****************************************************************************************************************************
 
-- Compressed Instructions Recoding -------------------------------------------------------
-- -------------------------------------------------------------------------------------------
neorv32_cpu_decompressor_inst_true:
199,9 → 263,8
neorv32_cpu_decompressor_inst: neorv32_cpu_decompressor
port map (
-- instruction input --
ci_instr16_i => ci_reg, -- compressed instruction input
ci_instr16_i => fetch_engine.ci_reg(15 downto 0), -- compressed instruction input
-- instruction output --
ci_valid_o => ci_valid, -- is a compressed instruction
ci_illegal_o => ci_illegal, -- is an illegal compressed instruction
ci_instr32_o => ci_instr32 -- 32-bit decompressed instruction
);
209,290 → 272,460
 
neorv32_cpu_decompressor_inst_false:
if (CPU_EXTENSION_RISCV_C = false) generate
ci_instr32 <= instr_i;
ci_valid <= '0';
ci_instr32 <= (others => '0');
ci_illegal <= '0';
end generate;
 
 
-- Fetch Engine FSM Sync ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
-- for registers that require a specific reset state --
fetch_engine_fsm_sync_rst: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
fetch_engine.state <= IFETCH_RESET;
elsif rising_edge(clk_i) then
if (fetch_engine.reset = '1') then
fetch_engine.state <= IFETCH_RESET;
else
fetch_engine.state <= fetch_engine.state_nxt;
end if;
end if;
end process fetch_engine_fsm_sync_rst;
 
 
-- for registers that DO NOT require a specific reset state --
fetch_engine_fsm_sync: process(clk_i)
begin
if rising_edge(clk_i) then
if (fetch_engine.state = IFETCH_RESET) then
fetch_engine.pc_fetch <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC
fetch_engine.pc_real <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC
else
fetch_engine.pc_real <= std_ulogic_vector(unsigned(fetch_engine.pc_real(data_width_c-1 downto 1) & '0') + unsigned(fetch_engine.pc_real_add(data_width_c-1 downto 1) & '0'));
fetch_engine.pc_fetch <= std_ulogic_vector(unsigned(fetch_engine.pc_fetch(data_width_c-1 downto 1) & '0') + unsigned(fetch_engine.pc_fetch_add(data_width_c-1 downto 1) & '0'));
end if;
--
fetch_engine.i_buf <= fetch_engine.i_buf_nxt;
fetch_engine.i_buf2 <= fetch_engine.i_buf2_nxt;
fetch_engine.i_buf_state <= fetch_engine.i_buf_state_nxt;
--
fetch_engine.ci_reg <= fetch_engine.ci_reg_nxt;
fetch_engine.ci_return <= fetch_engine.ci_return_nxt;
end if;
end process fetch_engine_fsm_sync;
 
 
-- Fetch Engine FSM Comb ------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
fetch_engine_fsm_comb: process(fetch_engine, execute_engine, csr, ipb, instr_i, bus_wait_i, bus_busy_i, ci_instr32, be_instr_i, ma_instr_i)
begin
-- arbiter defaults --
fetch_engine.state_nxt <= fetch_engine.state;
fetch_engine.pc_fetch_add <= (others => '0');
fetch_engine.pc_real_add <= (others => '0');
bus_fast_ir <= '0';
fetch_engine.i_buf_nxt <= fetch_engine.i_buf;
fetch_engine.i_buf2_nxt <= fetch_engine.i_buf2;
fetch_engine.i_buf_state_nxt <= fetch_engine.i_buf_state;
fetch_engine.ci_reg_nxt <= fetch_engine.ci_reg;
fetch_engine.ci_return_nxt <= fetch_engine.ci_return;
fetch_engine.bus_err_ack <= '0';
 
-- instruction prefetch buffer interface --
ipb.we <= '0';
ipb.clear <= '0';
ipb.wdata <= fetch_engine.i_buf2(33 downto 32) & '0' & fetch_engine.i_buf2(31 downto 0);
ipb.waddr <= fetch_engine.pc_real(data_width_c-1 downto 1) & '0';
 
-- state machine --
case fetch_engine.state is
 
when IFETCH_RESET => -- reset engine, prefetch buffer, get PC
-- ------------------------------------------------------------
fetch_engine.i_buf_state_nxt <= (others => '0');
fetch_engine.ci_return_nxt <= '0';
ipb.clear <= '1'; -- clear instruction prefetch buffer
fetch_engine.bus_err_ack <= '1'; -- ack bus errors, the execute engine has to take care of them
fetch_engine.state_nxt <= IFETCH_0;
 
when IFETCH_0 => -- output current PC to bus system, request 32-bit word
-- ------------------------------------------------------------
if (bus_busy_i = '0') and (execute_engine.state /= LOAD) and (execute_engine.state /= STORE) and
(execute_engine.state /= LOADSTORE_0) and (execute_engine.state /= LOADSTORE_1) then -- wait if execute engine is using bus unit
bus_fast_ir <= '1'; -- fast instruction fetch request (output PC to bus.address)
fetch_engine.state_nxt <= IFETCH_1;
end if;
 
when IFETCH_1 => -- store data from memory to buffer(s)
-- ------------------------------------------------------------
fetch_engine.i_buf_nxt <= be_instr_i & ma_instr_i & instr_i(31 downto 0); -- store data word and exception info
if (bus_wait_i = '0') then -- wait for bus response
fetch_engine.i_buf2_nxt <= fetch_engine.i_buf;
fetch_engine.i_buf_state_nxt(1) <= fetch_engine.i_buf_state(0);
fetch_engine.state_nxt <= IFETCH_2;
end if;
fetch_engine.i_buf_state_nxt(0) <= '1';
if (be_instr_i = '1') or (ma_instr_i = '1') then -- any fetch exception?
fetch_engine.bus_err_ack <= '1'; -- ack bus errors, the execute engine has to take care of them
end if;
 
when IFETCH_2 => -- construct instruction and issue
-- ------------------------------------------------------------
if (fetch_engine.i_buf_state(1) = '1') then
if (fetch_engine.pc_fetch(1) = '0') or (CPU_EXTENSION_RISCV_C = false) or (csr.misa_c_en = '0') then -- 32-bit aligned
fetch_engine.ci_reg_nxt <= fetch_engine.i_buf2(33 downto 32) & fetch_engine.i_buf2(15 downto 00);
ipb.wdata <= fetch_engine.i_buf2(33 downto 32) & '0' & fetch_engine.i_buf2(31 downto 0);
if (fetch_engine.i_buf2(01 downto 00) = "11") or (CPU_EXTENSION_RISCV_C = false) or (csr.misa_c_en = '0') then -- uncompressed
if (ipb.free = '1') then -- free entry in buffer?
ipb.we <= '1';
fetch_engine.pc_real_add <= std_ulogic_vector(to_unsigned(4, data_width_c));
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(4, data_width_c));
fetch_engine.state_nxt <= IFETCH_0;
end if;
else -- compressed
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(2, data_width_c));
fetch_engine.ci_return_nxt <= '1'; -- come back here after issueing
fetch_engine.state_nxt <= IFETCH_3;
end if;
else -- 16-bit aligned
fetch_engine.ci_reg_nxt <= fetch_engine.i_buf2(33 downto 32) & fetch_engine.i_buf2(31 downto 16);
ipb.wdata <= fetch_engine.i_buf(33 downto 32) & '0' & fetch_engine.i_buf(15 downto 00) & fetch_engine.i_buf2(31 downto 16);
if (fetch_engine.i_buf2(17 downto 16) = "11") then -- uncompressed
if (ipb.free = '1') then -- free entry in buffer?
ipb.we <= '1';
fetch_engine.pc_real_add <= std_ulogic_vector(to_unsigned(4, data_width_c));
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(4, data_width_c));
fetch_engine.state_nxt <= IFETCH_0;
end if;
else -- compressed
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(2, data_width_c));
fetch_engine.ci_return_nxt <= '0'; -- start next fetch after issueing
fetch_engine.state_nxt <= IFETCH_3;
end if;
end if;
else
fetch_engine.pc_fetch_add <= std_ulogic_vector(to_unsigned(4, data_width_c));
fetch_engine.state_nxt <= IFETCH_0;
end if;
 
when IFETCH_3 => -- additional cycle for issueing decompressed instructions
-- ------------------------------------------------------------
if (ipb.free = '1') then -- free entry in buffer?
ipb.we <= '1';
ipb.wdata <= fetch_engine.ci_reg(17 downto 16) & '1' & ci_instr32;
fetch_engine.pc_real_add <= std_ulogic_vector(to_unsigned(2, data_width_c));
if (fetch_engine.ci_return = '0') then
fetch_engine.state_nxt <= IFETCH_0;
else
fetch_engine.state_nxt <= IFETCH_2;
end if;
end if;
 
when others => -- undefined
-- ------------------------------------------------------------
fetch_engine.state_nxt <= IFETCH_RESET;
 
end case;
end process fetch_engine_fsm_comb;
 
 
-- ****************************************************************************************************************************
-- Instruction Prefetch Buffer
-- ****************************************************************************************************************************
 
 
-- Instruction Prefetch Buffer Stage ------------------------------------------------------
-- -------------------------------------------------------------------------------------------
instr_prefetch_buffer: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
ipb.status <= '0';
ipb.rdata <= (others => '0');
ipb.raddr <= (others => '0');
elsif rising_edge(clk_i) then
if (ipb.clear = '1') then
ipb.status <= '0';
elsif (ipb.we = '1') then
ipb.status <= '1';
elsif (ipb.re = '1') then
ipb.status <= '0';
end if;
if (ipb.we = '1') then
ipb.rdata <= ipb.wdata;
ipb.raddr <= ipb.waddr;
end if;
end if;
end process instr_prefetch_buffer;
 
-- status --
ipb.free <= not ipb.status;
ipb.avail <= ipb.status;
 
 
-- ****************************************************************************************************************************
-- Instruction Execution
-- ****************************************************************************************************************************
 
 
-- Immediate Generator --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imm_gen: process(clk_i)
begin
if rising_edge(clk_i) then
-- default: I-immediate --
imm_reg(31 downto 11) <= (others => i_reg(31)); -- sign extension
imm_reg(10 downto 05) <= i_reg(30 downto 25);
imm_reg(04 downto 01) <= i_reg(24 downto 21);
imm_reg(00) <= i_reg(20);
case i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
when opcode_store_c => -- S-immediate
imm_reg(31 downto 11) <= (others => i_reg(31)); -- sign extension
imm_reg(10 downto 05) <= i_reg(30 downto 25);
imm_reg(04 downto 01) <= i_reg(11 downto 08);
imm_reg(00) <= i_reg(07);
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
imm_o(00) <= execute_engine.i_reg(07);
when opcode_branch_c => -- B-immediate
imm_reg(31 downto 12) <= (others => i_reg(31)); -- sign extension
imm_reg(11) <= i_reg(07);
imm_reg(10 downto 05) <= i_reg(30 downto 25);
imm_reg(04 downto 01) <= i_reg(11 downto 08);
imm_reg(00) <= '0';
imm_o(31 downto 12) <= (others => execute_engine.i_reg(31)); -- sign extension
imm_o(11) <= execute_engine.i_reg(07);
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
imm_o(00) <= '0';
when opcode_lui_c | opcode_auipc_c => -- U-immediate
imm_reg(31 downto 20) <= i_reg(31 downto 20);
imm_reg(19 downto 12) <= i_reg(19 downto 12);
imm_reg(11 downto 00) <= (others => '0');
imm_o(31 downto 20) <= execute_engine.i_reg(31 downto 20);
imm_o(19 downto 12) <= execute_engine.i_reg(19 downto 12);
imm_o(11 downto 00) <= (others => '0');
when opcode_jal_c => -- J-immediate
imm_reg(31 downto 20) <= (others => i_reg(31)); -- sign extension
imm_reg(19 downto 12) <= i_reg(19 downto 12);
imm_reg(11) <= i_reg(20);
imm_reg(10 downto 05) <= i_reg(30 downto 25);
imm_reg(04 downto 01) <= i_reg(24 downto 21);
imm_reg(00) <= '0';
imm_o(31 downto 20) <= (others => execute_engine.i_reg(31)); -- sign extension
imm_o(19 downto 12) <= execute_engine.i_reg(19 downto 12);
imm_o(11) <= execute_engine.i_reg(20);
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
imm_o(04 downto 01) <= execute_engine.i_reg(24 downto 21);
imm_o(00) <= '0';
when opcode_syscsr_c => -- CSR-immediate
imm_reg(31 downto 05) <= (others => '0');
imm_reg(04 downto 00) <= i_reg(19 downto 15);
imm_o(31 downto 05) <= (others => '0');
imm_o(04 downto 00) <= execute_engine.i_reg(19 downto 15);
when others => -- I-immediate
imm_reg(31 downto 11) <= (others => i_reg(31)); -- sign extension
imm_reg(10 downto 05) <= i_reg(30 downto 25);
imm_reg(04 downto 01) <= i_reg(24 downto 21);
imm_reg(00) <= i_reg(20);
imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
imm_o(04 downto 01) <= execute_engine.i_reg(24 downto 21);
imm_o(00) <= execute_engine.i_reg(20);
end case;
end if;
end process imm_gen;
 
-- output --
imm_o <= imm_reg;
 
 
-- Branch Condition Check -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
branch_check: process(i_reg, cmp_i)
branch_check: process(execute_engine.i_reg, cmp_i)
begin
case i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_beq_c => -- branch if equal
branch_taken <= cmp_i(alu_cmp_equal_c);
execute_engine.branch_taken <= cmp_i(alu_cmp_equal_c);
when funct3_bne_c => -- branch if not equal
branch_taken <= not cmp_i(alu_cmp_equal_c);
execute_engine.branch_taken <= not cmp_i(alu_cmp_equal_c);
when funct3_blt_c | funct3_bltu_c => -- branch if less (signed/unsigned)
branch_taken <= cmp_i(alu_cmp_less_c);
execute_engine.branch_taken <= cmp_i(alu_cmp_less_c);
when funct3_bge_c | funct3_bgeu_c => -- branch if greater or equal (signed/unsigned)
branch_taken <= not cmp_i(alu_cmp_less_c);
execute_engine.branch_taken <= not cmp_i(alu_cmp_less_c);
when others => -- undefined
branch_taken <= '0';
execute_engine.branch_taken <= '0';
end case;
end process branch_check;
 
 
-- Arbiter State Machine Sync -------------------------------------------------------------
-- Execute Engine FSM Sync ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
arbiter_sync_rst: process(rstn_i, clk_i)
-- for registers that require a specific reset state --
execute_engine_fsm_sync_rst: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
-- these registers REQUIRE a specific reset state
state <= IFETCH_0;
if (BOOTLOADER_USE = true) then -- boot from bootloader ROM
execute_engine.pc <= boot_base_c(data_width_c-1 downto 1) & '0';
execute_engine.last_pc <= boot_base_c(data_width_c-1 downto 1) & '0';
else -- boot from IMEM
execute_engine.pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0';
execute_engine.last_pc <= MEM_ISPACE_BASE(data_width_c-1 downto 1) & '0';
end if;
execute_engine.state <= IDLE;
execute_engine.state_prev <= IDLE;
elsif rising_edge(clk_i) then
state <= state_nxt;
execute_engine.pc <= execute_engine.pc_nxt(data_width_c-1 downto 1) & '0';
if (execute_engine.state = EXECUTE) then
execute_engine.last_pc <= execute_engine.pc(data_width_c-1 downto 1) & '0';
end if;
execute_engine.state <= execute_engine.state_nxt;
execute_engine.state_prev <= execute_engine.state;
end if;
end process arbiter_sync_rst;
end process execute_engine_fsm_sync_rst;
 
arbiter_sync: process(clk_i)
 
-- for registers that DO NOT require a specific reset state --
execute_engine_fsm_sync: process(clk_i)
begin
if rising_edge(clk_i) then
-- these registers do not need a specific reset state
ctrl <= ctrl_nxt;
i_reg <= i_reg_nxt;
i_buf <= i_buf_nxt;
ci_reg <= ci_reg_nxt;
iavail <= iavail_nxt;
is_ci <= is_ci_nxt;
is_branch <= is_branch_nxt;
execute_engine.i_reg <= execute_engine.i_reg_nxt;
execute_engine.is_ci <= execute_engine.is_ci_nxt;
execute_engine.is_jump <= execute_engine.is_jump_nxt;
-- control signals --
ctrl <= ctrl_nxt;
end if;
end process arbiter_sync;
end process execute_engine_fsm_sync;
 
-- control bus output --
ctrl_outpu: process(ctrl, i_reg)
 
-- PC output --
execute_engine.next_pc <= std_ulogic_vector(unsigned(execute_engine.pc(data_width_c-1 downto 1) & '0') + 2) when (execute_engine.is_ci = '1') else
std_ulogic_vector(unsigned(execute_engine.pc(data_width_c-1 downto 1) & '0') + 4);
fetch_pc_o <= fetch_engine.pc_fetch(data_width_c-1 downto 1) & '0';
curr_pc_o <= execute_engine.pc(data_width_c-1 downto 1) & '0';
next_pc_o <= execute_engine.next_pc(data_width_c-1 downto 1) & '0';
 
 
-- CPU Control Bus Output -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
ctrl_output: process(ctrl, execute_engine, csr, bus_fast_ir, bus_fast_rd, bus_fast_wr)
begin
ctrl_o <= ctrl;
-- direct output of register addresses --
ctrl_o(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) <= i_reg(instr_rd_msb_c downto instr_rd_lsb_c);
ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c);
ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c);
end process ctrl_outpu;
ctrl_o(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) <= execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c);
ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c);
ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= execute_engine.i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c);
-- bus access requests --
ctrl_o(ctrl_bus_if_c) <= ctrl(ctrl_bus_if_c) or bus_fast_ir;
ctrl_o(ctrl_bus_rd_c) <= ctrl(ctrl_bus_rd_c) or bus_fast_rd;
ctrl_o(ctrl_bus_wr_c) <= ctrl(ctrl_bus_wr_c) or bus_fast_wr;
-- cpu extension control --
ctrl_o(ctrl_sys_c_ext_en_c) <= csr.misa_c_en; -- C extension enabled
ctrl_o(ctrl_sys_m_ext_en_c) <= csr.misa_m_en; -- M extension enabled
end process ctrl_output;
 
 
-- Arbiter State Machine Comb -----------------------------------------------
-- -----------------------------------------------------------------------------
arbiter_comb: process(state, ctrl, i_reg, alu_wait_i, bus_wait_i, exc_cpu_start, ma_load_i, be_load_i, ma_store_i, be_store_i,
ci_reg, i_buf, instr_i, is_ci, iavail, pc_backup_reg, ci_valid, ci_instr32)
-- Execute Engine FSM Comb ----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
execute_engine_fsm_comb: process(execute_engine, fetch_engine, ipb, trap_ctrl, csr, ctrl,
alu_add_i, alu_wait_i, bus_wait_i, ma_load_i, be_load_i, ma_store_i, be_store_i)
variable alu_immediate_v : std_ulogic;
variable alu_operation_v : std_ulogic_vector(2 downto 0);
variable rd_is_r0_v : std_ulogic;
variable rs1_is_r0_v : std_ulogic;
begin
-- arbiter defaults --
state_nxt <= state;
is_branch_nxt <= '0';
exc_cpu_ack <= '0';
exc_cpu_end <= '0';
execute_engine.state_nxt <= execute_engine.state;
execute_engine.i_reg_nxt <= execute_engine.i_reg;
execute_engine.is_jump_nxt <= '0';
execute_engine.is_ci_nxt <= execute_engine.is_ci;
execute_engine.pc_nxt <= execute_engine.pc(data_width_c-1 downto 1) & '0';
 
i_reg_nxt <= i_reg;
i_buf_nxt <= i_buf;
ci_reg_nxt <= ci_reg;
iavail_nxt <= iavail;
is_ci_nxt <= is_ci;
-- instruction dispatch --
fetch_engine.reset <= '0';
ipb.re <= '0';
 
-- trap environment control --
trap_ctrl.env_start_ack <= '0';
trap_ctrl.env_end <= '0';
 
-- bus access (fast) --
bus_fast_rd <= '0';
bus_fast_wr <= '0';
 
-- exception trigger --
env_call <= '0';
break_point <= '0';
trap_ctrl.instr_be <= '0';
trap_ctrl.instr_ma <= '0';
trap_ctrl.env_call <= '0';
trap_ctrl.break_point <= '0';
 
-- CSR access --
csr.we_nxt <= '0';
csr.re_nxt <= '0';
 
-- control defaults --
ctrl_nxt <= (others => '0'); -- all off at first
ctrl_nxt(ctrl_bus_unsigned_c) <= i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU)
if (i_reg(instr_opcode_lsb_c+4) = '1') then -- ALU ops
ctrl_nxt(ctrl_alu_unsigned_c) <= i_reg(instr_funct3_lsb_c+0); -- unsigned ALU operation (SLTIU, SLTU)
ctrl_nxt(ctrl_bus_unsigned_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- unsigned LOAD (LBU, LHU)
if (execute_engine.i_reg(instr_opcode_lsb_c+4) = '1') then -- ALU ops
ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- unsigned ALU operation (SLTIU, SLTU)
else -- branches
ctrl_nxt(ctrl_alu_unsigned_c) <= i_reg(instr_funct3_lsb_c+1); -- unsigned branches (BLTU, BGEU)
ctrl_nxt(ctrl_alu_unsigned_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- unsigned branches (BLTU, BGEU)
end if;
ctrl_nxt(ctrl_alu_shift_dir_c) <= i_reg(instr_funct3_msb_c); -- shift direction
ctrl_nxt(ctrl_alu_shift_ar_c) <= i_reg(30); -- arithmetic shift
ctrl_nxt(ctrl_bus_size_lsb_c) <= i_reg(instr_funct3_lsb_c+0); -- transfer size lsb (00=byte, 01=half-word)
ctrl_nxt(ctrl_bus_size_msb_c) <= i_reg(instr_funct3_lsb_c+1); -- transfer size msb (10=word, 11=?)
ctrl_nxt(ctrl_alu_shift_dir_c) <= execute_engine.i_reg(instr_funct3_msb_c); -- shift direction
ctrl_nxt(ctrl_alu_shift_ar_c) <= execute_engine.i_reg(30); -- arithmetic shift
ctrl_nxt(ctrl_bus_size_lsb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+0); -- transfer size lsb (00=byte, 01=half-word)
ctrl_nxt(ctrl_bus_size_msb_c) <= execute_engine.i_reg(instr_funct3_lsb_c+1); -- transfer size msb (10=word, 11=?)
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = add
ctrl_nxt(ctrl_cp_cmd2_c downto ctrl_cp_cmd0_c) <= i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c); -- CP operation
ctrl_nxt(ctrl_cp_cmd2_c downto ctrl_cp_cmd0_c) <= execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c); -- CP operation
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- only CP0 implemented yet
 
-- is immediate operation? --
alu_immediate_v := '0';
if (i_reg(instr_opcode_msb_c-1) = '0') then
if (execute_engine.i_reg(instr_opcode_msb_c-1) = '0') then
alu_immediate_v := '1';
end if;
 
-- hardware branch operation control --
hw_control(31 downto 24) <= ('0' & funct3_bne_c) & ('1' & funct3_bne_c);
hw_control(23 downto 16) <= funct3_xor_c & funct3_slt_c & "00";
hw_control(15 downto 08) <= funct3_beq_c & funct3_bne_c & "11";
hw_control(07 downto 00) <= funct3_beq_c & funct3_bne_c & "00";
 
-- alu operation --
case i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
-- alu operation re-coding --
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_subadd_c => -- SUB / ADD(I)
if (alu_immediate_v = '0') and (i_reg(instr_funct7_msb_c-1) = '1') then -- not immediate and funct7 = SUB
if (alu_immediate_v = '0') and (execute_engine.i_reg(instr_funct7_msb_c-1) = '1') then -- not immediate and funct7 = SUB
alu_operation_v := alu_cmd_sub_c;
else
alu_operation_v := alu_cmd_add_c;
end if;
when funct3_sll_c => alu_operation_v := alu_cmd_shift_c; -- SLL(I)
when funct3_slt_c => alu_operation_v := alu_cmd_slt_c; -- SLT(I)
when funct3_sltu_c => alu_operation_v := alu_cmd_slt_c; -- SLTU(I)
when funct3_xor_c => alu_operation_v := alu_cmd_xor_c; -- XOR(I)
when funct3_slt_c => alu_operation_v := alu_cmd_slt_c; -- SLT(I)
when funct3_sltu_c => alu_operation_v := alu_cmd_slt_c; -- SLTU(I)
when funct3_xor_c => alu_operation_v := alu_cmd_xor_c; -- XOR(I)
when funct3_sr_c => alu_operation_v := alu_cmd_shift_c; -- SRL(I) / SRA(I)
when funct3_or_c => alu_operation_v := alu_cmd_or_c; -- OR(I)
when funct3_and_c => alu_operation_v := alu_cmd_and_c; -- AND(I)
when funct3_or_c => alu_operation_v := alu_cmd_or_c; -- OR(I)
when funct3_and_c => alu_operation_v := alu_cmd_and_c; -- AND(I)
when others => alu_operation_v := (others => '0'); -- undefined
end case;
 
-- is rd = r0? --
rd_is_r0_v := '0';
if (execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") then
rd_is_r0_v := '1';
end if;
 
-- is rs1 = r0? --
rs1_is_r0_v := '0';
if (i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
if (execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
rs1_is_r0_v := '1';
end if;
 
-- state machine --
case execute_engine.state is
 
-- state machine: instruction fetch and execution --
case state is
 
when IFETCH_0 => -- output current PC to bus system
when IDLE => -- Delay cycle (used to wait for side effects to kick in)
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_if_c) <= '1'; -- instruction fetch request (output PC to bus address)
iavail_nxt <= '0'; -- absolutely no instruction available yet
state_nxt <= IFETCH_1;
execute_engine.state_nxt <= DISPATCH;
 
when IFETCH_1 => -- memory latency, update PC
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) <= "11"; -- opa = current PC
ctrl_nxt(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) <= "11"; -- opb = PC_increment
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
ctrl_nxt(ctrl_csr_pc_we_c) <= '1'; -- update PC
state_nxt <= IFETCH_2;
when DISPATCH => -- Get new command from instruction prefetch buffer (IPB)
-- ------------------------------------------------------------
if (ipb.avail = '1') then -- instruction available?
ipb.re <= '1';
trap_ctrl.instr_ma <= ipb.rdata(33);
trap_ctrl.instr_be <= ipb.rdata(34);
if (trap_ctrl.env_start = '1') or (ipb.rdata(33) = '1') or (ipb.rdata(34) = '1') then -- exception/interrupt?
execute_engine.state_nxt <= TRAP;
else
execute_engine.is_ci_nxt <= ipb.rdata(32); -- flag to indicate this is a compressed instruction beeing executed
execute_engine.i_reg_nxt <= ipb.rdata(31 downto 0);
execute_engine.pc_nxt <= ipb.raddr(data_width_c-1 downto 1) & '0'; -- the PC according to the current instruction
execute_engine.state_nxt <= EXECUTE;
end if;
end if;
 
when IFETCH_2 => -- update instruction buffers
when TRAP => -- Start trap environment (also used as sleep state)
-- ------------------------------------------------------------
if (exc_cpu_start = '1') then -- exception detected!
exc_cpu_ack <= '1';
state_nxt <= IFETCH_0; -- start new instruction fetch
else -- normal operation
-- instruction register update --
if (CPU_EXTENSION_RISCV_C = true) then -- compressed AND uncompressed instructions possible
if (pc_backup_reg(1) = '0') then
i_buf_nxt <= instr_i(31 downto 16);
ci_reg_nxt <= instr_i(15 downto 00);
else
i_buf_nxt <= instr_i(15 downto 00);
ci_reg_nxt <= instr_i(31 downto 16);
end if;
else -- only uncompressed instructions
i_reg_nxt <= instr_i(31 downto 0);
end if;
-- next state --
if (bus_wait_i = '0') then -- wait for bus response
if (CPU_EXTENSION_RISCV_C = true) then -- compressed AND uncompressed instructions possible
state_nxt <= IFETCH_3;
else -- only uncompressed instructions
state_nxt <= EXECUTE;
end if;
end if;
if (trap_ctrl.env_start = '1') then
trap_ctrl.env_start_ack <= '1';
execute_engine.pc_nxt <= csr.mtvec(data_width_c-1 downto 1) & '0';
fetch_engine.reset <= '1';
execute_engine.state_nxt <= IDLE;
end if;
 
 
when IFETCH_3 => -- check for exception, start instruction execution (only available for C-extension)
when EXECUTE => -- Decode and execute instruction
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) <= "11"; -- opa = current PC
ctrl_nxt(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) <= "11"; -- opb = PC_increment
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
--
if (exc_cpu_start = '1') then -- exception detected!
exc_cpu_ack <= '1';
state_nxt <= IFETCH_0; -- start new instruction fetch
else -- normal operation
if (ci_valid = '1') then -- directly execute decoded compressed instruction
i_reg_nxt <= ci_instr32;
state_nxt <= EXECUTE;
elsif (pc_backup_reg(1) = '0') or (iavail = '1') then -- 32-bit aligned uncompressed instruction
i_reg_nxt <= i_buf & ci_reg;
state_nxt <= EXECUTE;
ctrl_nxt(ctrl_csr_pc_we_c) <= not pc_backup_reg(1); -- update PC again when on 32b-aligned address
else
i_reg_nxt <= i_buf & ci_reg;
state_nxt <= IFETCH_4;
end if;
end if;
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
 
when IFETCH_4 => -- get missing instruction parts: output current PC to bus system (only available for C-extension)
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_if_c) <= '1'; -- instruction fetch request (output PC to bus address)
state_nxt <= IFETCH_5;
 
when IFETCH_5 => -- memory latency, update PC (only available for C-extension)
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_opa_mux_msb_c downto ctrl_alu_opa_mux_lsb_c) <= "11"; -- opa = current PC
ctrl_nxt(ctrl_alu_opb_mux_msb_c downto ctrl_alu_opb_mux_lsb_c) <= "11"; -- opb = PC_increment
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
ctrl_nxt(ctrl_csr_pc_we_c) <= '1'; -- update PC
state_nxt <= IFETCH_6;
 
when IFETCH_6 => -- update missing instruction buffer parts (only available for C-extension)
-- ------------------------------------------------------------
if (bus_wait_i = '0') then -- wait for bus response
i_buf_nxt <= instr_i(15 downto 00);
iavail_nxt <= '1';
state_nxt <= IFETCH_3;
end if;
 
 
when EXECUTE => -- decode and execute instruction
-- ------------------------------------------------------------
is_ci_nxt <= ci_valid; -- flag to indicate this is a compressed instruction beeing executed (ci_valid is zero if not C-ext is not implemented)
case i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
 
when opcode_alu_c | opcode_alui_c => -- ALU operation
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA
500,31 → 733,31
ctrl_nxt(ctrl_alu_opc_mux_c) <= not alu_immediate_v;
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result
if (CPU_EXTENSION_RISCV_M = true) and (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_alu_c) and
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV?
if (CPU_EXTENSION_RISCV_M = true) and (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_alu_c) and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV?
ctrl_nxt(ctrl_cp_use_c) <= '1'; -- use CP
ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- muldiv CP
state_nxt <= ALU_WAIT;
execute_engine.state_nxt <= ALU_WAIT;
elsif (alu_operation_v = alu_cmd_shift_c) then -- multi-cycle shift operation?
state_nxt <= ALU_WAIT;
execute_engine.state_nxt <= ALU_WAIT;
else
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
state_nxt <= IFETCH_0;
execute_engine.state_nxt <= DISPATCH;
end if;
 
when opcode_lui_c | opcode_auipc_c => -- load upper immediate (add to PC)
-- ------------------------------------------------------------
ctrl_nxt(ctrl_rf_clear_rs1_c) <= '1'; -- force RS1 = r0
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_auipc_c) then -- AUIPC
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_auipc_c) then -- AUIPC
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA
else -- LUI
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA
end if;
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
state_nxt <= IFETCH_0;
execute_engine.state_nxt <= DISPATCH;
 
when opcode_load_c | opcode_store_c => -- load/store
-- ------------------------------------------------------------
531,12 → 764,14
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation
ctrl_nxt(ctrl_bus_mar_we_c) <= '1'; -- write to MAR
ctrl_nxt(ctrl_bus_mdo_we_c) <= '1'; -- write to MDO (only relevant for stores)
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD
state_nxt <= LOAD_0;
else -- STORE
state_nxt <= STORE_0;
ctrl_nxt(ctrl_bus_mar_we_c) <= '1'; -- write to MAR
ctrl_nxt(ctrl_bus_mdo_we_c) <= '1'; -- write to MDO (only relevant for stores)
if (fetch_engine.state /= IFETCH_0) then
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD
execute_engine.state_nxt <= LOAD;
else -- STORE
execute_engine.state_nxt <= STORE;
end if;
end if;
 
when opcode_branch_c => -- branch instruction
543,14 → 778,13
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- use IMM as ALU.OPB
ctrl_nxt(ctrl_alu_opc_mux_c) <= '1'; -- use RS2 as ALU.OPC
is_branch_nxt <= '1';
state_nxt <= IFETCH_0;
ctrl_nxt(ctrl_alu_opc_mux_c) <= '1'; -- use RS2 as ALU.OPC
execute_engine.state_nxt <= BRANCH;
 
when opcode_jal_c | opcode_jalr_c => -- jump and link (with register)
-- ------------------------------------------------------------
-- compute target address --
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_jal_c) then -- JAL
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_jal_c) then -- JAL
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '1'; -- use PC as ALU.OPA
else -- JALR
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- use RS1 as ALU.OPA
559,70 → 793,49
-- save return address --
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "10"; -- RF input = current PC
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
-- update PC --
ctrl_nxt(ctrl_csr_pc_we_c) <= '1'; -- update PC
state_nxt <= IFETCH_0;
--
execute_engine.is_jump_nxt <= '1'; -- this is a jump operation
execute_engine.state_nxt <= BRANCH;
 
when opcode_syscsr_c => -- system/csr access
-- ------------------------------------------------------------
ctrl_nxt(ctrl_csr_re_c) <= '1'; -- ALWAYS READ CSR!!! (OLD: valid CSR read if rd is not r0)
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system
case i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
when x"000" => env_call <= '1'; state_nxt <= IFETCH_0; -- ECALL
when x"001" => break_point <= '1'; state_nxt <= IFETCH_0; -- EBREAK
when x"302" => exc_cpu_end <= '1'; state_nxt <= IFETCH_0; -- MRET
when x"105" => state_nxt <= SLEEP; -- WFI
when others => NULL; -- undefined
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) then
csr.re_nxt <= not rd_is_r0_v; -- only read CSR if not writing to zero_reg
else
csr.re_nxt <= '1'; -- always read CSR
end if;
--
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_env_c) then -- system
case execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) is
when x"000" => -- ECALL
trap_ctrl.env_call <= '1';
execute_engine.state_nxt <= IDLE;
when x"001" => -- EBREAK
trap_ctrl.break_point <= '1';
execute_engine.state_nxt <= IDLE;
when x"302" => -- MRET
trap_ctrl.env_end <= '1';
execute_engine.pc_nxt <= csr.mepc(data_width_c-1 downto 1) & '0';
fetch_engine.reset <= '1';
execute_engine.state_nxt <= IDLE;
when x"105" => -- WFI
execute_engine.state_nxt <= TRAP;
when others => -- undefined
NULL;
end case;
elsif (CPU_EXTENSION_RISCV_Zicsr = true) then -- CSR access
state_nxt <= CSR_ACCESS;
execute_engine.state_nxt <= CSR_ACCESS;
else
state_nxt <= IFETCH_0;
execute_engine.state_nxt <= DISPATCH;
end if;
 
when others => -- undefined
-- ------------------------------------------------------------
state_nxt <= IFETCH_0;
execute_engine.state_nxt <= DISPATCH;
 
end case;
 
when ALU_WAIT => -- wait for multi-cycle ALU operation to finish
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (write back all the time)
if (alu_wait_i = '0') then
state_nxt <= IFETCH_0;
end if;
 
when LOAD_0 => -- trigger memory read request
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_rd_c) <= '1'; -- read request
state_nxt <= LOADSTORE_0;
 
when STORE_0 => -- trigger memory write request
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_wr_c) <= '1'; -- write request
state_nxt <= LOADSTORE_0;
 
when LOADSTORE_0 => -- memory latency
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD)
state_nxt <= LOADSTORE_1;
 
when LOADSTORE_1 => -- wait for bus transaction to finish
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD)
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD)
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception
state_nxt <= IFETCH_0;
elsif (bus_wait_i = '0') then -- wait here for bus to finish transaction
if (i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD?
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
end if;
state_nxt <= IFETCH_0;
end if;
 
when CSR_ACCESS => -- write CSR data to RF, write ALU.res to CSR
-- ------------------------------------------------------------
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '0'; -- default
629,34 → 842,39
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- default
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '0'; -- default
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- default
ctrl_nxt(ctrl_csr_we_c) <= not rs1_is_r0_v; -- valid CSR write if rs1 is not r0 (or not imm5 = 0)
case i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_csrrw_c => -- CSSRW
case execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) is
when funct3_csrrw_c => -- CSRRW
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '0'; -- OPB = rs2
ctrl_nxt(ctrl_rf_clear_rs2_c) <= '1'; -- rs2 = 0
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
when funct3_csrrs_c => -- CSSRS
csr.we_nxt <= '1'; -- always write CSR
when funct3_csrrs_c => -- CSRRS
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = crs1
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
when funct3_csrrc_c => -- CSSRC
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg
when funct3_csrrc_c => -- CSRRC
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
ctrl_nxt(ctrl_alu_opb_mux_msb_c) <= '1'; -- OPB = rs1
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
when funct3_csrrwi_c => -- CSSRWI
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if rs1 is not zero_reg
when funct3_csrrwi_c => -- CSRRWI
ctrl_nxt(ctrl_alu_opa_mux_lsb_c) <= '0'; -- OPA = rs1
ctrl_nxt(ctrl_rf_clear_rs1_c) <= '1'; -- rs1 = 0
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_add_c; -- actual ALU operation = ADD
when funct3_csrrsi_c => -- CSSRSI
csr.we_nxt <= '1'; -- always write CSR
when funct3_csrrsi_c => -- CSRRSI
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_or_c; -- actual ALU operation = OR
when funct3_csrrci_c => -- CSSRCI
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if UIMM5 is not zero (bits from rs1 filed)
when funct3_csrrci_c => -- CSRRCI
ctrl_nxt(ctrl_alu_opa_mux_msb_c) <= '1'; -- OPA = csr
ctrl_nxt(ctrl_alu_opb_mux_lsb_c) <= '1'; -- OPB = immediate
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_cmd_bitc_c; -- actual ALU operation = bit clear
csr.we_nxt <= not rs1_is_r0_v; -- write CSR if UIMM5 is not zero (bits from rs1 filed)
when others => -- undefined
NULL;
end case;
663,28 → 881,66
-- RF write back --
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output register
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
state_nxt <= IFETCH_0;
execute_engine.state_nxt <= DISPATCH;
 
when SLEEP => -- stall and wait for interrupt (WFI)
when ALU_WAIT => -- wait for multi-cycle ALU operation to finish
-- ------------------------------------------------------------
if (exc_cpu_start = '1') then -- exception detected!
exc_cpu_ack <= '1';
state_nxt <= IFETCH_0; -- start new instruction fetch
ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back (write back all the time)
if (alu_wait_i = '0') then
execute_engine.state_nxt <= DISPATCH;
end if;
 
when BRANCH => -- update PC for taken branches and jumps
-- ------------------------------------------------------------
if (execute_engine.is_jump = '1') or (execute_engine.branch_taken = '1') then
execute_engine.pc_nxt <= alu_add_i(data_width_c-1 downto 1) & '0';
fetch_engine.reset <= '1';
end if;
execute_engine.state_nxt <= IDLE;
 
when LOAD => -- trigger memory read request
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_rd_c) <= '1';--bus_fast_rd <= '1'; -- fast read request
execute_engine.state_nxt <= LOADSTORE_0;
 
when STORE => -- trigger memory write request
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_wr_c) <= '1';--bus_fast_wr <= '1'; -- fast write request
execute_engine.state_nxt <= LOADSTORE_0;
 
when LOADSTORE_0 => -- memory latency
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- write input data to MDI (only relevant for LOAD)
execute_engine.state_nxt <= LOADSTORE_1;
 
when LOADSTORE_1 => -- wait for bus transaction to finish
-- ------------------------------------------------------------
ctrl_nxt(ctrl_bus_mdi_we_c) <= '1'; -- keep writing input data to MDI (only relevant for LOAD)
ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "01"; -- RF input = memory input (only relevant for LOAD)
if (ma_load_i = '1') or (be_load_i = '1') or (ma_store_i = '1') or (be_store_i = '1') then -- abort if exception
execute_engine.state_nxt <= IDLE;
elsif (bus_wait_i = '0') then -- wait here for bus to finish transaction
if (execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) = opcode_load_c) then -- LOAD?
ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
end if;
execute_engine.state_nxt <= DISPATCH;
end if;
 
when others => -- undefined
-- ------------------------------------------------------------
state_nxt <= IFETCH_0;
execute_engine.state_nxt <= IDLE;
 
end case;
end process arbiter_comb;
end process execute_engine_fsm_comb;
 
 
-- Illegal Instruction Check --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
illegal_instruction_check: process(i_reg, state, ctrl_nxt, ci_valid, ci_illegal)
illegal_instruction_check: process(execute_engine, csr, ctrl_nxt, ci_illegal)
begin
if (state = EXECUTE) then
if (execute_engine.state = EXECUTE) then
-- defaults --
illegal_instruction <= '0';
illegal_register <= '0';
691,14 → 947,14
illegal_compressed <= '0';
 
-- check if using reg >= 16 for E-CPUs --
if (CPU_EXTENSION_RISCV_E = true) then
illegal_register <= ctrl_nxt(ctrl_rf_rd_adr4_c) or ctrl_nxt(ctrl_rf_rs2_adr4_c) or ctrl_nxt(ctrl_rf_rs1_adr4_c);
else
illegal_register <= '0';
end if;
--if (CPU_EXTENSION_RISCV_E = true) then
-- illegal_register <= ctrl_nxt(ctrl_rf_rd_adr4_c) or ctrl_nxt(ctrl_rf_rs2_adr4_c) or ctrl_nxt(ctrl_rf_rs1_adr4_c);
--else
-- illegal_register <= '0';
--end if;
 
-- check instructions --
case i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
case execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c) is
 
-- OPCODE check sufficient: LUI, UIPC, JAL --
when opcode_lui_c | opcode_auipc_c | opcode_jal_c =>
705,11 → 961,11
illegal_instruction <= '0';
 
when opcode_alui_c => -- check ALUI funct7
if ((i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000")) or -- shift logical left
((i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and
((i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000"))) then -- shift right
if ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000")) or -- shift logical left
((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) and
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000"))) then -- shift right
illegal_instruction <= '1';
else
illegal_instruction <= '0';
716,11 → 972,11
end if;
when opcode_load_c => -- check LOAD funct3
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lh_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lw_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lbu_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lhu_c) then
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lb_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lh_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lw_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lbu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_lhu_c) then
illegal_instruction <= '0';
else
illegal_instruction <= '1';
727,9 → 983,9
end if;
when opcode_store_c => -- check STORE funct3
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sh_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sw_c) then
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sb_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sh_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sw_c) then
illegal_instruction <= '0';
else
illegal_instruction <= '1';
736,12 → 992,12
end if;
 
when opcode_branch_c => -- check BRANCH funct3
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bne_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_blt_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bge_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bltu_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bgeu_c) then
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_beq_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bne_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_blt_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bge_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bltu_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_bgeu_c) then
illegal_instruction <= '0';
else
illegal_instruction <= '1';
748,7 → 1004,7
end if;
 
when opcode_jalr_c => -- check JALR funct3
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = "000") then
illegal_instruction <= '0';
else
illegal_instruction <= '1';
755,14 → 1011,14
end if;
 
when opcode_alu_c => -- check ALU funct3 & funct7
if (i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV
if (CPU_EXTENSION_RISCV_M = false) then
if (execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) = "0000001") then -- MULDIV
if (CPU_EXTENSION_RISCV_M = false) or (csr.misa_m_en = '0') then -- not implemented or disabled
illegal_instruction <= '1';
end if;
elsif ((i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c)) and -- ADD/SUB or SRA/SRL check
((i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and
(i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000")) then -- ADD/SUB or SRA/SRL select
elsif ((execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_subadd_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c)) and -- ADD/SUB or SRA/SRL check
((execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0000000") and
(execute_engine.i_reg(instr_funct7_msb_c downto instr_funct7_lsb_c) /= "0100000")) then -- ADD/SUB or SRA/SRL select
illegal_instruction <= '1';
else
illegal_instruction <= '0';
770,46 → 1026,45
 
when opcode_syscsr_c => -- check system instructions --
-- CSR access --
if (i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrs_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrc_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrsi_c) or
(i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrci_c) then
if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrs_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrc_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrsi_c) or
(execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrci_c) then
-- valid CSR? --
if (i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"300") or -- mstatus
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"301") or -- misa
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"304") or -- mie
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"305") or -- mtvev
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"340") or -- mscratch
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"341") or -- mepc
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"34a") or -- mtinst
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"300") or -- mstatus
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"301") or -- misa
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"304") or -- mie
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"305") or -- mtvev
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"340") or -- mscratch
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"341") or -- mepc
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"34a") or -- mtinst
--
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CPU_EXTENSION_RISCV_E = false)) or -- cycle
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CPU_EXTENSION_RISCV_E = false)) or -- time
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c02") and (CPU_EXTENSION_RISCV_E = false)) or -- instret
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c80") and (CPU_EXTENSION_RISCV_E = false)) or -- cycleh
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c81") and (CPU_EXTENSION_RISCV_E = false)) or -- timeh
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c82") and (CPU_EXTENSION_RISCV_E = false)) or -- instreth
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycle
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- time
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c02") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- instret
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c80") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycleh
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c81") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- timeh
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c82") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- instreth
--
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b00") and (CPU_EXTENSION_RISCV_E = false)) or -- mcycle
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b02") and (CPU_EXTENSION_RISCV_E = false)) or -- minstret
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b80") and (CPU_EXTENSION_RISCV_E = false)) or -- mcycleh
((i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b82") and (CPU_EXTENSION_RISCV_E = false)) or -- minstreth
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b00") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- mcycle
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b02") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- minstret
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b80") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- mcycleh
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"b82") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- minstreth
--
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f13") or -- mimpid
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f14") or -- mhartid
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fff") or -- mhwctrl
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f13") or -- mimpid
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"f14") or -- mhartid
--
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc0") or -- mfeatures
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc1") or -- mclock
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc4") or -- mispacebase
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc5") or -- mispacesize
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc6") or -- mdspacebase
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc7") then -- mdspacesize
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc0") or -- mfeatures
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc1") or -- mclock
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc4") or -- mispacebase
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc5") or -- mispacesize
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc6") or -- mdspacebase
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"fc7") then -- mdspacesize
illegal_instruction <= '0';
else
illegal_instruction <= '1';
816,12 → 1071,12
end if;
 
-- ecall, ebreak, mret, wfi --
elsif (i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") and
(i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
if (i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000000") or -- ECALL
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000001") or -- EBREAK
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "001100000010") or -- MRET
(i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000100000101") then -- WFI
elsif (execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") and
(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
if (execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000000") or -- ECALL
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000000000001") or -- EBREAK
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "001100000010") or -- MRET
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = "000100000101") then -- WFI
illegal_instruction <= '0';
else
illegal_instruction <= '1';
831,10 → 1086,10
end if;
 
when others => -- compressed instruction or undefined instruction
if (i_reg(1 downto 0) = "11") then -- undefined/unimplemented opcode
if (execute_engine.i_reg(1 downto 0) = "11") then -- undefined/unimplemented opcode
illegal_instruction <= '1';
else -- compressed instruction
illegal_compressed <= ci_valid and ci_illegal;
else -- compressed instruction: illegal or disabled / not implemented
illegal_compressed <= ci_illegal or (not csr.misa_c_en);
end if;
 
end case;
846,142 → 1101,106
end process illegal_instruction_check;
 
-- any illegal condition? --
illegal_instr_exc <= illegal_instruction or illegal_register or illegal_compressed;
trap_ctrl.instr_il <= illegal_instruction or illegal_register or illegal_compressed;
 
 
-- Program Counter ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
program_counter: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
if (BOOTLOADER_USE = true) then -- boot from bootloader ROM
pc_reg <= boot_base_c;
pc_backup_reg <= boot_base_c;
pc_backup2_reg <= boot_base_c;
else -- boot from IMEM
pc_reg <= MEM_ISPACE_BASE;
pc_backup_reg <= MEM_ISPACE_BASE;
pc_backup2_reg <= MEM_ISPACE_BASE;
end if;
elsif rising_edge(clk_i) then
-- actual PC --
if (exc_cpu_ack = '1') then -- exception start?
pc_reg <= mtvec;
elsif (exc_cpu_end = '1') then -- return from exception
pc_reg <= mepc;
elsif (ctrl(ctrl_csr_pc_we_c) = '1') or ((is_branch and branch_taken) = '1') then -- manual update or taken branch
pc_reg <= alu_add_i;
end if;
-- delayed PC --
if (state = IFETCH_1) then
pc_backup_reg <= pc_reg; -- PC for ALU address computations
end if;
if (state = EXECUTE) then
pc_backup2_reg <= pc_backup_reg; -- PC backup for exceptions
end if;
end if;
end process program_counter;
-- ****************************************************************************************************************************
-- Exception and Interrupt Control
-- ****************************************************************************************************************************
 
-- output --
pc_o <= pc_reg;
alu_pc_o <= pc_backup_reg;
 
 
-- Exception Controller -------------------------------------------------------------------
-- Trap Controller ------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
exception_controller: process(rstn_i, clk_i)
trap_controller: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
exc_buf <= (others => '0');
irq_buf <= (others => '0');
exc_ack <= '0';
irq_ack <= (others => '0');
exc_src <= (others => '0');
exc_cpu_start <= '0';
exc_cause <= (others => '0');
mtinst <= (others => '0');
trap_ctrl.exc_buf <= (others => '0');
trap_ctrl.irq_buf <= (others => '0');
trap_ctrl.exc_ack <= '0';
trap_ctrl.irq_ack <= (others => '0');
trap_ctrl.cause <= (others => '0');
trap_ctrl.instr <= (others => '0');
trap_ctrl.exc_src <= (others => '0');
trap_ctrl.env_start <= '0';
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_Zicsr = true) then
-- exception buffer: misaligned load/store/instruction address
exc_buf(exception_lalign_c) <= (exc_buf(exception_lalign_c) or ma_load_i) and (not exc_ack);
exc_buf(exception_salign_c) <= (exc_buf(exception_salign_c) or ma_store_i) and (not exc_ack);
exc_buf(exception_ialign_c) <= (exc_buf(exception_ialign_c) or ma_instr_i) and (not exc_ack);
trap_ctrl.exc_buf(exception_lalign_c) <= (trap_ctrl.exc_buf(exception_lalign_c) or ma_load_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_salign_c) <= (trap_ctrl.exc_buf(exception_salign_c) or ma_store_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_ialign_c) <= (trap_ctrl.exc_buf(exception_ialign_c) or trap_ctrl.instr_ma) and (not trap_ctrl.exc_ack);
-- exception buffer: load/store/instruction bus access error
exc_buf(exception_laccess_c) <= (exc_buf(exception_laccess_c) or be_load_i) and (not exc_ack);
exc_buf(exception_saccess_c) <= (exc_buf(exception_saccess_c) or be_store_i) and (not exc_ack);
exc_buf(exception_iaccess_c) <= (exc_buf(exception_iaccess_c) or be_instr_i) and (not exc_ack);
trap_ctrl.exc_buf(exception_laccess_c) <= (trap_ctrl.exc_buf(exception_laccess_c) or be_load_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_saccess_c) <= (trap_ctrl.exc_buf(exception_saccess_c) or be_store_i) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_iaccess_c) <= (trap_ctrl.exc_buf(exception_iaccess_c) or trap_ctrl.instr_be) and (not trap_ctrl.exc_ack);
-- exception buffer: illegal instruction / env call / break point
exc_buf(exception_iillegal_c) <= (exc_buf(exception_iillegal_c) or illegal_instr_exc) and (not exc_ack);
exc_buf(exception_m_envcall_c) <= (exc_buf(exception_m_envcall_c) or env_call) and (not exc_ack);
exc_buf(exception_break_c) <= (exc_buf(exception_break_c) or break_point) and (not exc_ack);
trap_ctrl.exc_buf(exception_m_envcall_c) <= (trap_ctrl.exc_buf(exception_m_envcall_c) or trap_ctrl.env_call) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_break_c) <= (trap_ctrl.exc_buf(exception_break_c) or trap_ctrl.break_point) and (not trap_ctrl.exc_ack);
trap_ctrl.exc_buf(exception_iillegal_c) <= (trap_ctrl.exc_buf(exception_iillegal_c) or trap_ctrl.instr_il) and (not trap_ctrl.exc_ack);
-- interrupt buffer: machine software/external/timer interrupt
irq_buf(interrupt_msw_irq_c) <= mie_msie and (irq_buf(interrupt_msw_irq_c) or mip_msip) and (not irq_ack(interrupt_msw_irq_c));
irq_buf(interrupt_mext_irq_c) <= mie_meie and (irq_buf(interrupt_mext_irq_c) or clic_irq_i) and (not irq_ack(interrupt_mext_irq_c));
irq_buf(interrupt_mtime_irq_c) <= mie_mtie and (irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not irq_ack(interrupt_mtime_irq_c));
trap_ctrl.irq_buf(interrupt_msw_irq_c) <= csr.mie_msie and (trap_ctrl.irq_buf(interrupt_msw_irq_c) or csr.mip_msip) and (not trap_ctrl.irq_ack(interrupt_msw_irq_c));
trap_ctrl.irq_buf(interrupt_mext_irq_c) <= csr.mie_meie and (trap_ctrl.irq_buf(interrupt_mext_irq_c) or clic_irq_i) and (not trap_ctrl.irq_ack(interrupt_mext_irq_c));
trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and (trap_ctrl.irq_buf(interrupt_mtime_irq_c) or mtime_irq_i) and (not trap_ctrl.irq_ack(interrupt_mtime_irq_c));
 
-- exception control --
if (exc_cpu_start = '0') then --
-- exception/interrupt triggered, waiting for IRQ in EXECUTE (make sure at least 1 instr. is executed even for a continous IRQ)
if (exc_fire = '1') or ((irq_fire = '1') and ((state = EXECUTE) or (state = SLEEP))) then
exc_cause <= exc_cause_nxt; -- capture source for program
mtinst <= i_reg; -- MTINST NOT FOULLY IMPLEMENTED YET! FIXME
mtinst(1) <= not is_ci; -- bit is set for uncompressed instruction
exc_src <= exc_buf; -- capture source for hardware
exc_ack <= '1'; -- clear execption
irq_ack <= irq_ack_nxt; -- capture and clear with interrupt ACK mask
exc_cpu_start <= '1';
-- trap control --
if (trap_ctrl.env_start = '0') then -- no started trap handler
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- exception/IRQ detected!
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program
trap_ctrl.instr <= execute_engine.i_reg; -- FIXME mtinst transformation not fully implemented yet!
trap_ctrl.instr(1) <= not execute_engine.is_ci; -- bit is set for uncompressed instruction
trap_ctrl.exc_src <= trap_ctrl.exc_buf; -- capture exception source for hardware
trap_ctrl.exc_ack <= '1'; -- clear execption
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask
trap_ctrl.env_start <= '1'; -- now we want to start the trap handler
end if;
else -- waiting for exception handler to get started
if (exc_cpu_ack = '1') then -- handler started?
exc_ack <= '0';
irq_ack <= (others => '0');
exc_cpu_start <= '0';
else -- trap waiting to get started
if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine
trap_ctrl.exc_ack <= '0';
trap_ctrl.irq_ack <= (others => '0');
trap_ctrl.env_start <= '0';
end if;
end if;
else -- (CPU_EXTENSION_RISCV_Zicsr = false)
exc_buf <= (others => '0');
irq_buf <= (others => '0');
exc_ack <= '0';
irq_ack <= (others => '0');
exc_src <= (others => '0');
exc_cpu_start <= '0';
exc_cause <= (others => '0');
mtinst <= (others => '0');
end if;
end if;
end process exception_controller;
end process trap_controller;
 
-- any exception/interrupt? --
exc_fire <= or_all_f(exc_buf); -- classic exceptions (faults/traps) cannot be masked
irq_fire <= or_all_f(irq_buf) and mstatus_mie; -- classic interrupts can be enabled/disabled
trap_ctrl.exc_fire <= or_all_f(trap_ctrl.exc_buf); -- classic exceptions (faults/traps) cannot be masked
trap_ctrl.irq_fire <= or_all_f(trap_ctrl.irq_buf) and csr.mstatus_mie; -- classic interrupts can be enabled/disabled
 
-- exception acknowledge for bus unit --
bus_exc_ack_o <= exc_cpu_ack;
bus_exc_ack_o <= trap_ctrl.env_start_ack or fetch_engine.bus_err_ack;
 
-- exception priority encoder --
exc_priority: process(exc_buf, irq_buf)
-- exception/interrupt/status ID visible for program --
csr.mcause <= trap_ctrl.cause;
csr.mtinst <= trap_ctrl.instr;
 
 
-- Trap Priority Detector -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
trap_priority: process(trap_ctrl)
begin
-- defaults --
exc_cause_nxt <= (others => '0');
irq_ack_nxt <= (others => '0');
trap_ctrl.cause_nxt <= (others => '0');
trap_ctrl.irq_ack_nxt <= (others => '0');
 
-- interrupt: 1.11 machine external interrupt --
if (irq_buf(interrupt_mext_irq_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '1';
exc_cause_nxt(3 downto 0) <= "1011";
irq_ack_nxt(interrupt_mext_irq_c) <= '1';
if (trap_ctrl.irq_buf(interrupt_mext_irq_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '1';
trap_ctrl.cause_nxt(3 downto 0) <= "1011";
trap_ctrl.irq_ack_nxt(interrupt_mext_irq_c) <= '1';
 
-- interrupt: 1.7 machine timer interrupt --
elsif (irq_buf(interrupt_mtime_irq_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '1';
exc_cause_nxt(3 downto 0) <= "0111";
irq_ack_nxt(interrupt_mtime_irq_c) <= '1';
elsif (trap_ctrl.irq_buf(interrupt_mtime_irq_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '1';
trap_ctrl.cause_nxt(3 downto 0) <= "0111";
trap_ctrl.irq_ack_nxt(interrupt_mtime_irq_c) <= '1';
 
-- interrupt: 1.3 machine SW interrupt --
elsif (irq_buf(interrupt_msw_irq_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '1';
exc_cause_nxt(3 downto 0) <= "0011";
irq_ack_nxt(interrupt_msw_irq_c) <= '1';
elsif (trap_ctrl.irq_buf(interrupt_msw_irq_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '1';
trap_ctrl.cause_nxt(3 downto 0) <= "0011";
trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
 
 
-- the following traps are caused by synchronous exceptions
988,150 → 1207,161
-- here we do not need an acknowledge mask since only one exception can trigger at the same time
 
-- trap/fault: 0.0 instruction address misaligned --
elsif (exc_buf(exception_ialign_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0000";
elsif (trap_ctrl.exc_buf(exception_ialign_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0000";
 
-- trap/fault: 0.1 instruction access fault --
elsif (exc_buf(exception_iaccess_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0001";
elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0001";
 
-- trap/fault: 0.2 illegal instruction --
elsif (exc_buf(exception_iillegal_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0010";
elsif (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0010";
 
 
-- trap/fault: 0.11 environment call from M-mode --
elsif (exc_buf(exception_m_envcall_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "1011";
elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "1011";
 
-- trap/fault: 0.3 breakpoint --
elsif (exc_buf(exception_break_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0011";
elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0011";
 
 
-- trap/fault: 0.6 store address misaligned -
elsif (exc_buf(exception_salign_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0110";
elsif (trap_ctrl.exc_buf(exception_salign_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0110";
 
-- trap/fault: 0.4 load address misaligned --
elsif (exc_buf(exception_lalign_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0100";
elsif (trap_ctrl.exc_buf(exception_lalign_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0100";
 
-- trap/fault: 0.7 store access fault --
elsif (exc_buf(exception_saccess_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0111";
elsif (trap_ctrl.exc_buf(exception_saccess_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0111";
 
-- trap/fault: 0.5 load access fault --
elsif (exc_buf(exception_laccess_c) = '1') then
exc_cause_nxt(exc_cause_nxt'left) <= '0';
exc_cause_nxt(3 downto 0) <= "0101";
elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then
trap_ctrl.cause_nxt(data_width_c-1) <= '0';
trap_ctrl.cause_nxt(3 downto 0) <= "0101";
 
-- undefined / not implemented --
else
exc_cause_nxt <= (others => '0');
irq_ack_nxt <= (others => '0');
trap_ctrl.cause_nxt <= (others => '0');
trap_ctrl.irq_ack_nxt <= (others => '0');
end if;
end process exc_priority;
end process trap_priority;
 
-- ****************************************************************************************************************************
-- Control and Status Registers (CSRs)
-- ****************************************************************************************************************************
 
-- CSR CPU Access -------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
csr_cpu_acc: process(clk_i)
begin
if rising_edge(clk_i) then
csr.we <= csr.we_nxt;
csr.re <= csr.re_nxt;
end if;
end process csr_cpu_acc;
 
 
-- Control and Status Registers Write Access ----------------------------------------------
-- -------------------------------------------------------------------------------------------
csr_write_access: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
mstatus_mie <= '0';
mstatus_mpie <= '0';
mie_msie <= '0';
mie_meie <= '0';
mie_mtie <= '0';
mtvec <= (others => '0');
mtval <= (others => '0');
mepc <= (others => '0');
mip_msip <= '0';
csr.mstatus_mie <= '0';
csr.mstatus_mpie <= '0';
csr.mie_msie <= '0';
csr.mie_meie <= '0';
csr.mie_mtie <= '0';
csr.mtvec <= (others => '0');
csr.mtval <= (others => '0');
csr.mepc <= (others => '0');
csr.mip_msip <= '0';
csr.misa_c_en <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
csr.misa_m_en <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_Zicsr = true) then
mip_msip <= '0';
csr.mip_msip <= '0';
 
-- register that can be modified by user --
if (ctrl(ctrl_csr_we_c) = '1') then -- manual update
if (csr.we = '1') then -- manual update
 
-- machine trap setup --
if (i_reg(31 downto 24) = x"30") then
if (i_reg(23 downto 20) = x"0") then -- R/W: mstatus - machine status register
mstatus_mie <= csr_wdata_i(03);
mstatus_mpie <= csr_wdata_i(07);
if (execute_engine.i_reg(31 downto 24) = x"30") then
if (execute_engine.i_reg(23 downto 20) = x"0") then -- R/W: mstatus - machine status register
csr.mstatus_mie <= csr_wdata_i(03);
csr.mstatus_mpie <= csr_wdata_i(07);
end if;
if (i_reg(23 downto 20) = x"4") then -- R/W: mie - machine interrupt-enable register
mie_msie <= csr_wdata_i(03); -- SW IRQ enable
mie_mtie <= csr_wdata_i(07); -- TIMER IRQ enable
mie_meie <= csr_wdata_i(11); -- EXT IRQ enable
if (execute_engine.i_reg(23 downto 20) = x"1") then -- R/W: misa - machine instruction set extensions
csr.misa_c_en <= csr_wdata_i(02); -- C extension enable/disable
csr.misa_m_en <= csr_wdata_i(12); -- M extension enable/disable
end if;
if (i_reg(23 downto 20) = x"5") then -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
mtvec <= csr_wdata_i;
if (execute_engine.i_reg(23 downto 20) = x"4") then -- R/W: mie - machine interrupt-enable register
csr.mie_msie <= csr_wdata_i(03); -- SW IRQ enable
csr.mie_mtie <= csr_wdata_i(07); -- TIMER IRQ enable
csr.mie_meie <= csr_wdata_i(11); -- EXT IRQ enable
end if;
if (execute_engine.i_reg(23 downto 20) = x"5") then -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
csr.mtvec <= csr_wdata_i;
end if;
end if;
 
-- machine trap handling --
if (i_reg(31 downto 24) = x"34") then
if (i_reg(23 downto 20) = x"0") then -- R/W: mscratch - machine scratch register
mscratch <= csr_wdata_i;
if (execute_engine.i_reg(31 downto 24) = x"34") then
if (execute_engine.i_reg(23 downto 20) = x"0") then -- R/W: mscratch - machine scratch register
csr.mscratch <= csr_wdata_i;
end if;
if (i_reg(23 downto 20) = x"1") then-- R/W: mepc - machine exception program counter
mepc <= csr_wdata_i;
if (execute_engine.i_reg(23 downto 20) = x"1") then-- R/W: mepc - machine exception program counter
csr.mepc <= csr_wdata_i;
end if;
if (i_reg(23 downto 20) = x"4") then -- R/W: mip - machine interrupt pending
mip_msip <= csr_wdata_i(03); -- manual SW IRQ trigger
if (execute_engine.i_reg(23 downto 20) = x"4") then -- R/W: mip - machine interrupt pending
csr.mip_msip <= csr_wdata_i(03); -- manual SW IRQ trigger
end if;
end if;
 
else -- automatic update by hardware
-- machine exception PC & exception value register --
if (exc_cpu_ack = '1') then -- exception start?
if (exc_cause(exc_cause_nxt'left) = '1') then -- for INTERRUPTs: mepc = address of next (unclompeted) instruction
mepc <= pc_reg;
mtval <= (others => '0'); -- not specified
else -- for EXCEPTIONs: mepc = address of next (unclompeted) instruction
mepc <= pc_backup2_reg;
if ((exc_src(exception_iaccess_c) or exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction
mtval <= pc_backup_reg;
elsif (exc_src(exception_iillegal_c) = '1') then -- illegal instruction
mtval <= i_reg;
elsif ((exc_src(exception_lalign_c) or exc_src(exception_salign_c) or
exc_src(exception_laccess_c) or exc_src(exception_saccess_c)) = '1') then -- load/store misaligned / access error
mtval <= mar_i;
if (trap_ctrl.env_start_ack = '1') then -- trap handler started?
if (csr.mcause(data_width_c-1) = '1') then -- for INTERRUPTS only (mtval not defined for interrupts)
csr.mepc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction
csr.mtval <= (others => '0');
else -- for EXCEPTIONs
csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction
if ((trap_ctrl.exc_src(exception_iaccess_c) or trap_ctrl.exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction
csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0';
elsif (trap_ctrl.exc_src(exception_iillegal_c) = '1') then -- illegal instruction
csr.mtval <= execute_engine.i_reg;
else -- everything else
--elsif ((trap_ctrl.exc_src(exception_lalign_c) or trap_ctrl.exc_src(exception_salign_c) or
-- trap_ctrl.exc_src(exception_laccess_c) or trap_ctrl.exc_src(exception_saccess_c)) = '1') then -- load/store misaligned / access error
csr.mtval <= mar_i;
end if;
end if;
end if;
 
-- context switch in mstatus --
if (exc_cpu_ack = '1') then -- actually entering trap
mstatus_mie <= '0';
if (mstatus_mpie = '0') then -- FIXME: prevent loosing the prev MIE state after several traps
mstatus_mpie <= mstatus_mie;
if (trap_ctrl.env_start_ack = '1') then -- actually entering trap
csr.mstatus_mie <= '0';
if (csr.mstatus_mpie = '0') then -- FIXME: prevent loosing the prev MIE state after several traps
csr.mstatus_mpie <= csr.mstatus_mie;
end if;
elsif (exc_cpu_end = '1') then -- return from exception
mstatus_mie <= mstatus_mpie;
elsif (trap_ctrl.env_end = '1') then -- return from exception
csr.mstatus_mie <= csr.mstatus_mpie;
end if;
end if;
 
else -- CPU_EXTENSION_RISCV_Zicsr = false
mstatus_mie <= '0';
mstatus_mpie <= '0';
mie_msie <= '0';
mie_meie <= '0';
mie_mtie <= '0';
mtvec <= (others => '0');
mtval <= (others => '0');
mepc <= (others => '0');
mip_msip <= '0';
end if;
end if;
end process csr_write_access;
1144,67 → 1374,66
if rising_edge(clk_i) then
csr_rdata_o <= (others => '0'); -- default
if (CPU_EXTENSION_RISCV_Zicsr = true) then -- implement CSR access at all?
if (ctrl(ctrl_csr_re_c) = '1') then
case i_reg(31 downto 20) is
if (csr.re = '1') then
case execute_engine.i_reg(31 downto 20) is
-- machine trap setup --
when x"300" => -- R/W: mstatus - machine status register
csr_rdata_o(03) <= mstatus_mie; -- MIE
csr_rdata_o(07) <= mstatus_mpie; -- MPIE
csr_rdata_o(03) <= csr.mstatus_mie; -- MIE
csr_rdata_o(07) <= csr.mstatus_mpie; -- MPIE
csr_rdata_o(11) <= '1'; -- MPP low
csr_rdata_o(12) <= '1'; -- MPP high
when x"301" => -- R/-: misa - ISA and extensions
csr_rdata_o(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C); -- C CPU extension
when x"301" => -- R/W: misa - ISA and extensions
csr_rdata_o(02) <= csr.misa_c_en; -- C CPU extension
csr_rdata_o(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- E CPU extension
csr_rdata_o(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
csr_rdata_o(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M); -- M CPU extension
csr_rdata_o(12) <= csr.misa_m_en; -- M CPU extension
csr_rdata_o(23) <= '1'; -- X CPU extension: non-standard extensions
csr_rdata_o(25) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zicsr); -- Z CPU extension
csr_rdata_o(30) <= '1'; -- 32-bit architecture (MXL lo)
csr_rdata_o(31) <= '0'; -- 32-bit architecture (MXL hi)
when x"304" => -- R/W: mie - machine interrupt-enable register
csr_rdata_o(03) <= mie_msie; -- software IRQ enable
csr_rdata_o(07) <= mie_mtie; -- timer IRQ enable
csr_rdata_o(11) <= mie_meie; -- external IRQ enable
csr_rdata_o(03) <= csr.mie_msie; -- software IRQ enable
csr_rdata_o(07) <= csr.mie_mtie; -- timer IRQ enable
csr_rdata_o(11) <= csr.mie_meie; -- external IRQ enable
when x"305" => -- R/W: mtvec - machine trap-handler base address (for ALL exceptions)
csr_rdata_o <= mtvec;
csr_rdata_o <= csr.mtvec;
-- machine trap handling --
when x"340" => -- R/W: mscratch - machine scratch register
csr_rdata_o <= mscratch;
csr_rdata_o <= csr.mscratch;
when x"341" => -- R/W: mepc - machine exception program counter
csr_rdata_o <= mepc;
csr_rdata_o <= csr.mepc;
when x"342" => -- R/-: mcause - machine trap cause
csr_rdata_o <= exc_cause;
csr_rdata_o <= csr.mcause;
when x"343" => -- R/-: mtval - machine bad address or instruction
csr_rdata_o <= mtval;
csr_rdata_o <= csr.mtval;
when x"344" => -- R/W: mip - machine interrupt pending
csr_rdata_o(03) <= irq_buf(interrupt_msw_irq_c);
csr_rdata_o(07) <= irq_buf(interrupt_mtime_irq_c);
csr_rdata_o(11) <= irq_buf(interrupt_mext_irq_c);
csr_rdata_o(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
csr_rdata_o(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
csr_rdata_o(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
when x"34a" => -- R/-: mtinst - machine trap instruction (transformed)
csr_rdata_o <= mtinst;
csr_rdata_o <= csr.mtinst;
-- counter and timers --
when x"c00" | x"c01" | x"b00" => -- R/-: cycle/time/mcycle: Cycle counter LOW / Timer LOW
csr_rdata_o <= cycle_lo(31 downto 0);
csr_rdata_o <= csr.cycle(31 downto 0);
when x"c02" | x"b02" => -- R/-: instret/minstret: Instructions-retired counter LOW
csr_rdata_o <= instret_lo(31 downto 0);
csr_rdata_o <= csr.instret(31 downto 0);
when x"c80" | x"c81" | x"b80" => -- R/-: cycleh/timeh/mcycleh: Cycle counter HIGH / Timer HIGH
csr_rdata_o(15 downto 0) <= cycle_hi; -- counter is only 16-bit wide!
csr_rdata_o <= csr.cycleh;
when x"c82" | x"b82" => -- R/-: instreth/minstreth: Instructions-retired counter HIGH
csr_rdata_o(15 downto 0) <= instret_hi; -- counter is only 16-bit wide!
csr_rdata_o <= csr.instreth;
-- machine information registers --
when x"f13" => -- R/-: mimpid - implementation ID / version
csr_rdata_o <= hw_version_c;
when x"f14" => -- R/-: mhartid - hardware thread ID
csr_rdata_o <= HART_ID;
when x"fff" => -- R/-: mhwctrl - hardware controller
csr_rdata_o <= hw_control;
-- CUSTOM read-only machine CSRs --
when x"fc0" => -- R/-: mfeatures - implemented processor devices/features
csr_rdata_o(00) <= bool_to_ulogic_f(BOOTLOADER_USE); -- implement processor-internal bootloader?
csr_rdata_o(01) <= bool_to_ulogic_f(MEM_EXT_USE); -- implement external memory bus interface?
csr_rdata_o(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- implement processor-internal instruction memory
csr_rdata_o(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- implement processor-internal instruction memory as ROM
csr_rdata_o(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- implement processor-internal data memory
csr_rdata_o(02) <= bool_to_ulogic_f(MEM_INT_IMEM_USE); -- implement processor-internal instruction memory?
csr_rdata_o(03) <= bool_to_ulogic_f(MEM_INT_IMEM_ROM); -- implement processor-internal instruction memory as ROM?
csr_rdata_o(04) <= bool_to_ulogic_f(MEM_INT_DMEM_USE); -- implement processor-internal data memory?
csr_rdata_o(05) <= bool_to_ulogic_f(CSR_COUNTERS_USE); -- implement RISC-V (performance) counter?
--
csr_rdata_o(16) <= bool_to_ulogic_f(IO_GPIO_USE); -- implement general purpose input/output port unit (GPIO)?
csr_rdata_o(17) <= bool_to_ulogic_f(IO_MTIME_USE); -- implement machine system timer (MTIME)?
1236,41 → 1465,34
end process csr_read_access;
 
 
-- Optional RISC-V CSRs: Counters ---------------------------------------------------------
-- RISC-V Counter CSRs --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
csr_counters: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
cycle_lo <= (others => '0');
instret_lo <= (others => '0');
cycle_hi <= (others => '0');
instret_hi <= (others => '0');
cycle_lo_msb <= '0';
instret_lo_msb <= '0';
elsif (CPU_EXTENSION_RISCV_E = false) then
if (rstn_i = '0') then
csr.cycle <= (others => '0');
csr.instret <= (others => '0');
csr.cycleh <= (others => '0');
csr.instreth <= (others => '0');
cycle_msb <= '0';
instret_msb <= '0';
elsif rising_edge(clk_i) then
if (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true) then
-- low word overflow buffers --
cycle_lo_msb <= cycle_lo(cycle_lo'left);
instret_lo_msb <= instret_lo(instret_lo'left);
cycle_msb <= csr.cycle(csr.cycle'left);
instret_msb <= csr.instret(csr.instret'left);
-- low word counters --
cycle_lo <= std_ulogic_vector(unsigned(cycle_lo) + 1);
if (state = EXECUTE) then
instret_lo <= std_ulogic_vector(unsigned(instret_lo) + 1);
csr.cycle <= std_ulogic_vector(unsigned(csr.cycle) + 1);
if (execute_engine.state_prev /= EXECUTE) and (execute_engine.state = EXECUTE) then
csr.instret <= std_ulogic_vector(unsigned(csr.instret) + 1);
end if;
-- high word counters --
if ((cycle_lo_msb xor cycle_lo(cycle_lo'left)) = '1') then
cycle_hi <= std_ulogic_vector(unsigned(cycle_hi) + 1);
if ((cycle_msb xor csr.cycle(csr.cycle'left)) = '1') then
csr.cycleh <= std_ulogic_vector(unsigned(csr.cycleh) + 1);
end if;
if ((instret_lo_msb xor instret_lo(instret_lo'left)) = '1') then
instret_hi <= std_ulogic_vector(unsigned(instret_hi) + 1);
if ((instret_msb xor csr.instret(csr.instret'left)) = '1') then
csr.instreth <= std_ulogic_vector(unsigned(csr.instreth) + 1);
end if;
else -- counters are not available in embedded mode
cycle_lo <= (others => '0');
instret_lo <= (others => '0');
cycle_hi <= (others => '0');
instret_hi <= (others => '0');
cycle_lo_msb <= '0';
instret_lo_msb <= '0';
end if;
end if;
end process csr_counters;
/neorv32_cpu_cp_muldiv.vhd
2,8 → 2,8
-- # << NEORV32 - CPU Co-Processor: MULDIV unit >> #
-- # ********************************************************************************************* #
-- # Multiplier and Divider unit. Implements the RISC-V RV32-M CPU extension. #
-- # Multiplier core (signed/unsigned) uses serial algorithm. -> 32+8 cycles latency #
-- # Divider core (unsigned) uses serial algorithm. -> 32+8 cycles latency #
-- # Multiplier core (signed/unsigned) uses serial algorithm. -> 32+4 cycles latency #
-- # Divider core (unsigned) uses serial algorithm. -> 32+6 cycles latency #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
60,6 → 60,9
 
architecture neorv32_cpu_cp_muldiv_rtl of neorv32_cpu_cp_muldiv is
 
-- constants --
constant all_zero_c : std_ulogic_vector(data_width_c-1 downto 0) := (others => '0');
 
-- controller --
type state_t is (IDLE, DECODE, INIT_OPX, INIT_OPY, PROCESSING, FINALIZE, COMPLETED);
signal state : state_t;
70,6 → 73,7
signal opx, opy : std_ulogic_vector(data_width_c-1 downto 0); -- input operands
signal opx_is_signed : std_ulogic;
signal opy_is_signed : std_ulogic;
signal opy_is_zero : std_ulogic;
signal div_res_corr : std_ulogic;
 
-- divider core --
101,6 → 105,7
start <= '0';
valid_o <= '0';
div_res_corr <= '0';
opy_is_zero <= '0';
elsif rising_edge(clk_i) then
-- defaults --
start <= '0';
118,11 → 123,19
 
when DECODE =>
cnt <= "11111";
if (cp_op = cp_op_div_c) or (cp_op = cp_op_rem_c) then -- result sign compensation for div?
if (cp_op = cp_op_div_c) then -- result sign compensation for div?
div_res_corr <= opx(opx'left) xor opy(opy'left);
elsif (cp_op = cp_op_rem_c) then -- result sign compensation for rem?
div_res_corr <= opx(opx'left);
else
div_res_corr <= '0';
end if;
-- if (cp_op = cp_op_div_c) and (opy = all_zero_c) then -- *divide* by 0?
if (opy = all_zero_c) then -- *divide* by 0?
opy_is_zero <= '1';
else
opy_is_zero <= '0';
end if;
if (operation = '1') then -- division
state <= INIT_OPX;
else -- multiplication
175,7 → 188,7
begin
if rising_edge(clk_i) then
if (start = '1') then -- start new multiplication
mul_product(63 downto 32) <= (others => (opy(opy'left) and opy_is_signed)); -- sign extension
mul_product(63 downto 32) <= (others => '0');
mul_product(31 downto 00) <= opy;
elsif ((state = PROCESSING) or (state = FINALIZE)) and (operation = '0') then
mul_product(63 downto 31) <= mul_do_add(32 downto 0);
189,9 → 202,9
begin
if (mul_product(0) = '1') then
if (mul_sign_cycle = '1') then -- for signed operation only: take care of negative weighted MSB
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) - unsigned((opx(opy'left) and opx_is_signed) & opx));
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) - unsigned((opx(opx'left) and opx_is_signed) & opx));
else
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) + unsigned((opx(opy'left) and opx_is_signed) & opx));
mul_do_add <= std_ulogic_vector(unsigned(mul_p_sext & mul_product(63 downto 32)) + unsigned((opx(opx'left) and opx_is_signed) & opx));
end if;
else
mul_do_add <= mul_p_sext & mul_product(63 downto 32);
232,7 → 245,7
div_sign_comp <= std_ulogic_vector(0 - unsigned(div_sign_comp_in));
 
-- result sign correction --
div_res <= div_sign_comp when (div_res_corr = '1') else div_sign_comp_in;
div_res <= div_sign_comp when (div_res_corr = '1') and (opy_is_zero = '0') else div_sign_comp_in;
 
 
-- Data Output ----------------------------------------------------------------------------
240,6 → 253,7
operation_result: process(clk_i)
begin
if rising_edge(clk_i) then
res_o <= (others => '0'); -- default
case cp_op is
when cp_op_mul_c =>
res_o <= mul_product(31 downto 00);
250,7 → 264,11
when cp_op_divu_c =>
res_o <= quotient;
when cp_op_rem_c =>
res_o <= div_res;
if (opy_is_zero = '0') then
res_o <= div_res;
else
res_o <= opx;
end if;
when cp_op_remu_c =>
res_o <= remainder;
when others => -- undefined
/neorv32_cpu_decompressor.vhd
44,7 → 44,6
-- instruction input --
ci_instr16_i : in std_ulogic_vector(15 downto 0); -- compressed instruction input
-- instruction output --
ci_valid_o : out std_ulogic; -- is a compressed instruction
ci_illegal_o : out std_ulogic; -- is an illegal compressed instruction
ci_instr32_o : out std_ulogic_vector(31 downto 0) -- 32-bit decompressed instruction
);
147,7 → 146,7
ci_instr32_o(24) <= ci_instr16_i(11);
ci_instr32_o(25) <= ci_instr16_i(12);
ci_instr32_o(26) <= ci_instr16_i(5);
ci_instr32_o(31 downto 26) <= (others => '0');
ci_instr32_o(31 downto 27) <= (others => '0');
ci_instr32_o(instr_funct3_msb_c downto instr_funct3_lsb_c) <= funct3_lw_c;
ci_instr32_o(instr_rs1_msb_c downto instr_rs1_lsb_c) <= "01" & ci_instr16_i(ci_rs1_3_msb_c downto ci_rs1_3_lsb_c); -- x8 - x15
ci_instr32_o(instr_rd_msb_c downto instr_rd_lsb_c) <= "01" & ci_instr16_i(ci_rd_3_msb_c downto ci_rd_3_lsb_c); -- x8 - x15
432,8 → 431,5
end case;
end process decompressor;
 
-- is compressed instruction at all? --
ci_valid_o <= '0' when (ci_instr16_i(ci_opcode_msb_c downto ci_opcode_lsb_c) = "11") else '1';
 
 
end neorv32_cpu_decompressor_rtl;
/neorv32_devnull.vhd
3,6 → 3,7
-- # ********************************************************************************************* #
-- # In simulation: This unit will output the lowest 8 bit of the written data as ASCII chars #
-- # to the simulator console and to a text file ("neorv32.devnull.out"). #
-- # The complete data 32-bit data word is dumped to "neorv32.devnull.data.out". #
-- # In real hardware: This unit implements a "/dev/null" device. #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
61,7 → 62,8
architecture neorv32_devnull_rtl of neorv32_devnull is
 
-- configuration --
constant sim_output_en_c : boolean := true; -- output lowest byte as char to simulator when enabled
constant sim_text_output_en_c : boolean := true; -- output lowest byte as char to simulator and file when enabled
constant sim_data_output_en_c : boolean := true; -- dump 32-word to file when enabled
 
-- IO space: module base address --
constant hi_abb_c : natural := index_size_f(io_size_c)-1; -- high address boundary bit
80,26 → 82,36
-- Read/Write Access ----------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
rw_access: process(clk_i)
file file_devnull_out : text open write_mode is "neorv32.devnull.out";
file file_devnull_text_out : text open write_mode is "neorv32.devnull.out";
file file_devnull_data_out : text open write_mode is "neorv32.devnull.data.out";
variable i : integer;
variable la, lb : line; -- we need to variables here since "writeline" seems to flush the source variable
variable la, lb, lc : line; -- we need several variables here since "writeline" seems to flush the source variable
begin
if rising_edge(clk_i) then
ack_o <= acc_en and (wren_i or rden_i);
if ((acc_en and wren_i and ben_i(0)) = '1') and (sim_output_en_c = true) then
-- print lowest byte as ASCII to console --
i := to_integer(unsigned(data_i(7 downto 0)));
if (i >= 128) then -- out of range?
i := 0;
if (acc_en = '1') and (wren_i = '1') then
if (sim_text_output_en_c = true) and (ben_i(0) = '1') then
-- print lowest byte as ASCII to console --
i := to_integer(unsigned(data_i(7 downto 0)));
if (i >= 128) then -- out of range?
i := 0;
end if;
if (i /= 10) and (i /= 13) then -- skip line breaks - they are issued via "writeline"
write(la, character'val(i));
write(lb, character'val(i));
end if;
if (i = 10) then -- line break: write to screen and file
writeline(output, la);
writeline(file_devnull_text_out, lb);
end if;
end if;
if (i /= 10) and (i /= 13) then -- skip line breaks - they are issued via "writeline"
write(la, character'val(i));
write(lb, character'val(i));
if (sim_data_output_en_c = true) then
-- dump raw data
for x in 7 downto 0 loop
write(lc, to_hexchar_f(data_i(3+x*4 downto 0+x*4))); -- write in hex form
end loop; -- x
writeline(file_devnull_data_out, lc);
end if;
if (i = 10) then -- line break: write to screen and file
writeline(output, la);
writeline(file_devnull_out, lb);
end if;
end if;
end if;
end process rw_access;
/neorv32_mtime.vhd
108,6 → 108,7
else
-- mtime low --
mtime_lo <= std_ulogic_vector(unsigned(mtime_lo) + 1);
mtime_lo_msb_ff <= mtime_lo(mtime_lo'left);
-- mtime high --
if ((mtime_lo_msb_ff xor mtime_lo(mtime_lo'left)) = '1') then -- mtime_lo carry?
mtime_hi <= std_ulogic_vector(unsigned(mtime_hi) + 1);
/neorv32_package.vhd
41,7 → 41,7
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- data width - FIXED!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"00000206"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01000000"; -- no touchy!
 
-- Internal Functions ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
53,6 → 53,7
function and_all_f( a : std_ulogic_vector) return std_ulogic;
function xor_all_f( a : std_ulogic_vector) return std_ulogic;
function xnor_all_f(a : std_ulogic_vector) return std_ulogic;
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character;
 
-- Processor-internal Address Space Layout ------------------------------------------------
-- -------------------------------------------------------------------------------------------
160,9 → 161,9
constant ctrl_alu_cmd1_c : natural := 21; -- ALU command bit 1
constant ctrl_alu_cmd2_c : natural := 22; -- ALU command bit 2
constant ctrl_alu_opa_mux_lsb_c : natural := 23; -- operand A select lsb (00=rs1, 01=PC)
constant ctrl_alu_opa_mux_msb_c : natural := 24; -- operand A select msb (10=CSR, 11=CSR)
constant ctrl_alu_opb_mux_lsb_c : natural := 25; -- operand B select lsb (00=rs2, 01=PC)
constant ctrl_alu_opb_mux_msb_c : natural := 26; -- operand B select msb (10=rs1, 11=PC_increment(2/4))
constant ctrl_alu_opa_mux_msb_c : natural := 24; -- operand A select msb (10=CSR, 11=?)
constant ctrl_alu_opb_mux_lsb_c : natural := 25; -- operand B select lsb (00=rs2, 01=IMM)
constant ctrl_alu_opb_mux_msb_c : natural := 26; -- operand B select msb (10=rs1, 11=?)
constant ctrl_alu_opc_mux_c : natural := 27; -- operand C select (0=IMM, 1=rs2)
constant ctrl_alu_unsigned_c : natural := 28; -- is unsigned ALU operation
constant ctrl_alu_shift_dir_c : natural := 29; -- shift direction (0=left, 1=right)
177,24 → 178,23
constant ctrl_bus_mdo_we_c : natural := 37; -- memory data out register write enable
constant ctrl_bus_mdi_we_c : natural := 38; -- memory data in register write enable
constant ctrl_bus_unsigned_c : natural := 39; -- is unsigned load
-- csr/system --
constant ctrl_csr_pc_we_c : natural := 40; -- PC write enable
constant ctrl_csr_re_c : natural := 41; -- valid CSR read
constant ctrl_csr_we_c : natural := 42; -- valid CSR write
-- co-processor --
constant ctrl_cp_use_c : natural := 43; -- is cp operation
constant ctrl_cp_id_lsb_c : natural := 44; -- cp select lsb
constant ctrl_cp_id_msb_c : natural := 45; -- cp select msb
constant ctrl_cp_cmd0_c : natural := 46; -- cp command bit 0
constant ctrl_cp_cmd1_c : natural := 47; -- cp command bit 1
constant ctrl_cp_cmd2_c : natural := 48; -- cp command bit 2
constant ctrl_cp_use_c : natural := 40; -- is cp operation
constant ctrl_cp_id_lsb_c : natural := 41; -- cp select lsb
constant ctrl_cp_id_msb_c : natural := 42; -- cp select msb
constant ctrl_cp_cmd0_c : natural := 43; -- cp command bit 0
constant ctrl_cp_cmd1_c : natural := 44; -- cp command bit 1
constant ctrl_cp_cmd2_c : natural := 45; -- cp command bit 2
-- system --
constant ctrl_sys_c_ext_en_c : natural := 46; -- CPU C extension enabled
constant ctrl_sys_m_ext_en_c : natural := 47; -- CPU M extension enabled
-- control bus size --
constant ctrl_width_c : natural := 49; -- control bus size
constant ctrl_width_c : natural := 48; -- control bus size
 
-- ALU Comparator Bus ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant alu_cmp_equal_c : natural := 0;
constant alu_cmp_less_c : natural := 1; -- for signed and unsigned
constant alu_cmp_less_c : natural := 1; -- for signed and unsigned comparisons
 
-- RISC-V Opcode Layout -------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
279,14 → 279,14
-- cp ids --
constant cp_sel_muldiv_c : std_ulogic_vector(1 downto 0) := "00"; -- MULDIV CP
-- muldiv cp --
constant cp_op_mul_c : std_ulogic_vector(2 downto 0) := "000"; -- mul
constant cp_op_mulh_c : std_ulogic_vector(2 downto 0) := "001"; -- mulh
constant cp_op_mulhsu_c : std_ulogic_vector(2 downto 0) := "010"; -- mulhsu
constant cp_op_mulhu_c : std_ulogic_vector(2 downto 0) := "011"; -- mulhu
constant cp_op_div_c : std_ulogic_vector(2 downto 0) := "100"; -- div
constant cp_op_divu_c : std_ulogic_vector(2 downto 0) := "101"; -- divu
constant cp_op_rem_c : std_ulogic_vector(2 downto 0) := "110"; -- rem
constant cp_op_remu_c : std_ulogic_vector(2 downto 0) := "111"; -- remu
constant cp_op_mul_c : std_ulogic_vector(2 downto 0) := "000"; -- mul
constant cp_op_mulh_c : std_ulogic_vector(2 downto 0) := "001"; -- mulh
constant cp_op_mulhsu_c : std_ulogic_vector(2 downto 0) := "010"; -- mulhsu
constant cp_op_mulhu_c : std_ulogic_vector(2 downto 0) := "011"; -- mulhu
constant cp_op_div_c : std_ulogic_vector(2 downto 0) := "100"; -- div
constant cp_op_divu_c : std_ulogic_vector(2 downto 0) := "101"; -- divu
constant cp_op_rem_c : std_ulogic_vector(2 downto 0) := "110"; -- rem
constant cp_op_remu_c : std_ulogic_vector(2 downto 0) := "111"; -- remu
 
-- ALU Function Codes ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
337,6 → 337,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
390,9 → 391,9
uart_txd_o : out std_ulogic; -- UART send data
uart_rxd_i : in std_ulogic := '0'; -- UART receive data
-- SPI --
spi_sclk_o : out std_ulogic; -- serial clock line
spi_mosi_o : out std_ulogic; -- serial data line out
spi_miso_i : in std_ulogic := '0'; -- serial data line in
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; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- TWI --
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
413,6 → 414,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
471,6 → 473,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
515,8 → 518,9
alu_add_i : in std_ulogic_vector(data_width_c-1 downto 0); -- ALU.add result
-- data output --
imm_o : out std_ulogic_vector(data_width_c-1 downto 0); -- immediate
pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC
alu_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- delayed PC for ALU
fetch_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- PC for instruction fetch
curr_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- current PC (corresponding to current instruction)
next_pc_o : out std_ulogic_vector(data_width_c-1 downto 0); -- next PC (corresponding to current instruction)
-- csr interface --
csr_wdata_i : in std_ulogic_vector(data_width_c-1 downto 0); -- CSR write data
csr_rdata_o : out std_ulogic_vector(data_width_c-1 downto 0); -- CSR read data
531,7 → 535,8
be_instr_i : in std_ulogic; -- bus error on instruction access
be_load_i : in std_ulogic; -- bus error on load data access
be_store_i : in std_ulogic; -- bus error on store data access
bus_exc_ack_o : out std_ulogic -- bus exception error acknowledge
bus_exc_ack_o : out std_ulogic; -- bus exception error acknowledge
bus_busy_i : in std_ulogic -- bus unit is busy
);
end component;
 
559,10 → 564,6
-- Component: CPU ALU ---------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_alu
generic (
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_M : boolean := false -- implement mul/div extension?
);
port (
-- global control --
clk_i : in std_ulogic; -- global clock, rising edge
571,7 → 572,6
-- 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
pc_i : in std_ulogic_vector(data_width_c-1 downto 0); -- current PC
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
610,8 → 610,7
-- -------------------------------------------------------------------------------------------
component neorv32_cpu_bus
generic (
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
MEM_EXT_TIMEOUT : natural := 15 -- cycles after which a valid bus access will timeout
);
port (
-- global control --
634,6 → 633,7
be_load_o : out std_ulogic; -- bus error on load data access
be_store_o : out std_ulogic; -- bus error on store data
bus_wait_o : out std_ulogic; -- wait for bus operation to finish
bus_busy_o : out std_ulogic; -- bus unit is busy
exc_ack_i : in std_ulogic; -- exception controller ACK
-- bus system --
bus_addr_o : out std_ulogic_vector(data_width_c-1 downto 0); -- bus access address
654,7 → 654,6
-- instruction input --
ci_instr16_i : in std_ulogic_vector(15 downto 0); -- compressed instruction input
-- instruction output --
ci_valid_o : out std_ulogic; -- is a compressed instruction
ci_illegal_o : out std_ulogic; -- is an illegal compressed instruction
ci_instr32_o : out std_ulogic_vector(31 downto 0) -- 32-bit decompressed instruction
);
838,9 → 837,9
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- com lines --
spi_sclk_o : out std_ulogic; -- SPI serial clock
spi_mosi_o : out std_ulogic; -- SPI master out, slave in
spi_miso_i : in std_ulogic; -- SPI master in, slave out
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; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- interrupt --
spi_irq_o : out std_ulogic -- transmission done interrupt
1063,4 → 1062,31
return tmp_v;
end function xnor_all_f;
 
-- Function: Convert to hex char ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
function to_hexchar_f(input : std_ulogic_vector(3 downto 0)) return character is
variable output_v : character;
begin
case input is
when x"0" => output_v := '0';
when x"1" => output_v := '1';
when x"2" => output_v := '2';
when x"3" => output_v := '3';
when x"4" => output_v := '4';
when x"5" => output_v := '5';
when x"6" => output_v := '6';
when x"7" => output_v := '7';
when x"8" => output_v := '8';
when x"9" => output_v := '9';
when x"a" => output_v := 'a';
when x"b" => output_v := 'b';
when x"c" => output_v := 'c';
when x"d" => output_v := 'd';
when x"e" => output_v := 'e';
when x"f" => output_v := 'f';
when others => output_v := '?';
end case;
return output_v;
end function to_hexchar_f;
 
end neorv32_package;
/neorv32_spi.vhd
1,5 → 1,5
-- #################################################################################################
-- # << NEORV32 - Serial Peripheral Interface Master (SPI) >> #
-- # << NEORV32 - Serial Peripheral Interface Controller (SPI) >> #
-- # ********************************************************************************************* #
-- # Frame format: 8/16/24/32-bit RTX, MSB or LSB first, 2 clock modes, 8 clock speeds, #
-- # 8 dedicated CS lines (low-active). Interrupt: SPI_transfer_done #
57,9 → 57,9
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(07 downto 0);
-- com lines --
spi_sclk_o : out std_ulogic; -- SPI serial clock
spi_mosi_o : out std_ulogic; -- SPI master out, slave in
spi_miso_i : in std_ulogic; -- SPI master in, slave out
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; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- interrupt --
spi_irq_o : out std_ulogic -- transmission done interrupt
116,8 → 116,8
signal spi_rtx_sreg : std_ulogic_vector(31 downto 0);
signal spi_rx_data : std_ulogic_vector(31 downto 0);
signal spi_bitcnt : std_ulogic_vector(05 downto 0);
signal spi_miso_ff0 : std_ulogic;
signal spi_miso_ff1 : std_ulogic;
signal spi_sdi_ff0 : std_ulogic;
signal spi_sdi_ff1 : std_ulogic;
 
begin
 
217,9 → 217,9
spi_rtx_unit: process(clk_i)
begin
if rising_edge(clk_i) then
-- input (MISO) synchronizer --
spi_miso_ff0 <= spi_miso_i;
spi_miso_ff1 <= spi_miso_ff0;
-- input (sdi) synchronizer --
spi_sdi_ff0 <= spi_sdi_i;
spi_sdi_ff1 <= spi_sdi_ff0;
 
-- serial engine --
spi_irq_o <= '0';
231,8 → 231,8
when others => spi_bitcnt <= "100000"; -- 32-bit mode
end case;
spi_state1 <= '0';
spi_mosi_o <= '0';
spi_sclk_o <= '0';
spi_sdo_o <= '0';
spi_sck_o <= '0';
if (ctrl(ctrl_spi_en_c) = '0') then -- disabled
spi_busy <= '0';
elsif (spi_start = '1') then -- start new transmission
249,19 → 249,19
else -- transmission in progress
if (spi_state1 = '0') then -- first half of transmission
 
spi_sclk_o <= ctrl(ctrl_spi_cpha_c);
spi_sck_o <= ctrl(ctrl_spi_cpha_c);
if (ctrl(ctrl_spi_dir_c) = '0') then
spi_mosi_o <= spi_rtx_sreg(31); -- MSB first
spi_sdo_o <= spi_rtx_sreg(31); -- MSB first
else
spi_mosi_o <= spi_rtx_sreg(0); -- LSB first
spi_sdo_o <= spi_rtx_sreg(0); -- LSB first
end if;
if (spi_clk = '1') then
spi_state1 <= '1';
if (ctrl(ctrl_spi_cpha_c) = '0') then
if (ctrl(ctrl_spi_dir_c) = '0') then
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_miso_ff1; -- MSB first
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; -- MSB first
else
spi_rtx_sreg <= spi_miso_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
spi_rtx_sreg <= spi_sdi_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
end if;
end if;
spi_bitcnt <= std_ulogic_vector(unsigned(spi_bitcnt) - 1);
268,14 → 268,14
end if;
else -- second half of transmission
 
spi_sclk_o <= not ctrl(ctrl_spi_cpha_c);
spi_sck_o <= not ctrl(ctrl_spi_cpha_c);
if (spi_clk = '1') then
spi_state1 <= '0';
if (ctrl(ctrl_spi_cpha_c) = '1') then
if (ctrl(ctrl_spi_dir_c) = '0') then
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_miso_ff1; -- MSB first
spi_rtx_sreg <= spi_rtx_sreg(30 downto 0) & spi_sdi_ff1; -- MSB first
else
spi_rtx_sreg <= spi_miso_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
spi_rtx_sreg <= spi_sdi_ff1 & spi_rtx_sreg(31 downto 1); -- LSB first
end if;
end if;
if (spi_bitcnt = "000000") then
/neorv32_top.vhd
50,6 → 50,7
CLOCK_FREQUENCY : natural := 0; -- clock frequency of clk_i in Hz
HART_ID : std_ulogic_vector(31 downto 0) := x"00000000"; -- custom hardware thread ID
BOOTLOADER_USE : boolean := true; -- implement processor-internal bootloader?
CSR_COUNTERS_USE : boolean := true; -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C : boolean := false; -- implement compressed extension?
CPU_EXTENSION_RISCV_E : boolean := false; -- implement embedded RF extension?
103,9 → 104,9
uart_txd_o : out std_ulogic; -- UART send data
uart_rxd_i : in std_ulogic := '0'; -- UART receive data
-- SPI (available if IO_SPI_USE = true) --
spi_sclk_o : out std_ulogic; -- serial clock line
spi_mosi_o : out std_ulogic; -- serial data line out
spi_miso_i : in std_ulogic := '0'; -- serial data line in
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; -- controller data in, peripheral data out
spi_csn_o : out std_ulogic_vector(07 downto 0); -- SPI CS
-- TWI (available if IO_TWI_USE = true) --
twi_sda_io : inout std_logic := 'H'; -- twi serial data line
315,6 → 316,7
CLOCK_FREQUENCY => CLOCK_FREQUENCY, -- clock frequency of clk_i in Hz
HART_ID => HART_ID, -- custom hardware thread ID
BOOTLOADER_USE => BOOTLOADER_USE, -- implement processor-internal bootloader?
CSR_COUNTERS_USE => CSR_COUNTERS_USE, -- implement RISC-V perf. counters ([m]instret[h], [m]cycle[h], time[h])?
-- RISC-V CPU Extensions --
CPU_EXTENSION_RISCV_C => CPU_EXTENSION_RISCV_C, -- implement compressed extension?
CPU_EXTENSION_RISCV_E => CPU_EXTENSION_RISCV_E, -- implement embedded RF extension?
719,9 → 721,9
clkgen_en_o => spi_cg_en, -- enable clock generator
clkgen_i => clk_gen,
-- com lines --
spi_sclk_o => spi_sclk_o, -- SPI serial clock
spi_mosi_o => spi_mosi_o, -- SPI master out, slave in
spi_miso_i => spi_miso_i, -- SPI master in, slave out
spi_sck_o => spi_sck_o, -- SPI serial clock
spi_sdo_o => spi_sdo_o, -- controller data out, peripheral data in
spi_sdi_i => spi_sdi_i, -- controller data in, peripheral data out
spi_csn_o => spi_csn_o, -- SPI CS
-- interrupt --
spi_irq_o => spi_irq -- transmission done interrupt
732,8 → 734,8
if (IO_SPI_USE = false) generate
spi_rdata <= (others => '0');
spi_ack <= '0';
spi_sclk_o <= '0';
spi_mosi_o <= '0';
spi_sck_o <= '0';
spi_sdo_o <= '0';
spi_csn_o <= (others => '1'); -- CSn lines are low-active
spi_cg_en <= '0';
spi_irq <= '0';
/neorv32_twi.vhd
1,9 → 1,9
-- #################################################################################################
-- # << NEORV32 - Two-Wire Interface Master (TWI) >> #
-- # << NEORV32 - Two-Wire Interface Controller (TWI) >> #
-- # ********************************************************************************************* #
-- # Supports START and STOP conditions, 8 bit data + ACK/NACK transfers and clock stretching. #
-- # Supports ACKs by the master. No multi-master support and no slave mode support yet! #
-- # Interrupt: TWI_transfer_done #
-- # Supports ACKs by the constroller. No multi-controller support and no peripheral mode support #
-- # yet. Interrupt: TWI_transfer_done #
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
79,7 → 79,7
constant ctrl_twi_prsc0_c : natural := 4; -- r/w: CLK prsc bit 0
constant ctrl_twi_prsc1_c : natural := 5; -- r/w: CLK prsc bit 1
constant ctrl_twi_prsc2_c : natural := 6; -- r/w: CLK prsc bit 2
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by master for transmission
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by controller for transmission
--
constant ctrl_twi_ack_c : natural := 30; -- r/-: Set if ACK received
constant ctrl_twi_busy_c : natural := 31; -- r/-: Set if TWI unit is busy
201,7 → 201,7
-- TWI bus signals are set/sampled using 4 clock phases
case arbiter is
 
when "100" => -- IDLE: waiting for requests, bus might be still claimed by this master if no STOP condition was generated
when "100" => -- IDLE: waiting for requests, bus might be still claimed by this controller if no STOP condition was generated
twi_bitcnt <= (others => '0');
if (wr_en = '1') then
if (addr = twi_ctrl_addr_c) then
211,8 → 211,8
arbiter(1 downto 0) <= "10";
end if;
elsif (addr = twi_rtx_addr_c) then -- start a data transmission
-- one bit extra for ack, issued by master if ctrl_twi_mack_c is set,
-- sampled from slave if ctrl_twi_mack_c is cleared
-- one bit extra for ack, issued by controller if ctrl_twi_mack_c is set,
-- sampled from peripheral if ctrl_twi_mack_c is cleared
if (ben_i(0) = '1') then
twi_rtx_sreg <= data_i(7 downto 0) & (not ctrl(ctrl_twi_mack_c));
arbiter(1 downto 0) <= "11";
279,10 → 279,10
-- -------------------------------------------------------------------------------------------
clock_stretching: process(arbiter, twi_scl_o, twi_scl_i_ff1)
begin
-- clock stretching by the slave can happen at "any time"
-- clock stretching by the peripheral can happen at "any time"
if (arbiter(2) = '1') and -- module enabled
(twi_scl_o = '1') and -- master wants to pull scl high
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by slave
(twi_scl_o = '1') and -- controller wants to pull scl high
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral
twi_clk_halt <= '1';
else
twi_clk_halt <= '0';

powered by: WebSVN 2.1.0

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