77 lines
4.5 KiB
Plaintext
77 lines
4.5 KiB
Plaintext
|
// Test of CBZ and B instruction.
|
||
|
// Requires:
|
||
|
// CBZ, B, & ADDI instructions
|
||
|
// Expected results:
|
||
|
// X0 = 1
|
||
|
// X1 = 0 (anything else indicates an error)
|
||
|
// X2 = 0 on a single-cycle CPU, 4 on pipelined CPUs (counts delay slots executed)
|
||
|
// X3 = 1 (signifies program end was reached)
|
||
|
// X4 = 16+8+4+2+1 = 31 (bit per properly executed branch)
|
||
|
// X5 = 0 (should never get incremented, means accelerated branches not working).
|
||
|
|
||
|
//ADDI: I-type, Reg[Rd] = Reg[Rn] + {'0, Imm12}
|
||
|
//OP Imm12 Rn Rd
|
||
|
//3322222222 221111111111 00000 00000
|
||
|
//1098765432 109876543210 98765 43210
|
||
|
//1001000100 Unsigned 0..31 0..31
|
||
|
|
||
|
//B: B-type, PC = PC + SignExtend({Imm26, 2'b00})
|
||
|
//OP Imm26
|
||
|
//332222 22222211111111110000000000
|
||
|
//109876 54321098765432109876543210
|
||
|
//000101 2's Comp Imm26
|
||
|
|
||
|
//CBZ: CB-type, if (R[Rt] == 0) PC = PC + SignExtend({Imm19, 2'b00})
|
||
|
//OP Imm19 Rt
|
||
|
//33222222 2222111111111100000 00000
|
||
|
//10987654 3210987654321098765 43210
|
||
|
//10110100 2's Comp Imm19 0..31
|
||
|
|
||
|
// MAIN:
|
||
|
1001000100_000000000001_11111_00000 // ADDI X0, X31, #1 // Constant 1 register for testing
|
||
|
1001000100_000000000000_11111_00001 // ADDI X1, X31, #0 // Error register, should never be non-zero
|
||
|
1001000100_000000000000_11111_00010 // ADDI X2, X31, #0 // Delay slot counter. Value depends on delay slots.
|
||
|
1001000100_000000000000_11111_00011 // ADDI X3, X31, #0 // Flag for when we get to the final result.
|
||
|
1001000100_000000000000_11111_00100 // ADDI X4, X31, #0 // Set each bit as you do a branch correctly.
|
||
|
1001000100_000000000000_11111_00101 // ADDI X5, X31, #0 // Set if branches have >1 delay slot.
|
||
|
000101_00000000000000000000001100 // B FORWARD_B // 1st taken branch (+12*4)
|
||
|
1001000100_000000000001_00010_00010 // ADDI X2, X2, #1 // delay_slot++
|
||
|
1001000100_000000000001_00101_00101 // ADDI X5, X5, #1 // Should never reach here.
|
||
|
// ERROR: // Should never get here.
|
||
|
1001000100_000000000001_11111_00001 // ADDI X1, X31, #1 // Error = 1
|
||
|
000101_11111111111111111111111111 // B ERROR // Loop forever (-1)
|
||
|
1001000100_000000000000_11111_11111 // ADDI X31, X31, #0 // NOOP
|
||
|
// BACKWARD_B: // Target for a backwards branch
|
||
|
1001000100_000000000010_00100_00100 // ADDI X4, X4, #2 // 2nd branch succeeded
|
||
|
10110100_0000000000000010100_11111 // CBZ X31, FORWARD_CBZ // 3rd taken branch (+20)
|
||
|
1001000100_000000000001_00010_00010 // ADDI X2, X2, #1 // delay_slot++
|
||
|
1001000100_000000000001_00101_00101 // ADDI X5, X5, 1 // Should never reach here
|
||
|
000101_11111111111111111111111001 // B ERROR // Should never reach here (-7)
|
||
|
1001000100_000000000000_11111_11111 // ADDI X31, X31, 0 // NOP
|
||
|
// FORWARD_B:
|
||
|
1001000100_000000000001_00100_00100 // ADDI X4, X4, 1 // 1st branch succeeded.
|
||
|
000101_11111111111111111111111001 // B BACKWARD_B // 2nd taken branch (-7)
|
||
|
1001000100_000000000001_00010_00010 // ADDI X2, X2, 1 // delay_slot++
|
||
|
1001000100_000000000001_00101_00101 // ADDI X5, X5, 1 // Should never reach here
|
||
|
000101_11111111111111111111110011 // B ERROR // Should never reach here (-13)
|
||
|
1001000100_000000000000_11111_11111 // ADDI X31, X31, 0 // NOOP
|
||
|
// BACKWARD_CBZ:
|
||
|
1001000100_000000001000_00100_00100 // ADDI X4, X4, 8 // 4th branch succeeded.
|
||
|
10110100_0000000000000000110_00000 // CBZ X0, NOT_TAKEN // X0 != 0, so no branch (+6)
|
||
|
1001000100_000000000000_11111_11111 // ADDI X31, X31, 0 // NOOP
|
||
|
1001000100_000000010000_00100_00100 // ADDI X4, X4, 16 // Successfully didn't branch.
|
||
|
1001000100_000000000001_11111_00011 // ADDI X3, X31, 1 // Flag for finishing.
|
||
|
// HALT:
|
||
|
000101_00000000000000000000000000 // B HALT // Loop forever (0)
|
||
|
1001000100_000000000000_11111_11111 // ADDI X31, X31, 0 // NOOP
|
||
|
// NOT_TAKEN:
|
||
|
000101_11111111111111111111101010 // B ERROR // Should never reach here (-22)
|
||
|
1001000100_000000000000_11111_11111 // ADDI X31, X31, 0 // NOOP
|
||
|
// FORWARD_CBZ:
|
||
|
1001000100_000000000100_00100_00100 // ADDI X4, X4, 4 // 3rd branch succeeded.
|
||
|
10110100_1111111111111110110_11111 // CBZ X31, BACKWARD_CBZ // 4th taken branch (-10)
|
||
|
1001000100_000000000001_00010_00010 // ADDI X2, X2, 1 // delay_slot++
|
||
|
1001000100_000000000001_00101_00101 // ADDI X5, X5, 1 // Should never reach here.
|
||
|
000101_11111111111111111111100100 // B ERROR // Should never reach here (-28)
|
||
|
1001000100_000000000000_11111_11111 // ADDI X31, X31, 0 // NOOP
|