diff --git a/README.md b/README.md index 1c44853..4eb3aa0 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,104 @@ ![](../../workflows/gds/badge.svg) ![](../../workflows/docs/badge.svg) ![](../../workflows/test/badge.svg) -# Tiny Tapeout Verilog Project Template +# Tiny Shader -- [Read the documentation for project](docs/info.md) +Modern GPUs use fragment shaders to -## What is Tiny Tapeout? -TinyTapeout is an educational project that aims to make it easier and cheaper than ever to get your digital designs manufactured on a real chip. -To learn more and get started, visit https://tinytapeout.com. +Meaning for each pixel a small program is executed to determine the final color. -## Verilog Projects +## Examples -1. Add your Verilog files to the `src` folder. -2. Edit the [info.yaml](info.yaml) and update information about your project, paying special attention to the `source_files` and `top_module` properties. If you are upgrading an existing Tiny Tapeout project, check out our [online info.yaml migration tool](https://tinytapeout.github.io/tt-yaml-upgrade-tool/). -3. Edit [docs/info.md](docs/info.md) and add a description of your project. -4. Optionally, add a testbench to the `test` folder. See [test/README.md](test/README.md) for more information. +|Image|Shader| +|-|-| +|![default.png](images/default.png)|
GETX R0
GETY R1
XOR R0 R1
SETRGB R0
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
| +|![test4.png](images/test4.png)|| -The GitHub action will automatically build the ASIC files using [OpenLane](https://www.zerotoasiccourse.com/terminology/openlane/). +## Architecture -## Enable GitHub actions to build the results page +Tiny Shader has four (mostly) general purpose registers, REG0 to REG4. REG0 is special in a way as it is the target or destination register for some instructions. All registers are 6 bit wide. -- [Enabling GitHub Pages](https://tinytapeout.com/faq/#my-github-action-is-failing-on-the-pages-part) +### Input -## Resources +The shader has four sources to get input from: -- [FAQ](https://tinytapeout.com/faq/) -- [Digital design lessons](https://tinytapeout.com/digital_design/) -- [Learn how semiconductors work](https://tinytapeout.com/siliwiz/) -- [Join the community](https://tinytapeout.com/discord) -- [Build your design locally](https://docs.google.com/document/d/1aUUZ1jthRpg4QURIIyzlOaPWlmQzr-jBn3wZipVUPt4) +- `X` - X position of the current pixel +- `Y` - Y position of the current pixel +- `TIME` - Increases with the frame number. +- `USER` - Value that can be set via the SPI interface. -## What next? +### Output -- [Submit your design to the next shuttle](https://app.tinytapeout.com/). -- Edit [this README](README.md) and explain your design, how it works, and how to test it. -- Share your project on your social network of choice: - - LinkedIn [#tinytapeout](https://www.linkedin.com/search/results/content/?keywords=%23tinytapeout) [@TinyTapeout](https://www.linkedin.com/company/100708654/) - - Mastodon [#tinytapeout](https://chaos.social/tags/tinytapeout) [@matthewvenn](https://chaos.social/@matthewvenn) - - X (formerly Twitter) [#tinytapeout](https://twitter.com/hashtag/tinytapeout) [@matthewvenn](https://twitter.com/matthewvenn) +The goal of the shader is to determine the final output color: + +- `RGB` - The output color for the current pixel. Channel R, G and B can be set individually. + +### Sine Look Up Table + +TODO + + +## Instructions + +The following instructions are supported by Tiny Shader. A program consists of 12 (TODO) instructions and is executed for each pixel individually. The actual resolution is therefore less than the VGA resolution. + +### Output +|Instruction|Operation|Description| +|-----------|---------|-----------| +|SETRGB REGA|RGB <= REG|Set the output color to the value of the specified register.| +|SETR REGA|R <= REG[1:0]|Set the red channel of the output color to the lower two bits of the specified register.| +|SETG REGA|G <= REG[1:0]|Set the green channel of the output color to the lower two bits of the specified register.| +|SETB REGA|B <= REG[1:0]|Set the blue channel of the output color to the lower two bits of the specified register.| +### Input +|Instruction|Operation|Description| +|-----------|---------|-----------| +|GETX REGA|REG <= X|Set the specified register to the x position of the current pixel.| +|GETY REGA|REG <= Y|Set the specified register to the y position of the current pixel.| +|GETTIME REGA|REG <= TIME|Set the specified register to the current time value, increases with each frame.| +|GETUSER REGA|REG <= USER|Set the specified register to the user value, can be set via the SPI interface.| +### Branches +|Instruction|Operation|Description| +|-----------|---------|-----------| +|IFEQ REGA|TAKE <= REG == REG0|Execute the next instruction if REG equals REG0.| +|IFNE REGA|TAKE <= REG != REG0|Execute the next instruction if REG does not equal REG0.| +|IFGE REGA|TAKE <= REG >= REG0|Execute the next instruction if REG is greater then or equal REG0.| +|IFLT REGA|TAKE <= REG < REG0|Execute the next instruction if REG is less than REG0.| +### TODO +|Instruction|Operation|Description| +|-----------|---------|-----------| +|TODO0 REGA|TODO|TODO.| +|TODO1 REGA|TODO|TODO.| +|TODO2 REGA|TODO|TODO.| +### Special +|Instruction|Operation|Description| +|-----------|---------|-----------| +|SINE REGA|REG <= SINE[REG0[5:2]]|Get the sine value for REG0 and write into REG.| +### Boolean +|Instruction|Operation|Description| +|-----------|---------|-----------| +|AND REGA, REGB|REGA <= REGA & REGB|Boolean AND of REGA and REGB, result written into REGA.| +|OR REGA, REGB|REGA <= REGA | REGB|Boolean OR of REGA and REGB, result written into REGA.| +|NOT REGA, REGB|REGA <= ~REGB|Boolean NOT of REGB, result written into REGA.| +|XOR REGA, REGB|REGA <= REGA ^ REGB|Boolean XOR of REGA and REGB, result written into REGA.| +### Move +|Instruction|Operation|Description| +|-----------|---------|-----------| +|MOV REGA, REGB|REGA <= REGB|Move value of REGB into REGA.| +### Arithmetic +|Instruction|Operation|Description| +|-----------|---------|-----------| +|ADD REGA, REGB|REGA <= REGA + REGB|Add REGA and REGB, result written into REGA.| +### Shift +|Instruction|Operation|Description| +|-----------|---------|-----------| +|SHIFTL REGA, REGB|REGA <= REGA << REGB|Shift REGA with REGB to the left, result written into REGA.| +|SHIFTR REGA, REGB|REGA <= REGA >> REGB|Shift REGA with REGB to the right, result written into REGA.| +### Load +|Instruction|Operation|Description| +|-----------|---------|-----------| +|LDI IMMEDIATE|REGA <= IMMEDIATE|Load an immediate value into REGA.| + +## Tiny Tapeout + +This project was designed for [Tiny Tapeout](https://tinytapeout.com). diff --git a/src/shader_execute.sv b/src/shader_execute.sv index 1b7ea1a..58c449a 100644 --- a/src/shader_execute.sv +++ b/src/shader_execute.sv @@ -9,8 +9,11 @@ module shader_execute ( input logic [7:0] instr_i, input logic execute, - input logic [5:0] x_pos_i, - input logic [5:0] y_pos_i, + input logic [5:0] x_pos_i, + input logic [5:0] y_pos_i, + + input logic [5:0] time_i, + input logic [5:0] user_i, output logic [5:0] rgb_o ); @@ -40,8 +43,7 @@ module shader_execute ( logic [5:0] sine_lut [16]; logic [5:0] rgb; - logic [5:0] cur_time; - logic [5:0] user; + logic skip; always_ff @(posedge clk_i) begin @@ -69,8 +71,6 @@ module shader_execute ( rgb <= 6'b000000; - cur_time <= 5; - user <= 42; skip <= 1'b0; end else begin @@ -102,10 +102,10 @@ module shader_execute ( regs[arg0] <= y_pos_i; end 8'b00_0110_??: begin // GETTIME ARG0 <= TIME - regs[arg0] <= cur_time; + regs[arg0] <= time_i; end 8'b00_0111_??: begin // GETUSER ARG0 <= USER - regs[arg0] <= user; + regs[arg0] <= user_i; end 8'b00_1000_??: begin // IF ARG0 == REGS[0] diff --git a/src/tiny_shader_top.sv b/src/tiny_shader_top.sv index 08f1106..80841ca 100644 --- a/src/tiny_shader_top.sv +++ b/src/tiny_shader_top.sv @@ -137,18 +137,16 @@ module tiny_shader_top ( logic memory_shift; logic memory_load; - localparam NUM_REGS = 4; + localparam NUM_REGS = 2; localparam REG_SIZE = 8; // TODO logic [NUM_REGS*REG_SIZE-1:0] registers; - logic [7:0] reg0, reg1, reg2, reg3; + logic [7:0] reg0, reg1; assign reg0 = registers[0*8 +: 8]; assign reg1 = registers[1*8 +: 8]; - assign reg2 = registers[2*8 +: 8]; - assign reg3 = registers[3*8 +: 8]; spi_receiver #( .NUM_REGS (NUM_REGS), @@ -247,15 +245,15 @@ module tiny_shader_top ( if (x_subpos == NUM_INSTR-1) begin x_pos <= x_pos + 1; end - + if (next_vertical_o) begin x_pos <= '0; - + if (y_subpos == NUM_INSTR-1) begin y_pos <= y_pos + 1; end end - + if (next_frame_o) begin y_pos <= '0; end @@ -279,6 +277,9 @@ module tiny_shader_top ( .x_pos_i (x_pos), .y_pos_i (y_pos), + .time_i (reg0), // TODO use time + .user_i (reg1), + .rgb_o (rgb_o) );