This is a simple CPU architecture that I used to verify that I understand how to use FPGAs, VHDL, and write a CPU. This is my largest project to date.
Clock Speed. | |
---|---|
Word size | 32 Bits |
Memory | 4096 Words |
Average Instructions per second. | 16.6KIPS |
Cache | 0 |
Cores | 1 |
Registers | 16 |
Interrupt | 32 |
IO Addresses | 256 |
-
Computer (Laptop) - 13th Gen i9-13900 2.20GHz, 32 GB
-
Arty-S7 Rev-E with AMD XC7S50-1CSGA324C FPGA
Description Specification Logic Slices 8,150 6-Input LUT 32,200 Flip-Flops 65,200 Block RAM 337.5 KB DPS 120 Clock 100 MHz / 12 MHz (Max 450 MHz)
-
Connectivity and IO
Input/Output Specification USB USB-UART USB-JTAG Programmer Pmod Connectors 4 Other Connectors Arduino/chipKIT shield connector Switches 4 slide switches Buttons 4 Push buttons LEDs 4 LEDs, 2 RGB LEDs
- Microsoft Windows 11 Pro
- AMD Vivado v2023.2 (64-bit)
- VHDL 2K
- Visual Studio Code
- Extensions
- VHDL
- CustomAsm
- Extensions
- CustomAsm
-
Block Memory Generator v8.4
-
Interface Type: Native
-
Memory Type :True Dual Port RAM
-
Port A/B
- Write Width - 32 bits
- Read Width - 32 bits
- Write Depth - 4096
- Read Depth - 4096
- Primitive Output Register
-
Other Options
- Load Init File - Program.coe
- Fill Remaining Memory Locations - A5
-
Read Latency - 2 cycles
-
Clock Speed | |
---|---|
32 Bit words | |
4096 Word Memory | |
Average Instructions per second | |
Cache | |
No. Cores | |
No. Registers | |
No. Interrupt | |
No. IO Addresses | |
- Instructions are the same length.
- Memory is accessed in the same length as Instructions. Word and Instruction length is 32 bits.
- All instructions contain the same fields. Some fields are not used for some instructions.
- Each instruction contains 2 register fields.
- Only the store commands will update memory.
- There will be 16 registers.
- No status flags are required. Branches compare 2 registers.
Opcode | Flag | Access (Memory) |
Register 1 | Register 2 | Immediate / Address |
|
---|---|---|---|---|---|---|
Bit Position | 31-27 | 26 | 25-24 | 23-20 | 19-16 | 15-0 |
Number Bits | 5 | 1 | 2 | 4 | 4 | 16 |
Description | Hi/Low / Not | 0 = Register / Register 1 = Immediate 2 = Absolute 3 = Indexed |
Destination / Accumulator | Source / Index |
Recommendation: R0 not be used as a user register.
There are 5 bits for the opcode.
Load instruction - High 1/2 word = 1, Low 1/2 Word = 0
1 = NOT for the following instructions:
- Branch
- And
- Nand
- Or
- Nor
- Xor
- Xnor
Register/Register - The first register is an destination/accumulator. The second register is a source/memory index.
Immediate - This is 16-bit data that can be used to load or change the accumulator.
Absolute - This gets the address from the 16-bit Immediate part of the instruction.
Index - This gets the address from the addition of the 2nd register and the Immediate part of the instruction.
The first Register is the destination for load, source for the store, and accumulator for Add, Subtract, And, etc.
The Second Register is the source or index. For Operations (Add, Subtract, Add, etc.) this can be added to the Immediate value. If Register 0 is used then nothing will be used in the operation. For Branch instruction the second Register is Register 0 this will cause Register 1 to be compared with 0 (branch zero, branch not zero, branch negative and branch positive, etc).
The immediate part of the instruction is limited to 16 bits. It can only load the lower half of the word. Setting the flag will cause the load to work on the higher bits. The Immediate is currently an unsigned integer.
The CPU contains the Finite State Model for the instruction cycle. All of the processes are located in other modules. The Program Counter module includes the process to update the program counter and instruction address. The Memory Access module includes updating the instruction's memory argument (data). The Arithmetic Logic Unit (ALU) updates the register with the instruction operation. The IO Processing performs operations which sets the address, read/write enable, and writes data to the computer. The Wait / Timer module the wait pauses the instructions from executing and sleep will allow the processor to continue, and call an interrupt when the time expires. The Interrupt process will start when an interrupt happens then it stores the program counter and mask to the stack and calls the interrupt.
The Memory IP is maintained external to the CPU (currently inside the test Computer Module). Nothing prevents Port A and Port B from being different Memory Module.
The operation cycles are in the following order: ADDRESS, INSTFETCH1, INSTFETCH2, DECODE, MEMFETCH1, MEMFETCH2, EXECUTE, and CLEANUP. Some instructions do not use all of the cycles. Example: the MEMFETCH1only is used during Read / Write IO operations, other operations completely skipped this cycle. Another exception MEMFETCH1 and MEMFETCH2 cycles are skipped when the operation is not a Memory read (Access / Memory operations 2 and 3).
During each cycle, the Access (Memory) value is selected (Case statement) and then the Opcode is selected (Case). This is opposite to the normal method of CPU operation (Opcode first, Memory second).
Signal | Description |
---|---|
IO_ADDR | Address of the IO peripheral. |
IOW_DATA | Data to be written to the peripheral. |
IOW_ENA | Flag indicating the transfer of data from CPU to peripheral. |
IOR_ENA | Flag indicating the data needs to be transferred from peripheral to CPU. |
MEM_ENA | Enable at Address and disable during the Decode for branches. |
MEM_WEA | Always 0 (Read Only) |
MEM_ADDRA | The address to Read or Write memory. |
MEM_ENB | The Instruction Memory enabled. |
MEM_WEB | The Instruction Memory Read/Write. |
MEM_ADDRB | The Instruction address to Read or Write memory. |
MEM_DINB | The Instruction input data. |
Signal | Description |
---|---|
IOR_DATA | Data from the peripheral device. |
IO_STATUS | The IO status from the peripheral device. |
INTERRUPT | The Interrupt vector |
MEM_DINB | Instruction operation. |
MEM_DINB | The Instruction input data. |
Signal | Description |
---|---|
Program Counter | Program counter (address) of the current executed statement. |
fsm_inst_cycle_p / fsm_inst_cycle_n | Instruction finite state model (See below) |
flag/ffflag | Multiple use flag (e.g., negative logic) |
opcode/ffopcode | Instruction operation |
memop/ffmemop | Memory access operation. |
regop1/iregop1/ffiregop1 | Instruction identified first register. |
ireg1value | Value of the Register pointed to by instruction. |
regop2/iregop2/ffiregop2 | Instruction identified second register. |
ireg2value | Value of the Register pointed to by instruction. |
immop/ffimmop | Immediate value from the instruction. |
cpuRegs | The fast CPU registers. |
fsm_interrupt_cycle_p | Interrupt finite state model |
interruptRun | Flag indicating that the interrupt is running. |
interruptNum | Interrupt number being processed (1-31) |
interruptMask | The Interrupt enable mask (1 is enabled). |
interruptSpNum | The stack pointer register. |
interruptSpAddrValue | The value of the stack pointer at the starting of the interrupt. |
waitRun | This is active when it is in a wait state. |
waitAlarm | The alarm happens when the wait timer is completed. |
waitCancel | This cancels the wait state. |
timerAlarm | This alarm happens when the timer is completed. |
timerInt | The interrupt number is to be processed when the timer alarm goes off. |
Cycle | Description |
---|---|
ADDRESS | Sets the instruction address. Start interrupt processing |
INSTFETCH1 | Wait for instruction data. |
INSTFETCH2 | Wait for instruction data. |
DECODE | Instruction Data is available and the Instruction is separated into different fields. The main purpose is to get the values required to perform the operations. For Memory operations 0 (Register/Register), the register values are obtained. For Memory Operation 1 the Registers and the Immediate values. For Memory Operation 2, the Immediate value is used as the Memory address. For Memory Operation 3, the Register and the Immediate values are added and used as the Memory address. |
MEMFETCH1 | Wait for Access (Memory) types 2 and 3. The Return from Interrupt (RTI) operation reads the stack for the Interrupt Mask. |
MEMFETCH2 | Wait for Read for Access (Memory) types 2 and 3. |
EXECUTE | Perform the operations. |
CLEANUP | Perform additional items after Execute. Read and Write operations are the only operations that use this cycle state to reset the enable flag. |
stateDiagram
[*] --> ADDRESS_S : Reset
ADDRESS_S --> INSTFETCH1_S
INSTFETCH1_S --> INSTFETCH2_S
INSTFETCH2_S --> DECODE_S
DECODE_S --> MEMFETCH1_S : addr modes 2 & 3
MEMFETCH1_S --> MEMFETCH2_S
MEMFETCH2_S --> EXECUTE_S
DECODE_S --> EXECUTE_S : addr modes 0 & 1
EXECUTE_S --> ADDRESS_S : jumps & branches
EXECUTE_S --> CLEANUP_S : rio & wio
EXECUTE_S --> DECODE_S : addr modes 2 & 3
EXECUTE_S --> INSTFETCH2_S : addr modes 0 & 1
CLEANUP_S --> ADDRESS_S
This handles the program counter (PC) and memory access for obtaining the instruction. This sets the address of the next instruction (Port A memory access). This is the fetch.
- oJMP - Unconditional Jump
- oJSR - Jump and store PC (Jump to Subroutine)
- oRTN - Return from JSR (Return from Subroutine)
- oRTI - Return from Interrupt
- oBE - Branch Equal, Zero, Not Equal, or Not Zero
- oBLT - Branch Less Than, Negative, Greater than and Equal, Not Negative
- oBGT - Branch Greater Than, Positive, Less than and Equal, Not Positive
Signal | Description |
---|---|
MEM_ADDRA | The address to Read or Write memory. |
MEM_ENA | Enable at Address and disable during the Decode for branches. |
MEM_WEA | Always 0 (Read Only) |
Program Counter | Program counter (address) of the current executed statement. |
Note: Actually setting MEM_DOUTA (writting memory) is not part of this process. Note: The Program Counter is a Combinational output of the internal ProgCounterLocal.
Signal | Description |
---|---|
INSTRUCTION | Current Fetched Instruction |
cpuRegs | CPU Fast Registers |
fsm_inst_cycle_p | Process States: |
RESET_STATE_S - Reset the CPU. | |
ADDRESS_S - Setting the address from the program counter. This sets the clears the memory enable. | |
DECODE_S - Instruction Decode and identify operands. Sets up the Memory addresses and write data. | |
EXECUTE_S - Execute the instruction. To process interrupts, store registers/data. | |
fsm_interrupt_cycle_p | Process States: |
JUMP_S - Changes the program counter to address from the interrupt vector. |
Signal | Description |
---|---|
opcode/ffopcode | Instruction operation |
ffflag | Multiple use flag to modify the instruction operation (e.g., negative logic) |
ffmemop | Memory access operation (Reg/Reg, Immediate, absolute and indexed). |
ffiregop1 | Instruction identified first register. |
ffiregop2 | Instruction identified second register. |
ireg1value | Register value of the first instruction register. |
ireg2value | Register value of the second instruction register. |
ffimmop | Immediate value from the instruction. |
ProgCounterLocal | Local Program Counter used for calculations. |
Note: During the Decode state, the MEM_DOUTA is separated into opcode, flag, memop, regop1, regop2, and immop combinational wires. The ff* are clocked flip-flop registers that store the values to be used in other states.
This handles the memory access for the operand, stack, and etc. memory. This used the Port B memory access.
- oSTR - Store memory to register
- oRWIO - Read and store memory.
Signal | Description |
---|---|
MEM_ENB | The Instruction Memory enabled. |
MEM_WEB | The Instruction Memory Read/Write. |
MEM_ADDRB | The Instruction address to Read or Write memory. |
MEM_DINB | The Instruction input data. |
Note: Actually setting MEM_DOUTB (writting memory) is not part of this process. But setting the address to write memory is being set. This does not used 3-state addresses, could make use of it in the future.
Signal | Description |
---|---|
INSTRUCTION | Instruction operation |
cpuRegs | The fast CPU registers. |
fsm_inst_cycle_p | Process States: |
RESET_STATE_S - Reset the CPU. | |
ADDRESS_S - Setting the address from the program counter. This sets clears the memory enable. | |
DECODE_S - Instruction Decode and identify operands. Sets up the Memory addresses and writes data. | |
MEMFETCH1_S - Waits to read (MEM_DOUTB) because of the memory legacy and latches. This is use to pop interrupt PC and mask. | |
MEMFETCH2_S - Waits to read (MEM_DOUTB) because of the memory legacy and latches | |
EXECUTE_S - Execute the instruction. To process interrupts, and store registers/data. | |
CLEANUP_S - Clean up data after execute state. | |
fsm_interrupt_cycle_p | Process States: |
SAVEENA_S (State 2) - Saves the Interrupt Enable Mask. | |
DISABLEINT_S (State 3) - Disable all Interrupts. | |
JMPADDR_S (State 4) - Get the Interrupt Handler from address vector. | |
JMPFETCH2_S (State 6) - Memory Read Latency | |
interruptRun | Flag indicating that the interrupt is running. |
interruptNum | Interrupt number being processed (1-31) |
interruptMask | The Interrupt enable mask (1 is enabled). |
interruptSpAddrValue | The value of the stack pointer at the starting of the interrupt. |
ProgramCounter | Program counter (address) of the current executed statement. |
Signal | Description |
---|---|
flag/ffflag | Multiple use flag (e.g., negative logic) |
opcode/ffopcode | Instruction operation |
memop/ffmemop | Memory access operation. |
regop1/iregop1/ffiregop1 | Instruction identified first register. |
ireg1value | Value of the Register pointed to by instruction. |
regop2/iregop2/ffiregop2 | Instruction identified second register. |
ireg2value | Value of the Register pointed to by instruction. |
immop/ffimmop | Immediate value from the instruction. |
This handles the updating and operating on the register and is also known as the Arithmetic Logic Unit (ALU).
- oLD - Move Register contents, load memory to register
- oRTN - Return from JSR (Return from Subroutine)
- oRTI - Return from InterruptoRTN
- oADD - Add registers, immediate, or memory
- oSUB - Subtract registers, immediate, or memory
- oAND - And or Nand registers, immediate, or memory
- oOR - Or or Nor registers, immediate, or memory
- oXOR - Xor or Xnor registers, immediate, or memory
- oSHL - Shift left registers, immediate, or memory
- oSHR - Shift right registers, immediate, or memory
- oJSR - Jump and store PC (Jump to Subroutine)
- oRWIO - Load and write to IO.
- oPUSHPOP - Push or Pop from memory
Signal | Description |
---|---|
cpuRegs | The fast CPU registers. |
Signal | Description |
---|---|
INSTRUCTION | Instruction operation |
MEM_ARG | The current memory argument from decode. |
fsm_inst_cycle_p | Process States: |
RESET_STATE_S - Reset the CPU. | |
EXECUTE_S - Execute the instruction. To process interrupts, store registers/data. | |
CLEANUP_S - Clean up data after execute. | |
fsm_interrupt_cycle_p | Process States: |
SAVEENA_S (State 2) - Saves the Interrupt Enable Mask. | |
JMPADDR_S (State 4) - Get the Interrupt Handler from address vector. | |
interruptSPNum | |
IOR_DATA | Data from the peripheral device. |
IO_STATUS | The IO status from the peripheral device. |
ireg1value | Value of the Register pointed to by instruction. |
ffiregop2 | Instruction identified second register. |
ireg2value | Value of the Register pointed to by instruction. |
interruptSpAddrValue |
Signal | Description |
---|---|
ffopcode | Instruction operation |
ffflag | Multiple use flag (e.g., negative logic) |
ffmemop | Memory access operation. |
ffiregop1 | Instruction identified first register. |
ffiregop2 | Instruction identified second register. |
ffimmop | Immediate value from the instruction. |
This handles the address, data, and statuses for IO.
- oRWIO - Interface with the IO signals.
Signal | Description |
---|---|
IO_ADDR | Address of the IO peripheral. |
IOW_DATA | Data to be written to the peripheral. |
IOW_ENA | Flag indicating the transfer of data from CPU to peripheral. |
IOR_ENA | Flag indicating the data needs to be transferred from peripheral to CPU. |
Note: Interrupt driven peripheral should use the Interrupts Processing (No special purpose IO interrupts). Note: Reading the IO (IOR_DATA) is not performed in this process. it is used by other processes.
Signal | Description |
---|---|
INSTRUCTION | Instruction operation |
MEM_ARG | The current memory argument from decode. |
fsm_inst_cycle_p | Process States: |
RESET_STATE_S - Reset the CPU. | |
DECODE_S - Instruction Decode and identify operands. | |
EXECUTE_S - Execute the instruction. To process interrupts, store registers/data. | |
CLEANUP_S - Clean up data after execute. | |
cpuRegs | The fast CPU registers. |
Signal | Description |
---|---|
flag/ffflag | Multiple use flag (e.g., negative logic) |
opcode/ffopcode | Instruction operation |
memop/ffmemop | Memory access operation. |
regop1/iregop1/ffiregop1 | Instruction identified first register. |
ireg1value | Value of the Register pointed to by instruction. |
regop2/iregop2/ffiregop2 | Instruction identified second register. |
ireg2value | Value of the Register pointed to by instruction. |
immop/ffimmop | Immediate value from the instruction. |
- oWAIT - Wait, Timer or Cancel.
This processes the wait instruction which pauses execution and sleep which continues the execution, but when the alarm happens it will call a interrupt. The wait and sleep timers count the clock.
Signal | Description |
---|---|
waitAlarm | The alarm happens when the wait timer is completed. |
waitRun | This is active when it is in a wait state. |
waitCancel | This cancels the wait state. |
timerAlarm | This alarm happens when the timer is completed. |
timerInt | The interrupt number is to be processed when the timer alarm goes off. |
Note: Interrupt driven peripheral should use the Interrupts Processing (No special purpose IO interrupts). Note: Reading the IO (IOR_DATA) is not performed in this process. it is used by other processes.
Signal | Description |
---|---|
INSTRUCTION | Instruction operation |
fsm_inst_cycle_p | Process States: |
RESET_STATE_S - Reset the CPU. | |
DECODE_S - Instruction Decode and identify operands. | |
EXECUTE_S - Execute the instruction. To process interrupts, store registers/data. | |
cpuRegs | The fast CPU registers. |
Signal | Description |
---|---|
flag/ffflag | Multiple use flag (e.g., negative logic) |
opcode/ffopcode | Instruction operation |
memop/ffmemop | Memory access operation. |
regop1/iregop1/ffiregop1 | Instruction identified first register. |
ireg1value | Value of the Register pointed to by instruction. |
regop2/iregop2/ffiregop2 | Instruction identified second register. |
ireg2value | Value of the Register pointed to by instruction. |
immop/ffimmop | Immediate value from the instruction. |
waitReg | This is the wait register. |
waitTime | This is the wait timer. |
waitCount | This is the counter for the timer. |
waitResolution | This is the resolution of the wait timer. |
waitResCounter | This counter will count the number of resolution values. |
waitRunLocal | This is the local value of the wait run. |
waitCancelLocal | This is the local value of the cancel. |
timerRun | This is active when the timer is running. |
timerReg | This is the timer register number. |
timerTime | This is the wait timer. |
timerCount | This is the counter for the timer. |
timerResolution | This is the resolution of the wait timer. |
timerResCounter | This counter will count the number of resolution values. |
This handles the interrupt put the Mask and program counter on the stack and calls the interrupt handler. The maintains it own finite state machine (FSM).
Signal | Description |
---|---|
fsm_interrupt_cycle_p | |
INTRWAIT_S (State 0) - Wait for Interrupt | |
CYCLEWAIT_S (State 1) - Wait for Instruction Cycle to complete. | |
SAVEENA_S (State 2) - Saves the Interrupt Enable Mask. | |
DISABLEINT_S (State 3) - Disable all Interrupts. | |
JMPADDR_S (State 4) - Get the Interrupt Handler from address vector. | |
JMPFETCH1_S (State 5) - Memory Read Latency | |
JMPFETCH2_S (State 6) - Memory Read Latency | |
JUMP_S (State 7) - Start the Instruction Cycle with Interrupt Handler. | |
DONE_S (State 8) - Complete the Interrupt processing. | |
interruptRun | Flag indicating that the interrupt is running. |
interruptNum | Interrupt number being processed (1-31) |
interruptMask | The Interrupt enable mask (1 is enabled). |
interruptSpNum | The stack pointer register. |
interruptSpAddrValue | The value of the stack pointer at the starting of the interrupt. |
Note: Limitations 1) The interrupt is read when instruction in execute state.
Signal | Description |
---|---|
INSTRUCTION | Current Fetched Instruction |
cpuRegs | CPU Registers |
fsm_inst_cycle_p | Process States: |
RESET_STATE_S - Reset the CPU. | |
DECODE_S - Instruction Decode and identify operands. | |
EXECUTE_S - Execute the instruction. | |
CLEANUP_S - Clean up data after execute. | |
MEM_ARG | The current memory argument from decode. |
INTERRUPT | The Interrupt vector |
timerAlarm | Completion of the timer alarm. |
timerInt | The interrupt number (1-31) |
Signal | Description |
---|---|
opcode/ffopcode | Instruction operation |
ffflag | Multiple use flag (e.g., negative logic) |
memop/ffmemop | Memory access operation. |
ffiregop1 | Instruction identified first register. |
ireg1value | Value of the Register pointed to by instruction. |
ireg2value | Value of the Register pointed to by instruction. |
ffimmop | Immediate value from the instruction. |
fsm_interrupt_cycle_p_local | |
Local value of the current state (set and used). | |
fsm_interrupt_cycle_n | Next interrupt state. |
interBitNum | Interrupt bit number (interrupt number) |
interruptMaskLocal | Local value of the Mask (set and used). |
interruptSpNumLocal | Local value of the interrupt stack register number (set and used). |
Cycle | Description |
---|---|
Interrupt Processing | |
SAVEENA | IntEna → dinB reg(InterSP) → reg(InterSP) – 1 |
DISABLEINT | ’0’ → IntEna(interNum) reg(InterSP) → addrB PC → dinB |
JMPADDR | reg(InterSP) → reg(InterSP) – 1 InterNum → addrB |
JMPFETCH1 | Wait |
JMPFETCH2 | Wait |
JUMP | DoutB → PC |
stateDiagram
[*] --> INTRWAIT_S
INTRWAIT_S --> INTRWAIT_S
INTRWAIT_S --> CYCLEWAIT_S : interrupt, SWI
CYCLEWAIT_S --> CYCLEWAIT_S : Wait for Execute State
CYCLEWAIT_S --> SAVEENA_S : Execute State
SAVEENA_S --> DISABLEINT_S
DISABLEINT_S --> JMPADDR_S
JMPADDR_S --> JMPFETCH1_S
JMPFETCH1_S --> JMPFETCH2_S
JMPFETCH2_S --> JUMP_S
JUMP_S --> [*]
Opcode | Bits | Flag | Address #0 Register / Register |
Address #1 Immediate |
Address #2 Absolute Memory |
Address #3 Index Memory |
---|---|---|---|---|---|---|
NOOP |
00000 |
NA | NA | NA | NA | NA |
ld (Load) |
00010 |
High Bits (16-31) | ||||
st (Store) |
00100 |
NA | NA | NA | ||
jmp (Jump) |
00110 |
NA | ||||
jsr (Jump Subroutine)1
|
01000 |
NA | NA | NA | ||
rtn (Return)1
|
01010 |
NA | NA | NA | NA | |
be bne (not flag)2 bz (R2=0)bnz (R2=0, Flag=1)3
|
01100 |
Not | NA | NA | ||
bl bge (not flag)4 bn (R2=0)5
|
01110 |
Not | NA | NA | ||
bg ble (not flag)6bp (R2=0)7
|
10000 |
Not | NA | NA | ||
push 1
|
10010 |
0 | NA8 | NA8 | ||
pop 1
|
10010 |
1 | NA | NA8 | NA8 | |
wait 9
|
10101 |
0 | ||||
timer 10
|
10101 |
0 | ||||
cancel | 10101 | 1 | ||||
rio (Read IO) |
10110 |
0 | ||||
wio (Write IO) |
10110 |
1 | ||||
rsio (Read Status) |
11000 |
0 | ||||
wsio (Write Status) |
11000 |
1 | ||||
rti (Return from Interrupt)11
|
11010 |
NA | NA | NA | NA | NA |
swi (Software Interrupt)11
|
11100 |
NA | Not Tested | NA | ||
iena (Interrupt enable mask)11: 12: |
11110 |
NA | NA | |||
add |
00001 |
NA |
|
|||
sub |
00011 |
NA | ||||
and nand (Flag = 1) |
00101 |
not | ||||
or nor (Flag = 1) |
00110 |
not | ||||
xor xnor (Flag = 1) |
01011 |
not | ||||
sll (Shift Left Logical) |
01101 |
NA | ||||
srl (Shift Right Logical) |
01111 |
NA |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
---|---|---|---|---|---|---|---|---|
0 | ld r1, r2 |
jmp r1 |
jsr r1, r2 |
rtn r1 |
||||
1 | ldl r1, imm |
jmp imm |
jsr imm |
be r1, r2, imm<br />bz r1, imm |
blt r1, r2, imm<br />bn r1, imm |
|||
2 | ld r1, mem [addr] |
st r1, mem [addr] |
jmp mem [addr] |
be r1, r2, mem [addr]<br />bz r1, mem [addr] |
blt r1, r2, mem[addr] <br /> bn r1, mem[addr] |
|||
3 | ld r1, r2, mem [addr] |
st r1, r2, mem [addr] |
jmp r2, mem [addr] |
|||||
4 | ||||||||
5 | ldh r1, imm |
bne r1, r2, imm<br />bnz r1, imm |
bge r1, r2, imm<br />bl r1, r0, imm |
|||||
6 | bne r1, r2, mem [addr]<br />bnz r1, mem [addr] |
bge r1, r2, mem[addr]<br />bl r1, r0, mem[addr] |
||||||
7 | ||||||||
8 | add r1, r2 |
sub r1, r2 |
and r1, r2 |
or r1, r2 |
xor r1, r2 |
sll r1, r2 |
srl r1, r2 |
|
9 | add r1, r2, imm<br />add r1, imm |
sub r1, r2, imm<br />sub r1, imm |
and r1, r2, imm<br />and r1, imm |
or r1, r2, imm <br />or r1, imm |
xor r1, r2, imm<br />xor r1, imm |
sll r1, r2, imm<br />sll r1, imm |
srl r1, r2, imm<br />srl r1, imm |
|
a | add r1, mem[addr] |
sub r1, mem[addr] |
and r1, mem[addr] |
or r1, mem[addr] |
xor r1, mem[addr] |
sll r1, mem[addr] |
srl r1, mem[addr] |
|
b | add r1, r2, mem[addr] |
sub r1, r2, mem[addr] |
and r1, r2, mem[addr] |
or r1, r2, mem[addr] |
xor r1, r2, mem[addr] |
sll r1, r2, mem[addr] |
srl r1, r2, mem[addr] |
|
c | nand r1, r2 |
nor r1, r2 |
xnor r1, r2 |
|||||
d | nand r1, r2, imm<br />nand r1, imm |
nor r1, r2, imm<br />nor r1, imm |
xnor r1, r2, imm<br />xnor r1, imm |
|||||
e | nand r1, mem[addr] |
nor r1, mem[addr] |
xnor r1, mem[addr] |
|||||
f | nand r1, r2, mem[addr] |
nor r1, r2, mem[addr] |
xnor r1, r2, mem[addr] |
8 | 9 | a | b | c | d | e | f | |
---|---|---|---|---|---|---|---|---|
0 | push r1, r2 |
rio r1, r2 |
rsio r1, r2 |
rti |
swi r2 |
iena r1, r2 |
||
1 | bgt r1, r2, imm<br />bp r1, imm |
push r1, imm |
wait r1, imm<br />time r1, r2, imm |
roi r1, imm |
rsoi r1, imm |
swi imm |
iena r1, imm |
|
2 | bgt r1, r2, mem[addr]<br />bp r1, mem[addr] |
roi r1, mem[addr] |
swi mem[addr] |
iena r1, mem[addr] |
||||
3 | roi r1, r2, mem[addr] |
|||||||
4 | pop r1, r2 |
CANC r1 |
wio r1, r2 |
wsio r1, r2 |
||||
5 | ble r1, r2, imm<br />bg r1, r0, imm |
woi r1, imm |
wsoi r1, imm |
|||||
6 | ble r1, r2, mem[addr]<br />bg r1, r0, mem[addr] |
woi r1, mem[addr] |
||||||
7 | woi r1, r2, mem[addr] |
|||||||
8 | ||||||||
9 | ||||||||
a | ||||||||
b | ||||||||
c | ||||||||
d | ||||||||
e | ||||||||
f |
Reduction of cycles will be achieved when the instruction is preloaded (sequentially processed instruction).
Perform loads and store operations. The cycles are the maximum cycles for that instruction. The Load Immediate will fill the register with 2 separate operations (Load High and Load Low). The Load Immediate uses a Signed argument, and the Load High/Low uses unsigned.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
ld r1, r2 | Register/Register | 10 | 5 | R2 → R1 |
ldl r1, Imm | Immediate (Low) | 11 | 5 | Imm → R1[0:15] |
ldh r1, Imm | Immediate (High) | 15 | 5 | Imm → R1[16:31] |
ld r1, Imm | Immediate | 15 and 11 Performs two Operations |
10 | Imm[0:15] → R1[0:15] Imm[16:31] → R1[16:31] |
ld r1, mem[address] | Absolute | 12 | 7 | mem[address] → R1 |
ld r1, r2, mem[address] | Index | 13 | 7 | mem[address+R2] → R1 |
Store the contents of the register in memory.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
st r1, mem[address] | Absolute | 22 | 7 | R1 → mem[address] |
st r1, r2, mem[address] | Index | 23 | 7 | R1 → mem[address+R2] |
Unconditional jump to a new address. The index addressing command supports Jump Tables.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
jmp r1 | Register/Register | 30 | 5 | R1 → PC |
jmp Imm | Immediate | 31 | 5 | Imm[0:15] → PC |
jmp mem[address] | Absolute | 32 | 7 | mem[address] → PC |
jmp r2, mem[address] | Index | 33 | 7 | mem[address+R2] → PC |
The Jump to Subroutine stores the return address to the Stack which is pointed to by the first Register (Stack Pointer Register).
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
jsr r1, r2 | Register/Register | 40 | 5 | PC+1 → mem(R1) R1-1 → R1 R2 → PC |
jsr imm | Immediate | 41 | 5 | PC+1 → mem(R1), R1-1 → R1, imm → PC |
The Return reads the return address from the Stack which is pointed to by the stack pointer register.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
rtn r1 | Register/Register | 50 | 7 | R1+1→ R1, mem(R1) → PC |
Branches compare the first register with the second register. If the second register is register zero (0) then it will compare to zero (Example bz r1, aaaa would assemble to 6110 aaaa, if r1 contains 0 then it would branch).
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
be r1, r2, Imm | Immediate | 61 | 5 | if R1=R2 then Imm → PC |
be r1, r2, mem[address] | Absolute | 62 | 7 | if R1=R2 then mem(imm) → PC |
bne r1, r2, Imm | Immediate | 65 | 5 | if R1!=R2 then Imm → PC |
bne r1, r2, mem[address] | Absolute | 66 | 7 | if R1!=R2 then mem(imm) → PC |
bz r1, Imm | Immediate | 61x0 | 5 | if R1=0 then Imm → PC |
bz r1, mem[address] | Absolute | 62x0 | 7 | if R1=0 then mem(imm) → PC |
bnz r1, Imm | Immediate | 65x0 | 5 | if R1!=0 then Imm → PC |
bnz r1, mem[address] | Absolute | 66x0 | 7 | if R1!=0 then mem(imm) → PC |
blt r1, r2, Imm | Immediate | 71 | 5 | if R1<R2 then Imm → PC |
blt r1, r2, mem[address] | Absolute | 72 | 7 | if R1<R2 then mem(imm) → PC |
bge r1, r2, Imm | Immediate | 75 | 5 | if R1>=R2 then Imm → PC |
bge r1, r2, mem[address] | Absolute | 76 | 7 | if R1>=R2 then mem(imm) → PC |
bn r1, Imm | Immediate | 71x0 | 5 | if R1<0 then Imm → PC |
bn r1, mem[address] | Absolute | 72x0 | 7 | if R1<0 then mem(imm) → PC |
bl r1, r0, Imm (No specific assembly instruction) |
Immediate | 75x0 | 5 | if R1>=0 then Imm → PC |
bl r1, r0, mem[address] (No specific assembly instruction) |
Absolute | 76x0 | 7 | if R1>=0 then mem(imm) → PC |
bgt r1, r2, Imm | Immediate | 81 | 5 | if R1>R2 then Imm → PC |
bgt r1, r2, mem[address] | Absolute | 82 | 7 | if R1>R2 then mem(imm) → PC |
ble r1, r2, Imm | Immediate | 85 | 5 | if R1<=R2 then Imm → PC |
ble r1, r2, mem[address] | Absolute | 86 | 7 | if R1<=R2 then mem(imm) → PC |
bp r1, Imm | Immediate | 81x0 | 5 | if R1>0 then Imm → PC |
bp r1, mem[address] | Absolute | 82x0 | 7 | if R1>0 then mem(imm) → PC |
bg r1, r0, Imm (No specific assembly instruction) |
Immediate | 85x0 | 5 | if R1<=0 then Imm → PC |
bg r1, r0, mem[address] (No specific assembly instruction) |
Absolute | 86x0 | 7 | if R1<=0 then mem(imm) → PC |
Stack operations require a stack pointer register for R1. This is a normal register that can be loaded, stored, pushed, etc. Multiple stacks can exist using different registers. By convention, I use register 15 for stack pointer. Because the stack pointer is regular register, the register can be used to peek at the top of the stack, etc. The following instructions use the stack: jsr, rtn, push, pop, swi, and hardware interrupts.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
push r1, r2 | Register/Register | 90 | 7 | R2 → mem(R1), R1-1 → R1 |
push r1, Imm | Immediate | 91 | 7 | Imm → mem(R1), R1-1 → R1 |
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
pop r1, r2 | Register/Register | 94 | 7 | R1+1 → R1, mem(R1) → R2 |
This command received input for peripherals. The IO address is one 8 bits (byte) and the data is one word 32 bits. The Status is defined by the peripheral, the only requirement is bit 0 is a busy bit.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
rio r1, r2 | Register/Register | b0 | 7 | R2 → IOAddr, IOData → R1 |
rio r1, Imm | Immediate | b1 | 7 | Imm → IOAddr, IOData → R1 |
rio r1, mem[address] | Absolute | b2 | 8 | R2 → IOAddr, IOData → mem(imm) |
rio r1, r2, mem[address] | Index | b3 | 8 | R1 → IOAddr, IOData → mem(r2+imm) |
rsio r1, r2 | Register/Register | c0 | 7 | R2 → IOAddr, Status → R1 |
rsio r1, Imm | Immediate | c1 | 7 | Imm → IOAddr, Status → R1 |
This command output data to the peripherals. The IO address is one 8 bits (byte) and the data is one word 32 bits. The Status is defined by the peripheral, the only requirement is bit 0 is a busy bit.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
wio r1, r2 | Register/Register | b4 | 7 | R2 → IOAddr, R1 → IOData, Status → R0 |
wio r1, Imm | Immediate | b5 | 7 | Imm → IOAddr, R1 → IOData, Status → R0 |
wio r1, mem[address] | Absolute | b6 | 8 | R2 → IOAddr, mem(imm) → IOData, Status → R0 |
wio r1, r2, mem[address] | Index | b7 | 8 | R1 → IOAddr, mem(r2+imm) → IOData, Status → R0 |
wsio r1, r2 | Register/Register | c4 | 7 | R2 → IOAddr, Status → R1 |
wsio r1, Imm | Immediate | c5 | 7 | Imm → IOAddr, Status → R1 |
Performs 2-complement addition. This does not support carry.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
add r1, r2 | Register/Register | 08 | 5 | R1 + R2 → R1 |
add r1, r2, Imm | Immediate | 09 | 5 | R1 + R2 + Imm → R1 |
add r1, Imm | Immediate | 09x0 | 5 | R1 + Imm → R1 |
add r1, mem[address] | Absolute | 0a | 7 | R1 + mem(imm) → R1 |
add r1, r2, mem[address] | Index | 0b | 7 | R1 + mem(r2+imm) → R1 |
Performs a 2-complement subtraction. This does not support overflow and carry.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
sub r1, r2 | Register/Register | 18 | 5 | R1 + R2 → R1 |
sub r1, r2, Imm | Immediate | 19 | 5 | R1 + R2 + Imm → R1 |
sub r1, Imm | Immediate | 19x0 | 5 | R1 + Imm → R1 |
sub r1, mem[address] | Absolute | 1a | 7 | R1 + mem(imm) → R1 |
sub r1, r2, mem[address] | Index | 1b | 7 | R1 + mem(r2+imm) → R1 |
Performs the logical "and" or "nand" to the accumulator.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
and r1, r2 | Register/Register | 28 | 5 | R1 ∧ mem(imm) → R1 |
and r1, r2, Imm | Immediate | 29 | 5 | R1 ∧ R2 ∧ Imm → R1 |
and r1, Imm | Immediate | 29x0 | 5 | R1 ∧ Imm → R1 |
and r1, mem[address] | Absolute | 2a | 7 | R1 ∧ mem(imm) → R1 |
and r1, r2, mem[address] | Index | 2b | 7 | R1 ∧ mem(r2+imm) → R1 |
nand r1, r2 | Register/Register | 2c | 5 | R1 ⊼ mem(imm) → R1 |
nand r1, r2, Imm | Immediate | 2d | 5 | R1 ⊼ R2 ⊼ Imm → R1 |
nand r1, Imm | Immediate | 2dx0 | 5 | R1 ⊼ Imm → R1 |
nand r1, mem[address] | Absolute | 2e | 7 | R1 ⊼ mem(imm) → R1 |
nand r1, r2, mem[address] | Index | 2f | 7 | R1 ⊼ mem(r2+imm) → R1 |
Performs the logical "or" or "nor" to the accumulator.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
or r1, r2 | Register/Register | 38 | 5 | R1 ∨ mem(imm) → R1 |
or r1, r2, Imm | Immediate | 39 | 5 | R1 ∨ R2 ∨ Imm → R1 |
or r1, Imm | Immediate | 39x0 | 5 | R1 ∨ Imm → R1 |
or r1, mem[address] | Absolute | 3a | 7 | R1 ∨ mem(imm) → R1 |
or r1, r2, mem[address] | Index | 3b | 7 | R1 ∨ mem(r2+imm) → R1 |
nor r1, r2 | Register/Register | 3c | 5 | R1 ⊽ mem(imm) → R1 |
nor r1, r2, Imm | Immediate | 3d | 5 | R1 ⊽ R2 ⊽ Imm → R1 |
nor r1, Imm | Immediate | 3dx0 | 5 | R1 ⊽ Imm → R1 |
nor r1, mem[address] | Absolute | 3e | 7 | R1 ⊽ mem(imm) → R1 |
nor r1, r2, mem[address] | Index | 3f | 7 | R1 ⊽ mem(r2+imm) → R1 |
Performs the logical "xor" or "xnor" to the accumulator.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
xor r1, r2 | Register/Register | 58 | 5 | R1 ⊕ mem(imm) → R1 |
xor r1, r2, Imm | Immediate | 59 | 5 | R1 ⊕ R2 ⊕ Imm → R1 |
xor r1, Imm | Immediate | 59x0 | 5 | R1 ⊕ Imm → R1 |
xor r1, mem[address] | Absolute | 5a | 7 | R1 ⊕ mem(imm) → R1 |
xor r1, r2, mem[address] | Index | 5b | 7 | R1 ⊕ mem(r2+imm) → R1 |
xnor r1, r2 | Register/Register | 5c | 5 | R1 ⊙ mem(imm) → R1 |
xnor r1, r2, Imm | Immediate | 5d | 5 | R1 ⊙ R2 ⊙ Imm → R1 |
xnor r1, Imm | Immediate | 5dx0 | 5 | R1 ⊙ Imm → R1 |
xnor r1, mem[address] | Absolute | 5e | 7 | R1 ⊙ mem(imm) → R1 |
xnor r1, r2, mem[address] | Index | 5f | 7 | R1 ⊙ mem(r2+imm) → R1 |
Performs the shift left logical to the accumulator.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
sll r1, r2 | Register/Register | 68 | 5 | R1《 mem(imm) → R1 |
sll r1, r2, Imm | Immediate | 69 | 5 | R1《 R2《 Imm → R1 |
sll r1, Imm | Immediate | 69x0 | 5 | R1《 Imm → R1 |
sll r1, mem[address] | Absolute | 6a | 7 | R1《 mem(imm) → R1 |
sll r1, r2, mem[address] | Index | 6b | 7 | R1《 mem(r2+imm) → R1 |
Performs the shift right logical to the accumulator.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
srl r1, r2 | Register/Register | 78 | 5 | R1 》mem(imm) → R1 |
srl r1, r2, Imm | Immediate | 79 | 5 | R1 》R2 》Imm → R1 |
srl r1, Imm | Immediate | 79x0 | 5 | R1 》Imm → R1 |
srl r1, mem[address] | Absolute | 7a | 7 | R1 》mem(imm) → R1 |
srl r1, r2, mem[address] | Index | 7b | 7 | R1 》mem(r2+imm) → R1 |
The Wait instruction will accept the number of time cycles (R1 with 32-bits), and resolution (immediate 16-bits). The Timer instruction will accept the number of time cycles (R1 with 32-bits), interrupt number (R2 with lowest 5-bits), and resolution (immediate with 16-bits). If the wait and timer times is zero then the wait and timer will be set to infinite.
The 32-bit counter of a 100MHz clock will only count for 43 seconds. The Resolution field extends the time to 782 days, but the precision is maintained at 32 bits. The precision for the max time (782 days) is 0.6ms. The system contains a resolution counter and a timer counter. For each clock cycle the CPU increments the resolution counter. When the resolution counter reaches the resolution value it increments the timer counter.
resolCounter = resolCounter + 1;
if resolCounter >= resolution value then
timerCounter = timerCounter + 1;
resolCounter = 0;
if timerCounter >= timerValue then
either quit the wait or start the interrupt handler
timerCounter = 0;
end if
end if;
When the counter cycle is started an enable flag is set. When the counter is complete, the enable flag is reset.
For the sync (Wait), when the counter is going, the Wait cycle will be processed. When the counter is finished, the Wait Cycle is stopped and the start of the regular cycle starts.
For the async (timer) the counter is going the regular cycle continues. When the counter is finished the cycle is transferred to the interrupt cycle.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
wait r1, Imm | Immediate | a1x0 | 5 | R1 → Wait Timer Imm → Resolution Enable Wait Timer |
time r1, r2, Imm | Immediate | a1 | 5 | R1 → Timer R2 → Interrupt Number Imm → Resolution Enable Timer |
canc r1 | Register/Register | a4 | 5 | if R1 is Wait Reg then '0' → Disable Wait if R1 is Timer Reg then '0' → Disable Timer |
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
iena r1, r2 | Register/Register | f0 | 5 | R1 – IR Stack Pointer, R2 → Interrupts Enable Mask |
iena r1, Imm | Immediate | f1 | 5 | R1 –IR Stack Pointer, Imm → Interrupts Enable Mask(Low 16 bits) |
iena r1, mem[address] | Absolute | f2 | 7 | R1 – IR Stack Pointer, mem(address) → Interrupts Enable Mask |
The Software Interrupt just sets the Interrupt Process Flag and sets the Interrupt Number. This will initiate the interrupt process listed before.
There are 32 unique interrupts. Only 31 can be programmed interrupt 0 is for resetting the CPU. The CPU contains an interrupt enable mask (32-bit word). The CPU can only start processing one interrupt at a time. The interrupts are checked after the execute cycle and start at the next start of the instruction cycle. Interrupt 0 is the only non-maskable interrupt.
Software interrupts specify as part of the instruction the interrupt to process. The SW interrupt can start the same interrupt as a hardware interrupt. The software can reset the CPU by issuing a SW interrupt 0, this has not been tested.
Interrupt Vector:
interrupt Handler | Address |
---|---|
0 (CPU Reset) | 0 (Address of the first executable instruction after reset and Interrupt 0 (bit 0).) |
1 | 1 (Address of the interrupt handler for Interrupt 1.) |
... | ... |
31 | 31 (Address of the interrupt handler for Interrupt 31.) |
Executable Instructions | 32 |
... | ... |
Interrupt Process initiated by Hardware or Software interrupt.
- The Software Interrupt Mask is pushed onto the Interrupt Stack
- The Interrupt Mask is cleared. The Interrupt handler is responsible for updating the mask, if required.
- The Program counter is pushed on the Interrupt Stack.
- The interrupt Handler address is loaded to the Program Counter from the Interrupt Vector.
Return from Interrupt.
- The interrupt will issue an RTI instruction.
- The Program Counter will be popped from the Interrupt Stack
- The Interrupt Mask will be popped from the Interrupt Stack
- The Instruction Cycle starts over.
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
swi r1 | Register/Register | e0 | 5 | Check for Interrupt Enabled. IR Process Flag → ‘1’ R1 → Interrupt Number Perform Hardware Interrupt |
swi Imm | Immediate | e100 | 5 | Check for Interrupt Enabled. IR Process Flag → ‘1’ Imm → Interrupt Number Perform Hardware Interrupt |
swi mem[address] | Absolute | e2 | 7 | Check for Interrupt Enabled. IR Process Flag → ‘1’ mem(address) → Interrupts Enable Mask Perform Hardware Interrupt |
Assembly | Addressing | Code | Clock Cycles | Operation |
---|---|---|---|---|
rti | Register/Register | d000 | 8 | mem(reg(InterSP)+1) → PC mem(reg(InterSP))+2) → IntEna reg(InterSP)+2 → reg(InterSP) |
Cycle | Interrupt Process |
---|---|
PREFETCH | reg(InterSP) → addrB |
SAVEENA2 | IntEna → dinB reg(InterSP) → reg(InterSP) – 1 |
INTERRUPTDISABLE | ’0’ → IntEna(interNum) |
PUSHPC1 | reg(InterSP) → addrB |
PUSHPC2 | PC+1 → dinB reg(InterSP) → reg(InterSP) – 1 |
JINTERRUPT | InterNum → addrA |
WAIT1 | Wait |
WAIT2 | Wait |
JUMP | DoutA → PC |
Return from interrupt processing:
Cycle | Return Process |
---|---|
DECODES | reg(InterSP)+1 → addrB |
MEMRWAIT | reg(InterSP))+2 → addrB |
MEMR | Wait |
EXECUTE | DoutB → PC reg(InterSP)+2 → reg(InterSP) |
MEMW | DoutB → IntEna |
The Serial Device is a basic UART that runs through the Serial/Programming interface for the Arty device. This device uses the AXI UART Lite v2.0 IP provided by Vivado. The interface is AXI-Lite, the first time I used this interface, and needed additional time to understand it. It was hard to find documentation and examples of this IP. The example Vivado uses is limited and can only be read from the serial. I'm not describing the AXI-Lite protocol.
Signal | Direction | Description |
---|---|---|
CLK | IN | The System Clock |
RST | IN | Reset Signal |
UART_RXD | IN | Serial Read. |
UART_TXD | OUT | Serial Transmitted. |
TxByte | IN | Byte data to be transmitted. |
TxAvail | IN | The flag indicates that the transmitted byte is valid. |
TxStatus | OUT | Transmitted Status word. |
Interrupt | OUT | Interrupt value when the read data is available. |
RdByte | OUT | Read data byte. |
RdStatus | OUT | Read Status word |
Read/Write Status word is formatted with the following fields:
Bit(s) | Name | Read/Write/Both | Description |
---|---|---|---|
0 | Busy | Both | |
1-2 | AXI Response | Both | 0 = OKAY - Successful 1 = EXOKAY - Successful with Exclusive Access 2 = SLVERR - Unsuccessful 3 = DECERR - Decode Error |
3 | Rx FIFO Valid | Read | Indicates if the receive FIFO has data. |
4 | RX FIFO Full | Read | Indicates if the receive FIFO is full. |
5 | Tx FIFO Empty | Write | Indicates if the transmit FIFO is empty. |
6 | TS FIFO Full | Write | Indicates if the transmit FIFO is full. |
7 | Interrupt Ena | Read | Indicates that interrupts is enabled. |
8 | Overrun Error | Read | Indicates that an overrun error has occurred after the last time the status register was read. Overrun is when a new character has been received but the receive FIFO is full. The received character is ignored and not written into the receive FIFO. This bit is cleared when the status register is read. [This might not work in my implementation] |
9 | Frame Error | Read | Indicates that a frame error has occurred after the last time the status register was read. Frame error is defined as detection of a stop bit with the value 0. The receive character is ignored and not written to the receive FIFO. |
10 | Parity Error | Read | Indicates that a parity error has occurred after the last time the status register was read. If the UART is configured without any parity handling, this bit is always 0. |
Footnotes
-
R2 <> 0: R1 = R2 R1<>R2 (Flag=1) ↩
-
R2 = 0: R1 = 0 / R1 <> 0 (Flag=1) ↩
-
R2 <> 0: R1 < R2 / R1>=R2 (Flag =1) ↩
-
R2 = 0: R1 < 0 / R1 >= 0 (Flag=1) ↩
-
R2 <> 0: R1 > R2 / R1<=R2 (Flag=1) ↩
-
R2 = 0: R1 > 0 / R1 <= 0 (Flag=1) ↩
-
Memory Type 2 and 3 (might be possible with additional cycles) ↩ ↩2 ↩3 ↩4
-
R2 = 0: Wait statement ↩
-
R2<>0: Timer statement, R2 contains the interrupt handler number ↩
-
Interrupt Stack Pointer register number is saved and used for hardware and software interrupt. ↩