Skip to content

Commit

Permalink
docs(tt_um_dvxf_dj8): update project documentation #541
Browse files Browse the repository at this point in the history
* docs(tt_um_dvxf_dj8): Update info.md

* docs(tt_um_dvxf_dj8): added bytebeat.png
  • Loading branch information
dvxf authored Nov 5, 2024
1 parent e3087ab commit fcfd8ed
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 14 deletions.
Binary file added projects/tt_um_dvxf_dj8/docs/bytebeat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
133 changes: 119 additions & 14 deletions projects/tt_um_dvxf_dj8/docs/info.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ You can also include images in this folder and reference them in the markdown. E

# How it works

DJ8 is a 8-bit CPU, originally developped for XCS10XL featuring:
DJ8 is a 8-bit CPU implemented in VHDL, originally developped for XCS10XL featuring:
* 8 x 8-bit register file
* 3-4 cycles per instruction
* 15-bit address bus
* 8-bit data bus
* Built-in 256-bytes demo ROM with 2 demos

Sample assembly code could be found in [test bench](../test/test.py) and [demo ROM](../src/top.hdl).

Other implementations:

- [TT07 DJ8 8-bit CPU w/ DAC - Verilog, Mixed-signal, 8-bit DAC](https://github.com/dvxf/tt07-dj8v-dac)
- [TTIHP0P2 DJ8 8-bit CPU - Verilog](https://github.com/dvxf/ttiph0p2-dj8v)

## Memory Map

Expand All @@ -29,8 +37,110 @@ DJ8 is a 8-bit CPU, originally developped for XCS10XL featuring:
| 0x2000 | 0x3fff | External RAM (32 bytes)
| 0x4000 | 0x5fff | External Flash ROM (16KB)

## Registers

There are 8 general purposes 8-bit registers (A,B,C,D,E,F,G,H), two flag registers (CF, ZF), and 16-bit PC.

For memory addressing, 16-bit combined registers EF and GH are used.

At reset time, PC is set to 0x4000. All other registers are set to 0x80.

## Instruction Set
For future compatibility, please set the don't care bits (`?`) to `0`.

### ALU reg, imm8: Immediate ALU operation

| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 1 | A | A | A | D | D | D | I | I | I | I | I | I | I | I |

- A : ALU operation
- `000`: ADD: reg = reg + imm8
- `001`: ADC: reg = reg + imm8 + CF
- `010`: SUBC: reg = reg - (imm8 + CF)
- `011`: MOVR: reg = reg
- `100`: XOR: reg = reg ^ imm8
- `101`: OR: reg = reg | imm8
- `110`: AND: reg = reg & imm8
- `111`: MOVI: reg = imm8
- D : register
- I : imm8

### ALU dest, src, A {,shift}: ALU operation with src register & register A

| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 0 | A | A | A | D | D | D | S | S | S | ? | F | F | 0 | 0 |

- A : ALU operation
- `000`: ADD: dest = src + A
- `001`: ADC: dest = src + A + CF
- `010`: SUBC: dest = src - (A + CF)
- `011`: MOVR: dest = src
- `100`: XOR: dest = src ^ A
- `101`: OR: dest = src | A
- `110`: AND: dest = src & A
- `111`: MOVI: dest = A
- D : dest register
- S : src register
- F : final shift operation
- `00`: No shift
- `01`: Shift right logical (shr)
- `10`: Shift right arithmetic (sar)

### ALU dest, [mem], A {,shift}: ALU operation with memory & register A

| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 0 | A | A | A | D | D | D | ? | ? | ? | M | F | F | 1 | 0 |

- A : ALU operation
- `000`: ADD: dest = [mem] + A
- `001`: ADC: dest = [mem] + A + CF
- `010`: SUBC: dest = [mem] - (A + CF)
- `011`: MOVR: dest = [mem]
- `100`: XOR: dest = [mem] ^ A
- `101`: OR: dest = [mem] | A
- `110`: AND: dest = [mem] & A
- `111`: MOVI: dest = A
- D : dest register
- M: memory mode
- `0`: [GH]
- `1`: [EF]
- F : final shift operation
- `00`: No shift
- `01`: Shift right logical (shr)
- `10`: Shift right arithmetic (sar)

### MOVR [mem], reg: Store content of register in memory
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | 0 | 0 | 1 | 1 | D | D | D | ? | ? | ? | M | ? | ? | 0 | 1 |

- D: register
- M: memory mode
- `0`: [GH]
- `1`: [EF]

### Jxx imm12: Conditional or unconditional jump to absolute address
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 0 | 0 | J | J | I | I | I | I | I | I | I | I | I | I | I | I |

- J: jmpcode
- `01`: Jump if zero (JZ)
- `10`: Jump if not zero (JNZ)
- `11`: Unconditional jump (JMP)
- I: imm12
- PC = (PC & 0xe000) | (imm12 << 1)

### JMP GH: Unconditional jump to address GH
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 0 | 1 | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |

## Pinout
Due to TT06 IO constraints, pins are shared between *Address bus LSB* and *Data bus OUT*. It means that during memory write instructions, the address space is only 64 bytes.
Due to TT06 IO constraints, pins are shared between *Address bus LSB* and *Data bus OUT*. It means that during memory write instructions, the address space is only 128 bytes.

| Pins | Standard mode | During memory write execute+writeback cycles
|--|--|--|
Expand All @@ -39,17 +149,10 @@ Due to TT06 IO constraints, pins are shared between *Address bus LSB* and *Data
| uo[6..0] | Address bus MSB (14..8) | Address bus MSB (14..8)
| uo[7] | Write Enable | Write Enable

You can connect a 8KB parallel Flash ROM + 32b SRAM without
external logic and use uo[6] for RAM OE# and uo[5] for Flash ROM OE#.
You can connect a 8KB parallel Flash ROM + 32b SRAM without external logic and use uo[6] for RAM OE# and uo[5] for Flash ROM OE#.

To get a bidirectional data bus (needed for SRAM), uio bus must be connected to ui bus with resistors. To be tested!

## Reset

At reset time, PC is set to 0x4000.

All other registers are set to 0x80.

# How to test

An internal test ROM with two demos is included for easy testing. Just select the corresponding DIP switches at reset time to start the demo (technically, a ***jmp GH*** instruction will be seen on the data bus thanks to the DIP switches values, with GH=0x8080 at reset).
Expand All @@ -67,16 +170,18 @@ No external hardware needed. This demo shows a rotating indicator on the 7-segme
|--|--|--|--|--|--|--|--|
| 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 |

Modem handshakes sound like music to your hears? It's your lucky day! Become a DJ thanks to 256 lo-fi glitchy settings.
![](bytebeat.png)

Connect a speaker to uo[4] or use [Tiny Tapeout Simon Says PMOD](https://github.com/urish/tt-simon-pmod).
Modem handshakes sound like music to your hears? It's your lucky day! Become a bit-crunching DJ thanks to 256 lo-fi glitchy settings.

Connect a speaker to uo[4] or use [Tiny Tapeout Simon Says PMOD](https://github.com/urish/tt-simon-pmod). Play with the DIP switches to change the loop settings.

It is highly recommended to add a simple low-pass RC filter on the speaker line to filter out the buzzing 8kHz carrier. Ideal cut-off frequency between 3kHz and 8kHz, TBD.

Set SW1 and/or SW2 at reset time to adjust speed in case the design doesn't run at 14MHz.

# External hardware

* No external hardware needed for demos
* No external hardware for Demo 1
* Speaker for Demo 2
* Otherwise: Parallel Flash ROM + optional SRAM

0 comments on commit fcfd8ed

Please sign in to comment.