`timescale 1ps / 1ps module display( input wire nreset, input wire clk, input wire [5:0] red, // input wire [5:0] green, // current pixel input wire [5:0] blue, // output wire [7:0] x, // current pixel x output wire [7:0] y, // current pixel y output wire frame, // new frame indicator output wire pixel, // new pixel indicator output wire sck, output wire cs, output wire mosi, output wire dc ); localparam STATE_INIT_WAIT = 0; localparam STATE_INIT_RESET = 1; localparam STATE_INIT_WAIT_AFTER_RESET = 2; localparam STATE_INIT_STOP_SLEEP = 3; localparam STATE_INIT_WAIT_AFTER_STOP_SLEEP = 4; localparam STATE_INIT_SET_FORMAT = 5; localparam STATE_INIT_SET_FORMAT_PARAM1 = 6; localparam STATE_INIT_WAIT_AFTER_SET_FORMAT = 7; localparam STATE_INIT_SET_COLUMN_ADDRESS_RANGE = 8; localparam STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM1 = 9; localparam STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM2 = 10; localparam STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM3 = 11; localparam STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM4 = 12; localparam STATE_INIT_SET_ROW_ADDRESS_RANGE = 13; localparam STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM1 = 14; localparam STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM2 = 15; localparam STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM3 = 16; localparam STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM4 = 17; localparam STATE_INIT_SET_ADDRESSING_MODE = 18; localparam STATE_INIT_SET_ADDRESSING_MODE_PARAM1 = 19; localparam STATE_INIT_SET_DISPLAY_INVERSION = 20; localparam STATE_INIT_SET_DISPLAY_MODE = 21; localparam STATE_INIT_WAIT_AFTER_SET_DISPLAY_MODE = 22; localparam STATE_INIT_TURN_ON_DISPLAY = 23; localparam STATE_INIT_WAIT_AFTER_TURN_ON_DISPLAY = 24; localparam STATE_SEND_DISPLAY_CONTENTS_COMMAND = 25; localparam STATE_SEND_DISPLAY_CONTENTS_RED = 26; localparam STATE_SEND_DISPLAY_CONTENTS_GREEN = 27; localparam STATE_SEND_DISPLAY_CONTENTS_BLUE = 28; wire next; logic [7:0] spi_data_r; logic send_data_r; logic dc_r; logic [20:0] wait_counter_r; logic [4:0] state; logic [7:0] x_r; logic [7:0] y_r; logic frame_r; logic pixel_r; spi spi_inst( .nreset(nreset), .clk(clk), .data(spi_data_r), .send_data(send_data_r), .sck(sck), .mosi(mosi), .next(next) ); always_ff @(posedge clk) begin if (nreset) begin send_data_r <= 0; frame_r <= 0; pixel_r <= 0; case (state) STATE_INIT_WAIT : begin wait_counter_r <= wait_counter_r - 1; if (wait_counter_r == 0) begin wait_counter_r <= 0; state <= STATE_INIT_RESET; end end STATE_INIT_RESET : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h01; if (next) begin wait_counter_r <= 150000 * 48; // 150 ms wait state <= STATE_INIT_WAIT_AFTER_RESET; end end STATE_INIT_WAIT_AFTER_RESET : begin wait_counter_r <= wait_counter_r - 1; if (wait_counter_r == 0) begin wait_counter_r <= 0; state <= STATE_INIT_STOP_SLEEP; end end STATE_INIT_STOP_SLEEP : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h11; if (next) begin wait_counter_r <= 10000 * 48; // 10 ms wait state <= STATE_INIT_WAIT_AFTER_STOP_SLEEP; end end STATE_INIT_WAIT_AFTER_STOP_SLEEP : begin wait_counter_r <= wait_counter_r - 1; if (wait_counter_r == 0) begin wait_counter_r <= 0; state <= STATE_INIT_SET_FORMAT; end end STATE_INIT_SET_FORMAT : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h3A; if (next) begin state <= STATE_INIT_SET_FORMAT_PARAM1; end end STATE_INIT_SET_FORMAT_PARAM1 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h06; if (next) begin state <= STATE_INIT_WAIT_AFTER_SET_FORMAT; wait_counter_r <= 10000 * 48; // 10ms wait end end STATE_INIT_WAIT_AFTER_SET_FORMAT : begin wait_counter_r <= wait_counter_r - 1; if (wait_counter_r == 0) begin wait_counter_r <= 0; state <= STATE_INIT_SET_COLUMN_ADDRESS_RANGE; end end STATE_INIT_SET_COLUMN_ADDRESS_RANGE : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h2A; if (next) begin state <= STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM1; end end STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM1 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h00; if (next) begin state <= STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM2; end end STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM2 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h35; if (next) begin state <= STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM3; end end STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM3 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h00; if (next) begin state <= STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM4; end end STATE_INIT_SET_COLUMN_ADDRESS_RANGE_PARAM4 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'hBB; if (next) begin state <= STATE_INIT_SET_ROW_ADDRESS_RANGE; end end STATE_INIT_SET_ROW_ADDRESS_RANGE : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h2B; if (next) begin state <= STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM1; end end STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM1 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h00; if (next) begin state <= STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM2; end end STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM2 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h28; if (next) begin state <= STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM3; end end STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM3 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h01; if (next) begin state <= STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM4; end end STATE_INIT_SET_ROW_ADDRESS_RANGE_PARAM4 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'h17; if (next) begin state <= STATE_INIT_SET_ADDRESSING_MODE; end end STATE_INIT_SET_ADDRESSING_MODE : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h36; if (next) begin state <= STATE_INIT_SET_ADDRESSING_MODE_PARAM1; end end STATE_INIT_SET_ADDRESSING_MODE_PARAM1 : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= 8'hC0; if (next) begin state <= STATE_INIT_SET_DISPLAY_INVERSION; end end STATE_INIT_SET_DISPLAY_INVERSION : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h21; if (next) begin state <= STATE_INIT_SET_DISPLAY_MODE; end end STATE_INIT_SET_DISPLAY_MODE : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h13; if (next) begin wait_counter_r <= 10000 * 48; // 10ms wait state <= STATE_INIT_WAIT_AFTER_SET_DISPLAY_MODE; end end STATE_INIT_WAIT_AFTER_SET_DISPLAY_MODE : begin wait_counter_r <= wait_counter_r - 1; if (wait_counter_r == 0) begin wait_counter_r <= 0; state <= STATE_INIT_TURN_ON_DISPLAY; end end STATE_INIT_TURN_ON_DISPLAY : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h29; if (next) begin wait_counter_r <= 10000 * 48; // 10ms wait state <= STATE_INIT_WAIT_AFTER_TURN_ON_DISPLAY; end end STATE_INIT_WAIT_AFTER_TURN_ON_DISPLAY : begin wait_counter_r <= wait_counter_r - 1; if (wait_counter_r == 0) begin wait_counter_r <= 0; state <= STATE_SEND_DISPLAY_CONTENTS_COMMAND; end end STATE_SEND_DISPLAY_CONTENTS_COMMAND : begin send_data_r <= 1; dc_r <= 0; spi_data_r <= 8'h2C; if (next) begin x_r <= 0; y_r <= 0; wait_counter_r <= 32400; // 240 * 135 state <= STATE_SEND_DISPLAY_CONTENTS_RED; end end STATE_SEND_DISPLAY_CONTENTS_RED : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= {red, 2'b00}; if (next) begin state <= STATE_SEND_DISPLAY_CONTENTS_GREEN; end end STATE_SEND_DISPLAY_CONTENTS_GREEN : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= {green, 2'b00}; if (next) begin state <= STATE_SEND_DISPLAY_CONTENTS_BLUE; end end STATE_SEND_DISPLAY_CONTENTS_BLUE : begin send_data_r <= 1; dc_r <= 1; spi_data_r <= {blue, 2'b00}; if (next) begin x_r <= x_r + 1; if (x_r == 134) begin x_r <= 0; y_r <= y_r + 1; end wait_counter_r <= wait_counter_r - 1; if (wait_counter_r == 1) begin frame_r <= 1; state <= STATE_SEND_DISPLAY_CONTENTS_COMMAND; end else begin pixel_r <= 1; state <= STATE_SEND_DISPLAY_CONTENTS_RED; end end end endcase end else begin spi_data_r <= 0; send_data_r <= 0; wait_counter_r <= 10; dc_r <= 0; state <= STATE_INIT_WAIT; x_r <= 0; y_r <= 0; frame_r <= 0; pixel_r <= 0; end end assign cs = ~send_data_r; assign dc = dc_r; assign x = x_r; assign y = y_r; assign frame = frame_r; assign pixel = pixel_r; endmodule