From 3fd95eff641757d8efd8d0c7226e0b58fece20fd Mon Sep 17 00:00:00 2001 From: Konarak Date: Fri, 25 Apr 2025 23:01:17 +0530 Subject: [PATCH] wip optimization on SPI/LCD --- 06_IO_Devices/HACK.v | 10 +-- 06_IO_Devices/LCD.v | 141 +++++++++++++++---------------------------- 06_IO_Devices/SPI.v | 15 +++-- 3 files changed, 62 insertions(+), 104 deletions(-) diff --git a/06_IO_Devices/HACK.v b/06_IO_Devices/HACK.v index 76a586c..ace651f 100644 --- a/06_IO_Devices/HACK.v +++ b/06_IO_Devices/HACK.v @@ -134,7 +134,7 @@ module HACK( Mux16 SWITCHD(ROM_DATA, inIO6, load_sram, instruction); Register SRAM_A(clk, outM, loadIO5, inIO5); SRAM_D SRAM_D(clk, loadIO6, outM, inIO6, SRAM_DATA, SRAM_CSX, SRAM_OEX, SRAM_WEX); - //LCD LCD(clk, loadIO8, loadIO9, outM, fromLCD, LCD_DCX, LCD_CSX, LCD_SDO, LCD_SCK); + LCD LCD(clk, loadIO8, loadIO9, outM, fromLCD, LCD_DCX, LCD_CSX, LCD_SDO, LCD_SCK); Register DEBUG0(clk, outM, loadIOB, inIOB); Register DEBUG1(clk, outM, loadIOC, inIOC); @@ -150,10 +150,10 @@ module HACK( //assign SRAM_WEX=0; //assign SRAM_OEX=0; //assign SRAM_CSX=0; -assign LCD_DCX=0; -assign LCD_SDO=0; -assign LCD_SCK=0; -assign LCD_CSX=0; +// assign LCD_DCX=0; +// assign LCD_SDO=0; +// assign LCD_SCK=0; +// assign LCD_CSX=0; assign RTP_SDO=0; assign RTP_SCK=0; endmodule diff --git a/06_IO_Devices/LCD.v b/06_IO_Devices/LCD.v index cacda69..6ccc3f1 100644 --- a/06_IO_Devices/LCD.v +++ b/06_IO_Devices/LCD.v @@ -15,106 +15,65 @@ * After 32 clock cycles transmission is completed and out[15] is set to 0. */ `default_nettype none -module LCD( - input clk, //clock 25 MHz - input load, //start send command/byte over SPI - input load16, //start send data (16 bits) - input [15:0] in, //data to be send - output reg [15:0] out, //data to be send - output reg DCX, //SPI data/command not - output reg CSX, //SPI chip select not - output reg SDO, //SPI serial data out - output reg SCK //SPI serial clock + +module LCD ( + input wire clk, // 25 MHz clock + input wire load, // Start sending 8-bit command/data + input wire load16, // Start sending 16-bit data + input wire [15:0] in, // Data to be sent + output reg [15:0] out, // Status output + output reg DCX, // Data/Command select (1 = data, 0 = command) + output reg CSX, // Chip select (active low) + output reg SDO, // Serial data out (MOSI) + output reg SCK // Serial clock ); - // Put your code here: - reg [15:0] to_send; - reg [3:0] nthbit=0; - reg csx_low=0; - reg is_data=0; - reg active=0; - reg active16=0; - reg [4:0] is16; - always @(posedge clk) begin - SDO <= 0; + reg [15:0] shift_reg = 16'b0; + reg [3:0] bit_counter = 0; + reg transmitting = 0; + reg is_16bit = 0; + + initial begin + CSX <= 1; + DCX <= 0; SCK <= 0; - CSX <= (csx_low) ? 0 : 1; - DCX <= (is_data) ? 1 : 0; - out <= (load || load16 || active || active16) ? 16'h8000 : 16'h0000; + SDO <= 0; + end - if (load && ~active && ~active16) begin - if (in[8]) begin - csx_low <= 0; - CSX <= 1; - end else begin - active <= 1; - is16 <= 1; - csx_low <= 1; - CSX <= 0; - is_data <= in[9]; - DCX <= in[9]; - to_send <= in; - SDO <= in[7]; - end + always @(posedge clk) begin + // Default signal values + SCK <= 0; + SDO <= transmitting ? SDO : 0; + out <= (transmitting || load || load16) ? 16'h8000 : 16'h0000; + //CSX <= ~transmitting; + + // Handle new transmission start + if ((load || load16) && ~transmitting) begin + transmitting <= 1; + bit_counter <= (load16) ? 15 : 7; + shift_reg <= (load16) ? in : {8'b0, in[7:0]}; + is_16bit <= load16; + + DCX <= (load16) ? 1 : in[9]; // data if load16 or in[9] for load + CSX <= 0; + SDO <= (load16) ? in[15] : in[7]; // First bit to send end - else if (load16 && ~active && ~active16) begin - active16 <= 1; - is16 <= 1; - csx_low <= 1; - to_send <= in; - SDO <= in[15]; - end - else if (active) begin + + // Continue shifting out bits + else if (transmitting) begin SCK <= ~SCK; - if ( is16 == 15) begin - active <= 0; - SDO <= to_send[0]; + + if (SCK == 1) begin + // Set next bit on falling edge + SDO <= shift_reg[bit_counter - 1]; + bit_counter <= bit_counter - 1; end else begin - is16 <= is16 + 1; - SDO <= SDO; - case (is16) - 2 : SDO <= to_send[6]; - 4 : SDO <= to_send[5]; - 6 : SDO <= to_send[4]; - 8 : SDO <= to_send[3]; - 10 : SDO <= to_send[2]; - 12 : SDO <= to_send[1]; - 14 : SDO <= to_send[0]; - endcase - - end - end - else if (active16) begin - SCK <= ~SCK; - if ( is16 == 31) begin - active16 <= 0; - SDO <= to_send[0]; - end - else begin - is16 <= is16 + 1; - SDO <= SDO; - case (is16) - 2 : SDO <= to_send[14]; - 4 : SDO <= to_send[13]; - 6 : SDO <= to_send[12]; - 8 : SDO <= to_send[11]; - 10 : SDO <= to_send[10]; - 12 : SDO <= to_send[9]; - 14 : SDO <= to_send[8]; - 16 : SDO <= to_send[7]; - 18 : SDO <= to_send[6]; - 20 : SDO <= to_send[5]; - 22 : SDO <= to_send[4]; - 24 : SDO <= to_send[3]; - 26 : SDO <= to_send[2]; - 28 : SDO <= to_send[1]; - 30 : SDO <= to_send[0]; - endcase - + // Shift on rising edge + if (bit_counter == 0 && SCK == 0) begin + transmitting <= 0; + end end end end - - endmodule diff --git a/06_IO_Devices/SPI.v b/06_IO_Devices/SPI.v index aaeaf57..5f71b68 100644 --- a/06_IO_Devices/SPI.v +++ b/06_IO_Devices/SPI.v @@ -26,10 +26,10 @@ module SPI( reg [2:0] bit_index; reg [7:0] shift_out; reg [7:0] shift_in; - reg [4:0] count; + reg [3:0] count; wire is_sample_phase = (count >= 1 && count <= 15 && count[0] == 1); - wire is_shift_phase = (count >= 2 && count <= 16 && count[0] == 0); + wire is_shift_phase = (count >= 0 && count <= 14 && count[0] == 0); initial begin SDO <= 0; @@ -47,7 +47,7 @@ module SPI( if (!in[8]) begin active <= 1; - count <= 1; + count <= 0; bit_index <= 7; // byte order MSB->LSB CSX <= 0; out[15] <= 1; @@ -59,7 +59,7 @@ module SPI( else if (active==1) begin SCK <= ~SCK; - if (count == 16) begin + if (count == 15) begin SDO <= 0; out <= {8'b0, shift_in}; @@ -67,16 +67,15 @@ module SPI( end else begin count <= count + 1; - if (is_shift_phase) begin - // bit_index = bit_index - 1 - bit_index <= 7 - ((count) >> 1); + if (is_sample_phase) begin + bit_index <= bit_index - 1; out[7:0] <= {out[6:0], shift_in[bit_index]}; shift_out <= {shift_out[6:0], 1'b0}; SDO <= shift_out[6]; // next bit end - if (is_sample_phase) begin + if (is_shift_phase) begin shift_in[bit_index] <= SDI; end end