module i2c_slave (input CLK, input RESET, input SCL, inout SDA, output IS_TRANSMISSION, output IS_READ, output IS_ACK, output WR, //output ACK_MASTER_CTRL, output [7:0] RECEIVED_BYTE, input [7:0] BYTE_TO_TRANSMIT, output [(MAX_I2C_TRANSACTION_EXP2-1):0] COUNTER); // ALL OPERATIONS WITH MEMORY ARE IN POSEDGE CLK, IN NEGEDGE - ONLY SCL AND SDA LATCH // COUNTER = 0 - ADRESS RECEIVED, COUNTER >=1 - DATA TRANSMISSION // RECEIVED BYTES MUST READ WHEN WR POSEDGE, ADRESS NOT READING ###AND BYTE COUNTER >=1 (BYTE COUNTER = 0 - ADRESS) // BYTES TO TRANSMIT MUST WRITE WHEN WR POSEDGE, BYTE COUNTER CAN BE ZERO // (FIRST BYTE TRANSMITTED AFTER ADRESS). // LAST BYTE HAS NO WR ####BUT LAST BYTE NOT TRANSMITTED (DECAUSE MASTER STOPS TRANSMIT) parameter I2C_ADRESS = 7'h34; parameter MAX_I2C_TRANSACTION_EXP2 = 8; // !!! - FOR LIMIT BYTES TO TX/RX (WITH ADRESS) reg /*SDA_IN,*/ SDA_DIR, SDA_OUT; wire SDA_IN; initial begin SDA_OUT = 0; end /*reg*/wire SCLD, SDAD; reg SCL_LAST, SDA_LAST; reg i2c_state_machine; reg i2c_start_latency; // GETS LATENCY (ONE CLK) TO IS_TRANSMISSION WIRE // NEEDS WHEN START REPEAT OCCURS // WITHOUT THIS THERE ARE NO SIGNALS TO CALL ABOUT END OF PACKET BEFORE START REPEAT initial begin SCL_LAST = 1; SDA_LAST = 1; i2c_state_machine = 0; end reg is_read; reg [3:0] i2c_bit_counter; reg [7:0] received_byte; reg [7:0] byte_to_transmit; reg [(MAX_I2C_TRANSACTION_EXP2-1):0] byte_counter; //reg is_for_me; reg is_ack; reg wr;//reg ack_master_ctrl; // FILTER reg SCLF, SDAF; reg [3:0] scl_cnt, sda_cnt; simple_filter FLT_SCL (CLK, RESET, SCLF, SCLD); simple_filter FLT_SDA (CLK, RESET, SDAF, SDAD); always@(negedge CLK) begin SCLF <= SCL; SDAF <= SDA_IN; end always@(posedge CLK or negedge RESET) begin if (RESET == 0) i2c_state_machine <= 0; else begin /* if (scl_cnt != 0) begin scl_cnt = scl_cnt - 1; if (scl_cnt == 0) begin if (SCLD != SCLF) SCLD = SCLF; end end else begin if (SCLD != SCLF) scl_cnt = 3'd7; end if (sda_cnt != 0) begin sda_cnt = sda_cnt - 1; if (sda_cnt == 0) begin if (SDAD != SDAF) SDAD = SDAF; end end else begin if (SDAD != SDAF) sda_cnt = 3'd7; end*/ // END OF FILTER //SDA_IN = SDA; // FOR IVERILOG if ((SDAD == 0) && (SDA_LAST == 1) && (SCLD == 1)) begin i2c_state_machine = 1; i2c_start_latency = 0; i2c_bit_counter = 4'd8; byte_counter = 9'd0; //is_for_me = 1; // RESETS TO ZERO WHEN ADRESS CHECKING SDA_DIR = 0; is_ack = 0; //ack_master_ctrl = 1; wr = 0; end else if ((i2c_state_machine == 1) && (i2c_start_latency == 0)) begin i2c_start_latency = 1; is_read = 0; end if ((SDAD == 1) && (SDA_LAST == 0) && (SCLD == 1)) begin i2c_state_machine = 0; SDA_DIR = 0; wr = 0; end if (i2c_state_machine/* && is_for_me*/) begin if (!is_read) begin if (i2c_bit_counter > 0) begin if ((SCL_LAST == 0) && (SCLD == 1)) begin received_byte[i2c_bit_counter-1] = SDAD; i2c_bit_counter = i2c_bit_counter - 1; end end else begin if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 0)) begin if (byte_counter == 0) begin if (received_byte[7:1] != I2C_ADRESS) i2c_state_machine = 0; //is_for_me = 0; is_read = received_byte[0]; end else begin // EMIT SIGNAL OF BYTE RECEIVING end if (byte_counter != ((1< 1)) wr = 1; else if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 1)) begin is_ack = 0; SDA_DIR = 0; i2c_bit_counter = 4'd8; wr = 0; end end end else begin // IS_READ if (i2c_bit_counter > 0) begin if ((SCL_LAST == 1) && (SCLD == 0)) begin wr = 0; SDA_DIR = (BYTE_TO_TRANSMIT[i2c_bit_counter-1] ^ 1) /*& is_for_me & ack_master_ctrl*/; i2c_bit_counter = i2c_bit_counter - 1; is_ack = 0; end end else begin if ((SCL_LAST == 1) && (SCLD == 0) && (is_ack == 0)) begin SDA_DIR = 0; is_ack = 1; end else if ((SCL_LAST == 0) && (SCLD == 1) && (is_ack == 1)) begin i2c_bit_counter = 8; i2c_state_machine = (SDAD ^ 1) | SDA_DIR; //ack_master_ctrl = SDAD+1; // MAYBE TRANSMIT BYTE REPEAT wr = (SDAD ^ 1) | SDA_DIR; if (byte_counter != ((1<