From 6e0e35c06818b1d4f0e40ecd393661a4da37406b Mon Sep 17 00:00:00 2001 From: mole99 Date: Sat, 13 Apr 2024 12:08:50 +0200 Subject: [PATCH] Add remaining instructions, improve sine --- src/shader_execute.sv | 20 ++++++++------ src/shader_memory.sv | 14 +++++----- src/spi_receiver.sv | 62 ++++++++++++------------------------------ src/tiny_shader_top.sv | 33 ++++++++-------------- 4 files changed, 49 insertions(+), 80 deletions(-) diff --git a/src/shader_execute.sv b/src/shader_execute.sv index 16505df..60aa3b1 100644 --- a/src/shader_execute.sv +++ b/src/shader_execute.sv @@ -118,20 +118,24 @@ module shader_execute ( skip <= !(regs[arg0] < regs[0]); end - 8'b00_1100_??: begin // TODO special RGB to set all channels same, or use high bits from operand - + 8'b00_1100_??: begin // *2 + regs[arg0] <= regs[arg0] << 1; end - 8'b00_1101_??: begin // TODO duplicate - + 8'b00_1101_??: begin // /2 + regs[arg0] <= regs[arg0] >> 1; end - 8'b00_1110_??: begin // TODO half - + 8'b00_1110_??: begin // CLEAR RA + regs[arg0] <= 6'b0; end 8'b00_1111_??: begin // SINE ARG0 <= SINE_LUT[REGS[0]] - regs[arg0] <= sine_lut[regs[0][5:2]]; // TODO + // Mirror the sine wave + if (regs[0][4] == 1'b0) begin + regs[arg0] <= sine_lut[regs[0][3:0]]; // TODO + end else begin + regs[arg0] <= sine_lut[4'd15 - regs[0][3:0]]; // TODO + end end - // Dual arg instructions 01 - Logical 8'b01_00_??_??: begin // AND ARG0 <= ARG0 & ARG1 regs[arg0] <= regs[arg0] & regs[arg1]; diff --git a/src/shader_memory.sv b/src/shader_memory.sv index 1a84117..f55ad14 100644 --- a/src/shader_memory.sv +++ b/src/shader_memory.sv @@ -21,19 +21,19 @@ module shader_memory #( always_ff @(posedge clk_i, negedge rst_ni) begin if (!rst_ni) begin `ifdef COCOTB_SIM - $readmemb("../sw/binary/test4.bit", memory); + $readmemb("../sw/binary/test7.bit", memory); `else // Load the default program memory[0] <= 8'b00_0100_00; // GETX R0 memory[1] <= 8'b00_0101_01; // GETY R1 memory[2] <= 8'b01_11_01_00; // XOR R0 R1 memory[3] <= 8'b00_0000_00; // SETRGB R0 - memory[4] <= 8'b01_11_00_00; // XOR R0 R0 - 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 + memory[4] <= 8'b01_00_00_00; // NOP + memory[5] <= 8'b01_00_00_00; // NOP + memory[6] <= 8'b01_00_00_00; // NOP + memory[7] <= 8'b01_00_00_00; // NOP + memory[8] <= 8'b01_00_00_00; // NOP + memory[9] <= 8'b01_00_00_00; // NOP `endif end else begin if (shift_i) begin diff --git a/src/spi_receiver.sv b/src/spi_receiver.sv index e4c5a04..45a5f7e 100644 --- a/src/spi_receiver.sv +++ b/src/spi_receiver.sv @@ -4,9 +4,8 @@ `default_nettype none module spi_receiver #( - parameter NUM_REGS = 4, parameter REG_SIZE = 8, - parameter [NUM_REGS*REG_SIZE-1:0] REG_DEFAULTS = '0 + parameter [REG_SIZE-1:0] REG_DEFAULT = '0 )( input logic clk_i, // clock input logic rst_ni, // reset active low @@ -22,15 +21,16 @@ module spi_receiver #( // '1' = data mode input logic mode_i, + // Output memory 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 - // Output registers - output logic [NUM_REGS*REG_SIZE-1:0] registers_o + // Output user register + output logic [REG_SIZE-1:0] user_o ); - logic [NUM_REGS*REG_SIZE-1:0] registers; + logic [REG_SIZE-1:0] user; // Synchronizer to prevent metastability @@ -76,18 +76,14 @@ module spi_receiver #( assign spi_sclk_falling = spi_sclk_delayed && !spi_sclk_sync; // State Machine - logic [7:0] spi_cmd; logic [2:0] spi_cnt; - logic spi_mode; always_ff @(posedge clk_i, negedge rst_ni) begin if (!rst_ni) begin - spi_mode <= 1'b0; spi_cnt <= 3'd0; - spi_cmd <= 8'b0; - registers <= REG_DEFAULTS; + user <= REG_DEFAULT; spi_miso_o <= 1'b0; @@ -99,52 +95,30 @@ module spi_receiver #( if (!spi_cs_sync && spi_sclk_falling) begin // Read the command - if (spi_mode == 1'b0) begin - spi_cmd <= {spi_cmd[6:0], spi_mosi_sync}; - spi_cnt <= spi_cnt + 1; - - if (spi_cnt == 7) begin - if (mode_i == 0) begin - // Read the command - spi_mode <= 1'b1; - end else begin - memory_shift_o <= 1'b1; - memory_load_o <= 1'b1; - end - end - // Write the data depending on the command - end else begin - case (spi_cmd) - 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; - if (spi_cnt == 7) begin - spi_mode <= 1'b0; + spi_cmd <= {spi_cmd[6:0], spi_mosi_sync}; + spi_cnt <= spi_cnt + 1; + + if (spi_cnt == 7) begin + if (mode_i == 0) begin + // Read the command + user <= spi_cmd[REG_SIZE-1:0]; // TODO error + end else begin + memory_shift_o <= 1'b1; + memory_load_o <= 1'b1; end end end // Echo back the previous values if (!spi_cs_sync && spi_sclk_rising) begin - if (spi_mode == 1'b1) begin - case (spi_cmd) - 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 + spi_miso_o <= spi_cmd[7]; end end end // Assignments - assign registers_o = registers; + assign user_o = user; assign memory_instr_o = spi_cmd; endmodule diff --git a/src/tiny_shader_top.sv b/src/tiny_shader_top.sv index 5d83c50..f25dbc8 100644 --- a/src/tiny_shader_top.sv +++ b/src/tiny_shader_top.sv @@ -28,7 +28,7 @@ module tiny_shader_top ( /* Tiny Shader Settings */ - localparam NUM_INSTR = 12; + localparam NUM_INSTR = 10; /* VGA 640x480 @ 60 Hz @@ -95,7 +95,7 @@ module tiny_shader_top ( .counter (counter_v) ); - logic [7:0] cur_time; + logic [8:0] cur_time; logic time_dir; always_ff @(posedge clk_i, negedge rst_ni) begin @@ -106,12 +106,12 @@ module tiny_shader_top ( if (next_frame_o) begin if (time_dir == 1'b0) begin cur_time <= cur_time + 1; - if (cur_time == 255-1) begin + if (&(cur_time+1)) begin time_dir <= 1'b1; end end else begin cur_time <= cur_time - 1; - if (cur_time == 0+1) begin + if (cur_time == 1) begin time_dir <= 1'b0; end end @@ -132,21 +132,11 @@ module tiny_shader_top ( logic memory_shift; logic memory_load; - localparam NUM_REGS = 2; - localparam REG_SIZE = 8; - - // TODO - logic [NUM_REGS*REG_SIZE-1:0] registers; - - logic [7:0] reg0, reg1; - - assign reg0 = registers[0*8 +: 8]; - assign reg1 = registers[1*8 +: 8]; + logic [5:0] user; spi_receiver #( - .NUM_REGS (NUM_REGS), - .REG_SIZE (REG_SIZE), - .REG_DEFAULTS ({NUM_REGS{8'b0}}) + .REG_SIZE (6), + .REG_DEFAULT (6'd42) ) spi_receiver_inst ( .clk_i (clk_i), .rst_ni (rst_ni), @@ -160,12 +150,13 @@ module tiny_shader_top ( // Mode signal .mode_i (mode_i), + // Output memory .memory_instr_o (memory_instr), .memory_shift_o (memory_shift), .memory_load_o (memory_load), - // Output registers - .registers_o (registers) + // Output register + .user_o (user) ); // Graphics @@ -271,8 +262,8 @@ module tiny_shader_top ( .x_pos_i (x_pos), .y_pos_i (y_pos), - .time_i (cur_time[7:2]), - .user_i (reg0[5:0]), + .time_i (cur_time[8:3]), + .user_i (user), .rgb_o (rgb_o) );