Skip to content

Commit

Permalink
Configurable pixel size, set to 12
Browse files Browse the repository at this point in the history
  • Loading branch information
mole99 committed Apr 13, 2024
1 parent 82e139a commit f16f31e
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/shader_execute.sv
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ module shader_execute (

// Single arg instructions
8'b00_0000_??: begin // SETRGB RGB <= ARG0[1:0]
rgb <= regs[arg0];
rgb <= regs[arg0]; // TODO nop
end
8'b00_0001_??: begin // SETR R <= ARG0[1:0]
rgb[5:4] <= regs[arg0][1:0];
Expand Down
4 changes: 3 additions & 1 deletion src/shader_memory.sv
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module shader_memory #(
input logic [7:0] instr_i,
output logic [7:0] instr_o
);
logic [7:0] memory [NUM_INSTR];
logic [7:0] memory [NUM_INSTR]; // TODO load with nop
int i;

// Initialize the memory on reset
Expand All @@ -32,6 +32,8 @@ module shader_memory #(
memory[5] <= 8'b01_11_00_00; // XOR R0 R0
memory[6] <= 8'b01_11_00_00; // XOR R0 R0
memory[7] <= 8'b01_11_00_00; // XOR R0 R0
memory[8] <= 8'b01_11_00_00; // XOR R0 R0
memory[9] <= 8'b01_11_00_00; // XOR R0 R0
`endif
end else begin
if (shift_i) begin
Expand Down
19 changes: 9 additions & 10 deletions src/spi_receiver.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ module spi_receiver #(
// '1' = data mode
input logic mode_i,

input logic [7:0] memory_instr_i, // current sprite data
output logic [7:0] memory_instr_o, // current sprite data
output logic memory_shift_o, // shift pulse
output logic memory_load_o, // shift new data into sprite
Expand Down Expand Up @@ -116,10 +115,10 @@ module spi_receiver #(
// Write the data depending on the command
end else begin
case (spi_cmd)
3'd0: registers[0*8 +: 8] <= {registers[0*8 +: 7], spi_mosi_sync};
3'd1: registers[1*8 +: 8] <= {registers[1*8 +: 7], spi_mosi_sync};
3'd2: registers[2*8 +: 8] <= {registers[2*8 +: 7], spi_mosi_sync};
3'd3: registers[3*8 +: 8] <= {registers[3*8 +: 7], spi_mosi_sync};
8'd0: registers[0*8 +: 8] <= {registers[0*8 +: 7], spi_mosi_sync};
8'd1: registers[1*8 +: 8] <= {registers[1*8 +: 7], spi_mosi_sync};
8'd2: registers[2*8 +: 8] <= {registers[2*8 +: 7], spi_mosi_sync};
8'd3: registers[3*8 +: 8] <= {registers[3*8 +: 7], spi_mosi_sync};
endcase

spi_cnt <= spi_cnt + 1;
Expand All @@ -134,18 +133,18 @@ module spi_receiver #(
if (!spi_cs_sync && spi_sclk_rising) begin
if (spi_mode == 1'b1) begin
case (spi_cmd)
3'd0: spi_miso_o <= registers[0*8 + 7];
3'd1: spi_miso_o <= registers[1*8 + 7];
3'd2: spi_miso_o <= registers[2*8 + 7];
3'd3: spi_miso_o <= registers[3*8 + 7];
8'd0: spi_miso_o <= registers[0*8 + 7];
8'd1: spi_miso_o <= registers[1*8 + 7];
8'd2: spi_miso_o <= registers[2*8 + 7];
8'd3: spi_miso_o <= registers[3*8 + 7];
endcase
end
end
end
end

// Assignments
assign registers_o = registers;

assign memory_instr_o = spi_cmd;

endmodule
161 changes: 117 additions & 44 deletions src/tiny_shader_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ module tiny_shader_top (
output logic next_frame_o
);

/*
Tiny Shader Settings
*/

localparam NUM_INSTR = 12;

/*
VGA 640x480 @ 60 Hz
clock = 25.175 MHz
Expand All @@ -44,10 +50,6 @@ module tiny_shader_top (

localparam HTOTAL = WIDTH + HFRONT + HSYNC + HBACK;
localparam VTOTAL = HEIGHT + VFRONT + VSYNC + VBACK;

// Downscaling by factor of 8, i.e. one pixel is 8x8
localparam WIDTH_SMALL = WIDTH / 8; // 80
localparam HEIGHT_SMALL = HEIGHT / 8; // 60

/*
Horizontal and Vertical Timing
Expand Down Expand Up @@ -121,27 +123,6 @@ module tiny_shader_top (
end
end

/*
Final Color Composition
*/

always_comb begin
rrggbb_o = rgb_o;

/*if (counter_v == 32) begin
rrggbb_o = 6'b001100;
end
if (counter_h == 32) begin
rrggbb_o = 6'b110000;
end*/

if (hblank || vblank) begin
rrggbb_o = '0;
end
end


/*
SPI Receiver
Expand Down Expand Up @@ -185,8 +166,7 @@ module tiny_shader_top (

// Mode signal
.mode_i (mode_i),

.memory_instr_i (instr),

.memory_instr_o (memory_instr),
.memory_shift_o (memory_shift),
.memory_load_o (memory_load),
Expand All @@ -197,30 +177,95 @@ module tiny_shader_top (

// Graphics

logic [5:0] counter_h_small;
logic [5:0] counter_v_small;

assign counter_h_small = counter_h[$clog2(HTOTAL)-2 : 3];
assign counter_v_small = counter_v[$clog2(HTOTAL)-2 : 3];

logic [7:0] instr;

logic execute_shader;
assign execute_shader = counter_h+8 >= 0 && counter_h+8 < WIDTH
logic execute_shader_x, execute_shader_y;
assign execute_shader_x = counter_h+NUM_INSTR >= 0 && counter_h+NUM_INSTR < WIDTH
&& counter_v >= 0 && counter_v < HEIGHT;

assign execute_shader_y = counter_v >= 0 && counter_v < HEIGHT;


// TODO if started, complete instruction

shader_memory shader_memory_inst (
shader_memory #(
.NUM_INSTR (NUM_INSTR)
) shader_memory_inst (
.clk_i (clk_i),
.rst_ni (rst_ni),
.shift_i (execute_shader || memory_shift),
.shift_i (execute_shader_x || x_subpos > 0 || memory_shift),
.load_i (memory_load),
.instr_i (memory_instr),
.instr_o (instr)
);

logic [5:0] x_pos;
logic [5:0] y_pos;
logic [2:0] substep;

// Count subpixel positions
logic [$clog2(NUM_INSTR) - 1:0] x_subpos;
logic [$clog2(NUM_INSTR) - 1:0] y_subpos;

always_ff @(posedge clk_i, negedge rst_ni) begin
if (!rst_ni) begin
x_subpos = '0;
y_subpos = '0;
end else begin
if (execute_shader_x || x_subpos > 0) begin
// X sub position
x_subpos <= x_subpos + 1;

if (x_subpos == NUM_INSTR-1) begin
x_subpos <= '0;
end
end

if (execute_shader_y) begin

// Y sub position
if (next_vertical_o) begin
y_subpos <= y_subpos + 1;

if (y_subpos == NUM_INSTR-1) begin
y_subpos <= '0;
end
end

end
end
end

// Count x and y positions
localparam WIDTH_SMALL = WIDTH / NUM_INSTR;
localparam HEIGHT_SMALL = HEIGHT / NUM_INSTR;

logic [$clog2(WIDTH_SMALL) - 1:0] x_pos;
logic [$clog2(HEIGHT_SMALL) - 1:0] y_pos;

always_ff @(posedge clk_i, negedge rst_ni) begin
if (!rst_ni) begin
x_pos <= '0;
y_pos <= '0;
end else begin
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
end
end


/*
Shader execution
*/

logic [5:0] rgb_o;
logic [5:0] rgb_d;
Expand All @@ -229,12 +274,40 @@ module tiny_shader_top (
.clk_i (clk_i),
.rst_ni (rst_ni),
.instr_i (instr),
.execute (execute_shader),
.execute (execute_shader_x),

.x_pos_i (counter_h_small+6'd1),// +1
.y_pos_i (counter_v_small),
.x_pos_i (x_pos),
.y_pos_i (y_pos),

.rgb_o (rgb_o)
);

// Capture output color, after shader completed
always_ff @(posedge clk_i) begin

if (x_subpos == NUM_INSTR-1) begin
rgb_d <= rgb_o;
end
end

/*
Final Color Composition
*/

always_comb begin
rrggbb_o = rgb_d;

/*if (counter_v == 32) begin
rrggbb_o = 6'b001100;
end
if (counter_h == 32) begin
rrggbb_o = 6'b110000;
end*/

if (hblank || vblank) begin
rrggbb_o = '0;
end
end

endmodule
Binary file added test/default.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 13 additions & 10 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@

from cocotbext.spi import SpiBus, SpiConfig, SpiMaster

# Tiny Shader Settings
NUM_INSTR = 12

# VGA Parameters
WIDTH = 640;
HEIGHT = 480;
WIDTH = 640
HEIGHT = 480

HFRONT = 16;
HSYNC = 96;
HBACK = 48;
HFRONT = 16
HSYNC = 96
HBACK = 48

VFRONT = 10;
VSYNC = 2;
VBACK = 33;
VFRONT = 10
VSYNC = 2
VBACK = 33

# Reset coroutine
async def reset_dut(rst_ni, duration_ns):
Expand Down Expand Up @@ -199,7 +202,7 @@ async def test_spi_shader(dut):
dut._log.info("Reset done")

# Send shader instructions
shader = [0x12, 0x00, 0xFF, 0x64, 0x42, 0x11, 0x97, 0x0F]
shader = [0x42]*NUM_INSTR
await spi_master.write(shader, burst=True)

# Verify shader was correctly written
Expand Down Expand Up @@ -269,7 +272,7 @@ async def test_spi_regs_shader_regs_random(dut):
dut.mode.value = 1 # data mode

# Send shader instructions
shader = [random.randint(0, 255) for i in range(8)]
shader = [random.randint(0, 255) for i in range(NUM_INSTR)]
await spi_master.write(shader, burst=True)

# Verify shader was correctly written
Expand Down

0 comments on commit f16f31e

Please sign in to comment.