Skip to content

Commit

Permalink
feat: update project tt_um_28add11_QOAdecode from 28add11/tt07_qoa_de…
Browse files Browse the repository at this point in the history
…code

Commit: 593ae752357e232fbc652ca066c163b3c4014d69
Workflow: https://github.com/28add11/tt07_qoa_decode/actions/runs/9328400253
  • Loading branch information
TinyTapeoutBot authored and urish committed Jun 1, 2024
1 parent 9efc374 commit 8aa6109
Show file tree
Hide file tree
Showing 9 changed files with 11,579 additions and 12,034 deletions.
4 changes: 2 additions & 2 deletions projects/tt_um_28add11_QOAdecode/commit_id.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"app": "Tiny Tapeout tt07 11b2d371",
"repo": "https://github.com/28add11/tt07_qoa_decode",
"commit": "fb54f127c521d3be21030f070f5ee0641fc13689",
"workflow_url": "https://github.com/28add11/tt07_qoa_decode/actions/runs/9308561102",
"commit": "593ae752357e232fbc652ca066c163b3c4014d69",
"workflow_url": "https://github.com/28add11/tt07_qoa_decode/actions/runs/9328400253",
"sort_id": 1716848861892,
"openlane_version": "OpenLane2 2.0.7",
"pdk_version": "open_pdks bdc9412b3e468c102d01b7cf6337be06ec6e9c9a"
Expand Down
Binary file added projects/tt_um_28add11_QOAdecode/docs/decoder.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 16 additions & 3 deletions projects/tt_um_28add11_QOAdecode/docs/info.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,25 @@ You can also include images in this folder and reference them in the markdown. E

## How it works

This chip decoded the QOA audio format, which is designed to be a simple, portable format for 16 bit PCM audio data. The specification is one page, and is availible at [qoaformat.org](https://qoaformat.org/). The chip communicates through an SPI slave mode 0 interface to a controller chip, which handles the file interface and all adjecent functions. The chip only handles decoding samples into their 16 bit uncompressed versions.
This chip is for decoding the QOA audio format, which is designed to be a simple, fast format for 16 bit PCM audio data. The specification is one page, and is availible at [qoaformat.org](https://qoaformat.org/). The chip communicates through an SPI slave mode 0 interface to a controller chip, which handles the file interface and all adjecent functions. The chip only handles decoding samples into their 16 bit uncompressed versions.

### Block diagram

![A diagram showing the internal structure of the chip](28add11_QOAdecode_whole.jpg)

The chip itself consists of two main parts, an SPI interface for communication, and the decoder itself. The decoder contains a parser for the SPI data, the LMS predictor/updater at the heart of the QOA format, and the history/weights for the LMS predictor.
For die area savings, we use a sequential multiplier in the LMS predictor, and save on the expensive dequantizing computations by using a precalculated table in the [reference code on Github](https://github.com/phoboslab/qoa). This ROM also takes half the size of that in the original code, because half of the values are just their negative counterpart so we just flip the sign.
For die area savings, we use a sequential multiplier in the LMS predictor, and save on the expensive dequantizing computations by using a precalculated table from the [reference code on Github](https://github.com/phoboslab/qoa). We save space further by only saving half the values, since every odd index is just the negative counterpart of the previous value, and we can just flip the sign.

### The decoder itself

The decoder has three main parts, registers for the LMS history and weights, a parser for handling SPI data, and the QOA decoder in the parser.

![A block diagram of the decoder itself, showing the components and how they are linked](decoder.jpg)

First off, whenever `data_rdy` is pulsed, the main state machine in the parser decodes `spi_in` into either a hist/weights fill instruction, a sample decode instruction, or a sample send instruction.
- If the instruction is a hist/weights fill, it takes the next 2 bytes (i.e. 2 `data_rdy` pulses) and puts them into the history or weights registers specified by the index in the instruction.
- If the instruction is a sample send request, the parser will set the `spi_out` register to the upper bit of sample, wait for it to transmit (8 SPI clock cycles, so a `data_rdy` pulse), then set it to the low byte and finish the transmission.
- Finally, if it is a sample decode instruction, it will iteratively multiply the history and weights values using a sequential multiplier, adding them to an accumulator. It then uses combinational logic and the ROM to calculate the final sample. This is then used to update history, weights, and is sent if a sample send request is recived.

## How to test

Expand All @@ -41,8 +52,10 @@ After sending the sample, wait 40 chip clock cycles, then request the sample wit
Once you send that instruction, the next two bytes sent by the chip will be the decoded sample, MSB first.
While you are reciving the sample, you can send any data, but it will be ignored. The chip will send unknown data when the instruction is not used.

On the testbench, it can calculate one sample every 5680ns, SPI transfer included, at a clock speed of 50MHz and an SPI frequency of 8MHz, which should be achivable on hardware. This can likely be improved by using a custom/different approach to SPI, since my test bench leaves relatively long periods of inactivity. The current speed results in a max of 176,056 samples per second, more than enough for real time audio streaming.

Eventually I will get arould to writing code for the interface on [my Github](https://github.com/28add11), please look back there for updates.

## External hardware

Since this is a co-processor for the QOA format, a seperate microcontroller is required to interface with it. Since I am used to the RP2040, I will likely provide firmware for it on my Github in the future. Because this is also an audio decoder, you will need some space to put the actual audio file, so a PC to convert/store audio data for testing is also reccomended.
Since this is a co-processor for the QOA format, a seperate microcontroller is required to interface with it. Since I am used to the RP2040 and it is included on the Tiny Tapeout PCB, I will likely provide software for it on my Github in the future. I plan to take a streaming approach with this software, so a PC supporting USB will also be needed to send, store, and convert the files.
4 changes: 2 additions & 2 deletions projects/tt_um_28add11_QOAdecode/info.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Tiny Tapeout project information
project:
title: "QOA_Decoder" # Project title
title: "QOA Decoder" # Project title
author: "Nicholas West" # Your name
discord: "28add11" # Your discord username, for communication and automatically assigning you a Tapeout role (optional)
description: "A decoder for the QOA audio format." # One line description of what your project does
language: "Verilog" # other examples include SystemVerilog, Amaranth, VHDL, etc
clock_hz: 0 # Clock frequency in Hz (or 0 if not applicable)
clock_hz: 30303030 # Clock frequency in Hz (or 0 if not applicable)

# How many tiles your design occupies? A single tile is about 167x108 uM.
tiles: "1x2" # Valid values: 1x1, 1x2, 2x2, 3x2, 4x2, 6x2 or 8x2
Expand Down
Loading

0 comments on commit 8aa6109

Please sign in to comment.