Components/IP/NanoBlaze
(→Component) |
(→Sources) |
||
(12 intermediate revisions by one user not shown) | |||
Line 1: | Line 1: | ||
{{TOC right}} | {{TOC right}} | ||
− | The '''NanoBlaze''' is a grow-up of the [http://www.xilinx.com/picoblaze.html Xilinx PicoBlaze] | + | The '''NanoBlaze''' is a grow-up of the [http://www.xilinx.com/picoblaze.html Xilinx PicoBlaze] microprocessor, hence the name. |
+ | The PicoBlaze is a simple, orthogonal [https://en.wikipedia.org/wiki/Reduced_instruction_set_computing RISC] [https://en.wikipedia.org/wiki/Von_Neumann_architecture Von Neumann] processor which has raised a large interest and pushed developers to design several device independant [https://en.wikipedia.org/wiki/PicoBlaze variants]. | ||
This processor is used in our [http://wiki.hevs.ch/fsi/index.php5/SEm embedded systems] course lab, together with an I/O space to AHB-Lite adapter. | This processor is used in our [http://wiki.hevs.ch/fsi/index.php5/SEm embedded systems] course lab, together with an I/O space to AHB-Lite adapter. | ||
+ | It processes each instruction, except for the jumps, within a single clock period. | ||
The interrupt logic has not been implemented yet. | The interrupt logic has not been implemented yet. | ||
Line 9: | Line 11: | ||
[[File:nanoBlaze.png|250px|thumb|right]] | [[File:nanoBlaze.png|250px|thumb|right]] | ||
+ | The figure on the right shows the processor's inputs and outputs. | ||
+ | |||
+ | == Generics == | ||
+ | |||
Various sizes can be defined with the help of generic parameters: | Various sizes can be defined with the help of generic parameters: | ||
*<code>registerBitNb</code> defines the data bit width | *<code>registerBitNb</code> defines the data bit width | ||
Line 17: | Line 23: | ||
*<code>addressBitNb</code> defines the size of the I/O space | *<code>addressBitNb</code> defines the size of the I/O space | ||
− | With <code>scratchPadAddressBitNb = 0</code>, the scratchpad is not implemented. | + | With <code>scratchPadAddressBitNb = 0</code>, the scratchpad is not implemented physically. |
− | + | == Speed == | |
− | Contrarily to the PicoBlaze, the NanoBlaze | + | Contrarily to the PicoBlaze, the NanoBlaze executes every instruction within a single clock cycle. |
− | + | This design choice reduces the maximal operating speed compared to the original 2-cycle processor. | |
− | With this, when a branch condition is met, the processor will anyway | + | However, an additional <code>en</code> input allows to have it work at half the clock rate and so catch up the performance of the original processor, |
− | Obviously, | + | as long as the synthesis tool allows to do so (''to be verified''). |
+ | Dividing the operating frequency by a factor greater than 2 allows the NanoBlaze to work in systems working at even higher frequencies | ||
+ | without requiring to split a design into multiple clock domains. | ||
+ | |||
+ | == Synchronous BlockRam delay == | ||
+ | |||
+ | The NanoBlaze's instruction ROM is designed to be mapped as a Block RAM. | ||
+ | Due to this mapping, the instructions are provided delayed by one clock period compared to the program counter. | ||
+ | With this, when a branch condition is met, the processor will anyway have received the instruction of the next memory location. | ||
+ | Obviously, that instruction will not be executed, and this means that every successful branch requires two clock cycles. | ||
= Assembler = | = Assembler = | ||
− | The NanoBlaze has an assembler written in [http://www.perl.org PERL] which runs on any operating system. | + | The NanoBlaze has an assembler written in [http://www.perl.org PERL] which thus runs on any operating system. |
− | + | In our labs, the assembler is integrated in the [[Tools/Mentor_HDL_Designer|Mentor HDL Designer]] environment. | |
− | The VHDL processor code includes a disassembler process which | + | The VHDL processor code includes a disassembler VHDL process which translates the current instruction in the form of a string. |
This string can be displayed in the simulator for debugging purpose. | This string can be displayed in the simulator for debugging purpose. | ||
The corresponding VHDL code is commented out for synthesis via the <code>pragma translate_off</code> clause. | The corresponding VHDL code is commented out for synthesis via the <code>pragma translate_off</code> clause. | ||
Line 37: | Line 52: | ||
= Instruction set = | = Instruction set = | ||
− | The following table shows the instruction set | + | The following table shows the instruction set in the case of an 8 bit processor with 16 registers and 10 program address bits: |
{| class="wikitable" style="text-align:center" | {| class="wikitable" style="text-align:center" | ||
|- | |- | ||
Line 43: | Line 58: | ||
|- | |- | ||
! style="text-align:left" | LOAD sX, kk | ! style="text-align:left" | LOAD sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 00000 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 49: | Line 65: | ||
|- | |- | ||
! style="text-align:left" | LOAD sX, (sY) | ! style="text-align:left" | LOAD sX, (sY) | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | loads register sY into register sX | | style="text-align:left" | loads register sY into register sX | ||
|- | |- | ||
! style="text-align:left" | INPUT sX, kk | ! style="text-align:left" | INPUT sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 00010 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 61: | Line 79: | ||
|- | |- | ||
! style="text-align:left" | INPUT sX, (sY) | ! style="text-align:left" | INPUT sX, (sY) | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | loads I/O value at address sY to register sX | | style="text-align:left" | loads I/O value at address sY to register sX | ||
|- | |- | ||
! style="text-align:left" | FETCH sX, kk | ! style="text-align:left" | FETCH sX, kk | ||
− | | colspan=" | + | | style="border-bottom: 3px solid grey" rowspan="2" colspan="5" | 00011 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
| style="text-align:left" | loads scratchpad value at address kk to register sX | | style="text-align:left" | loads scratchpad value at address kk to register sX | ||
|- | |- | ||
− | ! style="text-align:left; border-bottom: | + | ! style="text-align:left; border-bottom: 3px solid grey" | FETCH sX, (sY) |
− | | colspan=" | + | | style="border-bottom: 3px solid grey" colspan="1" | 1 |
− | | colspan="4" | sX address | + | | style="border-bottom: 3px solid grey" colspan="4" | sX address |
− | | colspan=" | + | | style="border-bottom: 3px solid grey" colspan="4" | sY addr |
− | | style="text-align:left" | loads scratchpad value at address sY to register sX | + | | style="border-bottom: 3px solid grey" colspan="4" | - |
+ | | style="text-align:left; border-bottom: 3px solid grey" | loads scratchpad value at address sY to register sX | ||
|- | |- | ||
! style="text-align:left" | AND sX, kk | ! style="text-align:left" | AND sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 00101 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 85: | Line 107: | ||
|- | |- | ||
! style="text-align:left" | AND sX, sY | ! style="text-align:left" | AND sX, sY | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | applies bitwise AND of register sY pattern to register sX | | style="text-align:left" | applies bitwise AND of register sY pattern to register sX | ||
|- | |- | ||
! style="text-align:left" | OR sX, kk | ! style="text-align:left" | OR sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 00110 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 97: | Line 121: | ||
|- | |- | ||
! style="text-align:left" | OR sX, sY | ! style="text-align:left" | OR sX, sY | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | applies bitwise OR of register sY pattern to register sX | | style="text-align:left" | applies bitwise OR of register sY pattern to register sX | ||
|- | |- | ||
! style="text-align:left" | XOR sX, kk | ! style="text-align:left" | XOR sX, kk | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="2" colspan="5" | 00111 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 109: | Line 135: | ||
|- | |- | ||
! style="text-align:left; border-bottom: 2px solid grey" | XOR sX, sY | ! style="text-align:left; border-bottom: 2px solid grey" | XOR sX, sY | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="1" | 1 |
− | | colspan="4" | sX address | + | | style="border-bottom: 2px solid grey" colspan="4" | sX address |
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="4" | sY addr |
− | | style="text-align:left" | applies bitwise XOR of register sY pattern to register sX | + | | style="border-bottom: 2px solid grey" colspan="4" | - |
+ | | style="text-align:left; border-bottom: 2px solid grey" | applies bitwise XOR of register sY pattern to register sX | ||
|- | |- | ||
! style="text-align:left" | TEST sX, kk | ! style="text-align:left" | TEST sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 01001 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 121: | Line 149: | ||
|- | |- | ||
! style="text-align:left" | TEST sX, sY | ! style="text-align:left" | TEST sX, sY | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | applies bitwise AND between register sY and register sX, only updates C and Z flags | | style="text-align:left" | applies bitwise AND between register sY and register sX, only updates C and Z flags | ||
|- | |- | ||
! style="text-align:left" | COMPARE sX, kk | ! style="text-align:left" | COMPARE sX, kk | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="2" colspan="5" | 01010 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 133: | Line 163: | ||
|- | |- | ||
! style="text-align:left; border-bottom: 2px solid grey" | COMPARE sX, sY | ! style="text-align:left; border-bottom: 2px solid grey" | COMPARE sX, sY | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="1" | 1 |
− | | colspan="4" | sX address | + | | style="border-bottom: 2px solid grey" colspan="4" | sX address |
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="4" | sY addr |
− | | style="text-align:left" | subtracts register sY from register sX, only updates C and Z flags | + | | style="border-bottom: 2px solid grey" colspan="4" | - |
+ | | style="text-align:left; border-bottom: 2px solid grey" | subtracts register sY from register sX, only updates C and Z flags | ||
|- | |- | ||
! style="text-align:left" | ADD sX, kk | ! style="text-align:left" | ADD sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 01100 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 145: | Line 177: | ||
|- | |- | ||
! style="text-align:left" | ADD sX, sY | ! style="text-align:left" | ADD sX, sY | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | adds register sY to register sX | | style="text-align:left" | adds register sY to register sX | ||
|- | |- | ||
! style="text-align:left" | ADDCY sX, kk | ! style="text-align:left" | ADDCY sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 01101 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 157: | Line 191: | ||
|- | |- | ||
! style="text-align:left" | ADDCY sX, sY | ! style="text-align:left" | ADDCY sX, sY | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | adds register sY and carry bit to register sX | | style="text-align:left" | adds register sY and carry bit to register sX | ||
|- | |- | ||
! style="text-align:left" | SUB sX, kk | ! style="text-align:left" | SUB sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 01110 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 169: | Line 205: | ||
|- | |- | ||
! style="text-align:left" | SUB sX, sY | ! style="text-align:left" | SUB sX, sY | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | subtracts register sY from register sX | | style="text-align:left" | subtracts register sY from register sX | ||
|- | |- | ||
! style="text-align:left" | SUBCY sX, kk | ! style="text-align:left" | SUBCY sX, kk | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="2" colspan="5" | 01111 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 181: | Line 219: | ||
|- | |- | ||
! style="text-align:left; border-bottom: 2px solid grey" | SUBCY sX, sY | ! style="text-align:left; border-bottom: 2px solid grey" | SUBCY sX, sY | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="1" | 1 |
− | | colspan="4" | sX address | + | | style="border-bottom: 2px solid grey" colspan="4" | sX address |
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="4" | sY addr |
− | | style="text-align:left" | subtracts register sY and carry bit from register sX | + | | style="border-bottom: 2px solid grey" colspan="4" | - |
+ | | style="text-align:left; border-bottom: 2px solid grey" | subtracts register sY and carry bit from register sX | ||
|- | |- | ||
! style="text-align:left" | SLA sX | ! style="text-align:left" | SLA sX | ||
− | | colspan=" | + | | style="border-bottom: 3px solid grey" rowspan="10" colspan="5" | 10000 |
+ | | colspan="1" | - | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 194: | Line 234: | ||
|- | |- | ||
! style="text-align:left" | RL sX | ! style="text-align:left" | RL sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 201: | Line 241: | ||
|- | |- | ||
! style="text-align:left" | SLX sX | ! style="text-align:left" | SLX sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 208: | Line 248: | ||
|- | |- | ||
! style="text-align:left" | SL0 sX | ! style="text-align:left" | SL0 sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 215: | Line 255: | ||
|- | |- | ||
! style="text-align:left" | SL1 sX | ! style="text-align:left" | SL1 sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 222: | Line 262: | ||
|- | |- | ||
! style="text-align:left" | SRA sX | ! style="text-align:left" | SRA sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 229: | Line 269: | ||
|- | |- | ||
! style="text-align:left" | SRX sX | ! style="text-align:left" | SRX sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 236: | Line 276: | ||
|- | |- | ||
! style="text-align:left" | RR sX | ! style="text-align:left" | RR sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 243: | Line 283: | ||
|- | |- | ||
! style="text-align:left" | SR0 sX | ! style="text-align:left" | SR0 sX | ||
− | | colspan=" | + | | colspan="1" | - |
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="4" | - | | colspan="4" | - | ||
Line 249: | Line 289: | ||
| style="text-align:left" | shifts register sX to the right, LSB set to 0 | | style="text-align:left" | shifts register sX to the right, LSB set to 0 | ||
|- | |- | ||
− | ! style="text-align:left; border-bottom: | + | ! style="text-align:left; border-bottom: 3px solid grey" | SR1 sX |
− | | colspan=" | + | | style="border-bottom: 3px solid grey" colspan="1" | - |
− | | colspan="4" | sX address | + | | style="border-bottom: 3px solid grey" colspan="4" | sX address |
− | | colspan="4" | - | + | | style="border-bottom: 3px solid grey" colspan="4" | - |
− | | colspan="4" | 1111 | + | | style="border-bottom: 3px solid grey" colspan="4" | 1111 |
− | | style="text-align:left" | shifts register sX to the right, LSB set to 1 | + | | style="text-align:left; border-bottom: 3px solid grey" | shifts register sX to the right, LSB set to 1 |
|- | |- | ||
! style="text-align:left" | OUTPUT sX, kk | ! style="text-align:left" | OUTPUT sX, kk | ||
− | | colspan=" | + | | rowspan="2" colspan="5" | 10110 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 263: | Line 304: | ||
|- | |- | ||
! style="text-align:left" | OUTPUT sX, (sY) | ! style="text-align:left" | OUTPUT sX, (sY) | ||
− | | colspan=" | + | | colspan="1" | 1 |
| colspan="4" | sX address | | colspan="4" | sX address | ||
− | | colspan=" | + | | colspan="4" | sY addr |
+ | | colspan="4" | - | ||
| style="text-align:left" | sends register sX to I/O at address sY | | style="text-align:left" | sends register sX to I/O at address sY | ||
|- | |- | ||
! style="text-align:left" | STORE sX, kk | ! style="text-align:left" | STORE sX, kk | ||
− | | colspan=" | + | | style="border-bottom: 3px solid grey" rowspan="2" colspan="5" | 10111 |
+ | | colspan="1" | 0 | ||
| colspan="4" | sX address | | colspan="4" | sX address | ||
| colspan="8" | kk value | | colspan="8" | kk value | ||
Line 275: | Line 318: | ||
|- | |- | ||
! style="text-align:left; border-bottom: 3px solid grey" | STORE sX, (sY) | ! style="text-align:left; border-bottom: 3px solid grey" | STORE sX, (sY) | ||
− | | colspan=" | + | | style="border-bottom: 3px solid grey" colspan="1" | 1 |
− | | colspan="4" | sX address | + | | style="border-bottom: 3px solid grey" colspan="4" | sX address |
− | | colspan=" | + | | style="border-bottom: 3px solid grey" colspan="4" | sY addr |
− | | style="text-align:left" | sends register sX to scratchpad at address sY | + | | style="border-bottom: 3px solid grey" colspan="4" | - |
+ | | style="text-align:left; border-bottom: 3px solid grey" | sends register sX to scratchpad at address sY | ||
|- | |- | ||
! style="text-align:left" | RETURN | ! style="text-align:left" | RETURN | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="5" colspan="5" | 10101 |
− | | colspan="10" | | + | | colspan="1" | 0 |
+ | | colspan="2" | - | ||
+ | | colspan="10" | - | ||
| style="text-align:left" | returns from function call | | style="text-align:left" | returns from function call | ||
|- | |- | ||
! style="text-align:left" | RETURN Z | ! style="text-align:left" | RETURN Z | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="4" colspan="1" | 1 |
− | | colspan="10" | | + | | colspan="2" | 00 |
+ | | colspan="10" | - | ||
| style="text-align:left" | returns from function call if zero flag is set | | style="text-align:left" | returns from function call if zero flag is set | ||
|- | |- | ||
! style="text-align:left" | RETURN NZ | ! style="text-align:left" | RETURN NZ | ||
− | | colspan=" | + | | colspan="2" | 01 |
− | | colspan="10" | | + | | colspan="10" | - |
| style="text-align:left" | returns from function call if zero flag is not set | | style="text-align:left" | returns from function call if zero flag is not set | ||
|- | |- | ||
! style="text-align:left" | RETURN C | ! style="text-align:left" | RETURN C | ||
− | | colspan=" | + | | colspan="2" | 10 |
− | | colspan="10" | | + | | colspan="10" | - |
| style="text-align:left" | returns from function call if carry flag is set | | style="text-align:left" | returns from function call if carry flag is set | ||
|- | |- | ||
! style="text-align:left; border-bottom: 2px solid grey" | RETURN NC | ! style="text-align:left; border-bottom: 2px solid grey" | RETURN NC | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="2" | 11 |
− | | colspan="10" | | + | | style="border-bottom: 2px solid grey" colspan="10" | - |
− | | style="text-align:left" | returns from function call if carry flag is not set | + | | style="text-align:left; border-bottom: 2px solid grey" | returns from function call if carry flag is not set |
|- | |- | ||
! style="text-align:left" | CALL addr | ! style="text-align:left" | CALL addr | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="5" colspan="5" | 11000 |
+ | | colspan="1" | 0 | ||
+ | | colspan="2" | - | ||
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | calls function at address | | style="text-align:left" | calls function at address | ||
|- | |- | ||
! style="text-align:left" | CALL Z addr | ! style="text-align:left" | CALL Z addr | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="4" colspan="1" | 1 |
+ | | colspan="2" | 00 | ||
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | calls function at address if zero flag is set | | style="text-align:left" | calls function at address if zero flag is set | ||
|- | |- | ||
! style="text-align:left" | CALL NZ addr | ! style="text-align:left" | CALL NZ addr | ||
− | | colspan=" | + | | colspan="2" | 01 |
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | calls function at address if zero flag is not set | | style="text-align:left" | calls function at address if zero flag is not set | ||
|- | |- | ||
! style="text-align:left" | CALL C addr | ! style="text-align:left" | CALL C addr | ||
− | | colspan=" | + | | colspan="2" | 10 |
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | calls function at address if carry flag is set | | style="text-align:left" | calls function at address if carry flag is set | ||
|- | |- | ||
! style="text-align:left; border-bottom: 2px solid grey" | CALL NC addr | ! style="text-align:left; border-bottom: 2px solid grey" | CALL NC addr | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="2" | 11 |
− | | colspan="10" | program address | + | | style="border-bottom: 2px solid grey" colspan="10" | program address |
− | | style="text-align:left" | calls function at address if carry flag is not set | + | | style="text-align:left; border-bottom: 2px solid grey" | calls function at address if carry flag is not set |
|- | |- | ||
− | ! style="text-align:left" | JUMP addr | + | ! style="border-bottom: 2px solid grey" style="text-align:left" | JUMP addr |
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="5" colspan="5" | 11010 |
+ | | colspan="1" | 0 | ||
+ | | colspan="2" | - | ||
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | jumps to address | | style="text-align:left" | jumps to address | ||
|- | |- | ||
! style="text-align:left" | JUMP Z addr | ! style="text-align:left" | JUMP Z addr | ||
− | | colspan=" | + | | style="border-bottom: 2px solid grey" rowspan="4" colspan="1" | 1 |
+ | | colspan="2" | 00 | ||
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | jumps to address if zero flag is set | | style="text-align:left" | jumps to address if zero flag is set | ||
|- | |- | ||
! style="text-align:left" | JUMP NZ addr | ! style="text-align:left" | JUMP NZ addr | ||
− | | colspan=" | + | | colspan="2" | 01 |
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | jumps to address if zero flag is not set | | style="text-align:left" | jumps to address if zero flag is not set | ||
|- | |- | ||
! style="text-align:left" | JUMP C addr | ! style="text-align:left" | JUMP C addr | ||
− | | colspan=" | + | | colspan="2" | 10 |
| colspan="10" | program address | | colspan="10" | program address | ||
| style="text-align:left" | jumps to address if carry flag is set | | style="text-align:left" | jumps to address if carry flag is set | ||
|- | |- | ||
− | ! style="text-align:left" | JUMP NC addr | + | ! style="text-align:left; border-bottom: 2px solid grey" | JUMP NC addr |
− | | colspan=" | + | | style="border-bottom: 2px solid grey" colspan="2" | 11 |
− | | colspan="10" | program address | + | | style="border-bottom: 2px solid grey" colspan="10" | program address |
− | | style="text-align:left" | jumps to address if carry flag is not set | + | | style="text-align:left; border-bottom: 2px solid grey" | jumps to address if carry flag is not set |
+ | |- | ||
+ | ! style="text-align:left" | RETURNI DISABLE | ||
+ | | style="border-bottom: 2px solid grey" rowspan="2" colspan="5" | 11100 | ||
+ | | colspan="12" | - | ||
+ | | 0 | ||
+ | | style="text-align:left" | return from interrupt, disable further interrupts (''not implemented yet'') | ||
+ | |- | ||
+ | ! style="text-align:left; border-bottom: 2px solid grey" | RETURNI ENABLE | ||
+ | | style="border-bottom: 2px solid grey" colspan="12" | - | ||
+ | | style="border-bottom: 2px solid grey" | 1 | ||
+ | | style="text-align:left; border-bottom: 2px solid grey" | return from interrupt, enable further interrupts (''not implemented yet'') | ||
+ | |- | ||
+ | ! style="text-align:left" | DISABLE INTERRUPT | ||
+ | | rowspan="2" colspan="5" | 11110 | ||
+ | | colspan="12" | - | ||
+ | | 0 | ||
+ | | style="text-align:left" | disable interrupts (''not implemented yet'') | ||
+ | |- | ||
+ | ! style="text-align:left" | ENABLE INTERRUPT | ||
+ | | colspan="12" | - | ||
+ | | 1 | ||
+ | | style="text-align:left" | enable interrupts (''not implemented yet'') | ||
|} | |} | ||
− | The length of the instruction is adapted to cope with the different generic values associated to the component. | + | The length of the instruction word is automatically adapted to cope with the different generic values associated to the component. |
= Sources = | = Sources = | ||
This IP is found in the HEVs EDA Repository: svn: https://repos.hevs.ch/svn/eda/ | This IP is found in the HEVs EDA Repository: svn: https://repos.hevs.ch/svn/eda/ | ||
+ | |||
+ | [[Category:Components]] [[Category:Designs]] [[Category:VHDL]] [[Category:IP]] |
Latest revision as of 09:35, 28 June 2018
|
The NanoBlaze is a grow-up of the Xilinx PicoBlaze microprocessor, hence the name. The PicoBlaze is a simple, orthogonal RISC Von Neumann processor which has raised a large interest and pushed developers to design several device independant variants.
This processor is used in our embedded systems course lab, together with an I/O space to AHB-Lite adapter. It processes each instruction, except for the jumps, within a single clock period.
The interrupt logic has not been implemented yet.
Component
The figure on the right shows the processor's inputs and outputs.
Generics
Various sizes can be defined with the help of generic parameters:
registerBitNb
defines the data bit widthregisterAddressBitNb
allows to choose the number of internal registersprogramCounterBitNb
allows to cope with different program lengthsstackPointerBitNb
adapts to various nesting depths of the subroutinesscratchPadAddressBitNb
allows to manage the size of the scratchpadaddressBitNb
defines the size of the I/O space
With scratchPadAddressBitNb = 0
, the scratchpad is not implemented physically.
Speed
Contrarily to the PicoBlaze, the NanoBlaze executes every instruction within a single clock cycle.
This design choice reduces the maximal operating speed compared to the original 2-cycle processor.
However, an additional en
input allows to have it work at half the clock rate and so catch up the performance of the original processor,
as long as the synthesis tool allows to do so (to be verified).
Dividing the operating frequency by a factor greater than 2 allows the NanoBlaze to work in systems working at even higher frequencies
without requiring to split a design into multiple clock domains.
Synchronous BlockRam delay
The NanoBlaze's instruction ROM is designed to be mapped as a Block RAM. Due to this mapping, the instructions are provided delayed by one clock period compared to the program counter. With this, when a branch condition is met, the processor will anyway have received the instruction of the next memory location. Obviously, that instruction will not be executed, and this means that every successful branch requires two clock cycles.
Assembler
The NanoBlaze has an assembler written in PERL which thus runs on any operating system. In our labs, the assembler is integrated in the Mentor HDL Designer environment.
The VHDL processor code includes a disassembler VHDL process which translates the current instruction in the form of a string.
This string can be displayed in the simulator for debugging purpose.
The corresponding VHDL code is commented out for synthesis via the pragma translate_off
clause.
Instruction set
The following table shows the instruction set in the case of an 8 bit processor with 16 registers and 10 program address bits:
instruction | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | function |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LOAD sX, kk | 00000 | 0 | sX address | kk value | loads constant kk into register sX | ||||||||||||||
LOAD sX, (sY) | 1 | sX address | sY addr | - | loads register sY into register sX | ||||||||||||||
INPUT sX, kk | 00010 | 0 | sX address | kk value | loads I/O value at address kk to register sX | ||||||||||||||
INPUT sX, (sY) | 1 | sX address | sY addr | - | loads I/O value at address sY to register sX | ||||||||||||||
FETCH sX, kk | 00011 | 0 | sX address | kk value | loads scratchpad value at address kk to register sX | ||||||||||||||
FETCH sX, (sY) | 1 | sX address | sY addr | - | loads scratchpad value at address sY to register sX | ||||||||||||||
AND sX, kk | 00101 | 0 | sX address | kk value | applies bitwise AND of constant kk pattern to register sX | ||||||||||||||
AND sX, sY | 1 | sX address | sY addr | - | applies bitwise AND of register sY pattern to register sX | ||||||||||||||
OR sX, kk | 00110 | 0 | sX address | kk value | applies bitwise OR of constant kk pattern to register sX | ||||||||||||||
OR sX, sY | 1 | sX address | sY addr | - | applies bitwise OR of register sY pattern to register sX | ||||||||||||||
XOR sX, kk | 00111 | 0 | sX address | kk value | applies bitwise XOR of constant kk pattern to register sX | ||||||||||||||
XOR sX, sY | 1 | sX address | sY addr | - | applies bitwise XOR of register sY pattern to register sX | ||||||||||||||
TEST sX, kk | 01001 | 0 | sX address | kk value | applies bitwise AND between constant kk and register sX, only updates C and Z flags | ||||||||||||||
TEST sX, sY | 1 | sX address | sY addr | - | applies bitwise AND between register sY and register sX, only updates C and Z flags | ||||||||||||||
COMPARE sX, kk | 01010 | 0 | sX address | kk value | subtracts constant kk from register sX, only updates C and Z flags | ||||||||||||||
COMPARE sX, sY | 1 | sX address | sY addr | - | subtracts register sY from register sX, only updates C and Z flags | ||||||||||||||
ADD sX, kk | 01100 | 0 | sX address | kk value | adds constant kk to register sX | ||||||||||||||
ADD sX, sY | 1 | sX address | sY addr | - | adds register sY to register sX | ||||||||||||||
ADDCY sX, kk | 01101 | 0 | sX address | kk value | adds constant kk and carry bit to register sX | ||||||||||||||
ADDCY sX, sY | 1 | sX address | sY addr | - | adds register sY and carry bit to register sX | ||||||||||||||
SUB sX, kk | 01110 | 0 | sX address | kk value | subtracts constant kk from register sX | ||||||||||||||
SUB sX, sY | 1 | sX address | sY addr | - | subtracts register sY from register sX | ||||||||||||||
SUBCY sX, kk | 01111 | 0 | sX address | kk value | subtracts constant kk and carry bit from register sX | ||||||||||||||
SUBCY sX, sY | 1 | sX address | sY addr | - | subtracts register sY and carry bit from register sX | ||||||||||||||
SLA sX | 10000 | - | sX address | - | 0000 | shifts register sX to the left, C flag goes to LSB | |||||||||||||
RL sX | - | sX address | - | 0010 | rotates register sX to the left, LSB goes to LSB | ||||||||||||||
SLX sX | - | sX address | - | 0100 | shifts register sX to the left, LSB remains in LSB | ||||||||||||||
SL0 sX | - | sX address | - | 0110 | shifts register sX to the left, LSB set to 0 | ||||||||||||||
SL1 sX | - | sX address | - | 0111 | shifts register sX to the left, LSB set to 1 | ||||||||||||||
SRA sX | - | sX address | - | 1000 | shifts register sX to the right, C flag goes to MSB | ||||||||||||||
SRX sX | - | sX address | - | 1010 | shift register sX to the right, MSB remains in MSB | ||||||||||||||
RR sX | - | sX address | - | 1100 | rotates register sX to the right, LSB goes to MSB | ||||||||||||||
SR0 sX | - | sX address | - | 1110 | shifts register sX to the right, LSB set to 0 | ||||||||||||||
SR1 sX | - | sX address | - | 1111 | shifts register sX to the right, LSB set to 1 | ||||||||||||||
OUTPUT sX, kk | 10110 | 0 | sX address | kk value | sends register sX to I/O at address kk | ||||||||||||||
OUTPUT sX, (sY) | 1 | sX address | sY addr | - | sends register sX to I/O at address sY | ||||||||||||||
STORE sX, kk | 10111 | 0 | sX address | kk value | sends register sX to scratchpad at address kk | ||||||||||||||
STORE sX, (sY) | 1 | sX address | sY addr | - | sends register sX to scratchpad at address sY | ||||||||||||||
RETURN | 10101 | 0 | - | - | returns from function call | ||||||||||||||
RETURN Z | 1 | 00 | - | returns from function call if zero flag is set | |||||||||||||||
RETURN NZ | 01 | - | returns from function call if zero flag is not set | ||||||||||||||||
RETURN C | 10 | - | returns from function call if carry flag is set | ||||||||||||||||
RETURN NC | 11 | - | returns from function call if carry flag is not set | ||||||||||||||||
CALL addr | 11000 | 0 | - | program address | calls function at address | ||||||||||||||
CALL Z addr | 1 | 00 | program address | calls function at address if zero flag is set | |||||||||||||||
CALL NZ addr | 01 | program address | calls function at address if zero flag is not set | ||||||||||||||||
CALL C addr | 10 | program address | calls function at address if carry flag is set | ||||||||||||||||
CALL NC addr | 11 | program address | calls function at address if carry flag is not set | ||||||||||||||||
JUMP addr | 11010 | 0 | - | program address | jumps to address | ||||||||||||||
JUMP Z addr | 1 | 00 | program address | jumps to address if zero flag is set | |||||||||||||||
JUMP NZ addr | 01 | program address | jumps to address if zero flag is not set | ||||||||||||||||
JUMP C addr | 10 | program address | jumps to address if carry flag is set | ||||||||||||||||
JUMP NC addr | 11 | program address | jumps to address if carry flag is not set | ||||||||||||||||
RETURNI DISABLE | 11100 | - | 0 | return from interrupt, disable further interrupts (not implemented yet) | |||||||||||||||
RETURNI ENABLE | - | 1 | return from interrupt, enable further interrupts (not implemented yet) | ||||||||||||||||
DISABLE INTERRUPT | 11110 | - | 0 | disable interrupts (not implemented yet) | |||||||||||||||
ENABLE INTERRUPT | - | 1 | enable interrupts (not implemented yet) |
The length of the instruction word is automatically adapted to cope with the different generic values associated to the component.
Sources
This IP is found in the HEVs EDA Repository: svn: https://repos.hevs.ch/svn/eda/