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 (BECAUSE 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_adress; reg is_ack; reg wr; // 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@(posedge CLK) begin SCLF = SCL; SDAF = SDA_IN; end always@(negedge CLK/* or negedge RESET*/) begin if (RESET == 0) i2c_state_machine = 0; else begin //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; is_adress = 1;//byte_counter = 9'd0; SDA_DIR = 0; is_ack = 0; wr = 0; is_read = 0; end else if ((i2c_state_machine == 1) && (i2c_start_latency == 0)) begin i2c_start_latency = 1; 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 (is_adress == 1) begin if (received_byte[7:1] != I2C_ADRESS) i2c_state_machine = 0; //is_for_me = 0; is_read = received_byte[0]; //is_adress = 0; end //else begin // EMIT SIGNAL OF BYTE RECEIVING //end //if (byte_counter != ((1< 1)) if (is_adress == 1) is_adress = 0; else wr = 1; end 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<