Skip to main content
Became Hot Network Question
deleted 65 characters in body; edited tags
Source Link
toolic
  • 16.4k
  • 6
  • 29
  • 221

mainFor now, I have only implemented a simple I2C protocol where only the master transmits the data. Also there is ack_bit for the I2C Address only. For state 5, i.e., data_byte its always acknowledged.

I am just starting with Verilog, and this is my first big project so, please review my code and suggest any changes.

main source code:

testbenchtestbench code:

For now i have only implemented simple I2C protocol where only master transmits the data. Also there is ack_bit for Address only. For state 5 i.e. data_byte its always acknowledged.

I am just starting with verilog and this is my first big project so, Please review my code and Suggest any changes. Also how can i take this project further, i am thinking of implementing storing data function.

main source code:

testbench code:

For now i have only implemented simple I2C protocol where only master transmits the data. Also there is ack_bit for Address only. For state 5 i.e. data_byte its always acknowledged.

I am just starting with verilog and this is my first big project so, Please review my code and Suggest any changes. Also how can i take this project further, i am thinking of implementing storing data function.

For now, I have only implemented a simple I2C protocol where only the master transmits the data. Also there is ack_bit for the I2C Address only. For state 5, i.e., data_byte its always acknowledged.

I am just starting with Verilog, and this is my first big project so, please review my code and suggest any changes.

main source code:

testbench code:

added 2310 characters in body
Source Link

module main(input reset);

wire scl,clk;
wire sda_line;
wire sda_master_enable;
master main_master(.reset(reset),.sda_line(sda_line),.scl(scl),.sda_master_enable(sda_master_enable));

slave main_slave(.sda_line(sda_line),.scl(scl),.sda_master_enable(sda_master_enable));


endmodule

////////////////////////////////////////////////////////////////////////////////////

module master(input reset, inout sda_line, output reg scl,[2:0]state_out,wire sda_master_enable);



wire clk,reset;
reg sda,sda_enable = 1;
reg [2:0]state = 3'b000;
reg [2:0] state_out;
reg sda_master_enable;
reg [6:0]addr_reg = 7'h69;   //69 = 1101001
reg [2:0]count = 3'd6;
reg rw_reg = 0;          //FOR NOW transmitting data from master;
reg [7:0] data_reg = 8'b10001010;
reg data_out;
reg addr_ack_bit = 1;
reg data_ack_bit;
reg ack_flag = 0;

reg [2:0]data_count = 3'd7;



parameter   IDLE_STATE = 3'b000,
            START_STATE = 3'b001,
            ADDR_STATE = 3'b010,
            RW_STATE = 3'b011,
            ADDR_ACK_STATE = 3'b100,
            DATA_STATE = 3'b101,
            DATA_ACK_STATE = 3'b110,
            STOP_STATE = 3'b111;
            

clock_divider master_cd(.i2c_clk(clk));



assign sda_line = (sda_enable) ? sda : 1'bz;  // Master drives SDA only when sda_enable = 1



always @(posedge clk) begin
    if(reset == 0) begin
        case(state)
            IDLE_STATE: begin
                sda<=1;scl<=1;
                state_out <= IDLE_STATE;

                state<=START_STATE;

            end
            START_STATE: begin
                sda<=0;
                state_out <= START_STATE;

                state<=ADDR_STATE;

            end
            ADDR_STATE: begin
                sda_enable = 1;
                       
                if(count == 0) begin
                    sda<=addr_reg[count];
                    state_out <= ADDR_STATE;

                    state<=RW_STATE;
                    count<=3'd6;

                end
                else begin
                    sda<=addr_reg[count];
                    count = count-1;  // DATA will work according to sysclk; 
                    // you have to configure scl accordingly to match i2c rule;
                end 
            end 
            RW_STATE: begin
                sda<=rw_reg;
                state_out <= RW_STATE;
                state<=ADDR_ACK_STATE;


                
                end
            ADDR_ACK_STATE: begin
                sda_enable = 0;  

                state_out <= ADDR_ACK_STATE;
               end 

            DATA_STATE: begin   
                sda_enable = 1;    

                if(data_count == 0) begin
                    sda<=data_reg[data_count];
                    state_out <= DATA_STATE;
                    state<=DATA_ACK_STATE;

                end
                else begin
                    sda<=data_reg[data_count];
                    data_count = data_count-1;  // DATA will work according to sysclk; 
                    // you have to configure scl accordingly to match i2c rule;
                end      
            end
            
            DATA_ACK_STATE: begin
                sda_enable = 0;
                data_ack_bit = sda_line;
                state_out <= DATA_STATE;
                              
                state <= (data_ack_bit) ? DATA_STATE : STOP_STATE;

                
            
                
            end
            
            
            STOP_STATE: begin
                sda_enable <= 1;            
                sda<= 1;
                scl<=1;
                state_out <= STOP_STATE;
          
            end
            
                   
          default: begin sda<=1;scl<=1; end        
        endcase  
    end
    
    else if(reset == 1) begin
        sda<=1;
        scl <= 1;
    end
    
    
    state_out <= state;

    
end

always @(posedge scl) begin
    if(state_out == ADDR_ACK_STATE) begin
        sda = sda_line;  // Capture it properly
        addr_ack_bit = sda;


        $display("ACK Bit Read: %b", sda);
        if(addr_ack_bit == 1) begin
            state <= ADDR_STATE;  // Retry address phase if no ACK
        end
        else if(addr_ack_bit == 0) begin
            state <= DATA_STATE;  // Proceed to data transmission
        end
    end
end





    





always @(clk) begin
    if(state == ADDR_STATE || state == RW_STATE || state == ADDR_ACK_STATE || state == DATA_STATE ||state == DATA_ACK_STATE) begin    //Starting of scl after completing starting state;
        scl <= ~clk;   
    end
    
    if(state_out == DATA_ACK_STATE) begin
        scl <= 1;
    end
end 

always @(sda_enable) begin
    sda_master_enable = sda_enable;
end




endmodule



///////////////////////////////////////////////////////////////

module slave(input scl,sda_master_enable,inout sda_line,output addr_data_out,addr_count_out,flag);

    reg sda,sda_enable = 0;  // Controls when slave drives SDA
    wire clk;
    reg flag_reg = 1'bz;
    wire flag;
    reg [7:0] addr_data =  8'b00000000;
    reg [7:0] addr_data_out;
    reg [3:0] addr_count = 4'b1010; //here from 9 to 0 10 states // we require 8 bits (7+1)  //+1 bit for starting posedge of scl from Hi-im state; 
    reg [3:0] addr_count_out;
    reg addr_flag = 0;
    
    parameter slave_addr = 8'hD2;8'hD1;
   
    
    assign sda_line = sda_enable ? sda : 1'bz; // To drive the inout net
    
    clock_divider master_cd(.i2c_clk(clk));



       
    always @(negedge clk) begin
        
    
        if(flag_reg == 1) begin

            
           
            

            if(addr_flag == 0) begin
                if(addr_count <= 9 && addr_count >= 2)  begin
                     sda = sda_line;              //no non-blocking for sda because we want it right now and here, nd not on next clock cycle
                    
                    addr_data = addr_data | (sda << addr_count-2) ; //same case with addr_data
                    addr_data_out[7:0] <= addr_data[7:0];
                    
                    addr_count <= addr_count -1;           //Some fucked up shit combining bloacking and non blocking is not advisable but for now its giving me correct result so gud!!
                    addr_count_out <= addr_count -1; 
                end
                
                
                else begin
                    addr_count <= addr_count -1;
                    addr_count_out <= addr_count -1;                          //earlier it was addr_count_out <= addr_count  ,,,,which was two step process first addt_count updates in one cycle and then addr_count_out;
    
                end
                
            end
                         
                
         

            
      
        end    
        
        
    end    
    
    always @(negedge sda_line) begin
    #1;
    
        if(scl == 1)
            flag_reg <= 1;   //Starting condition detected
         
    end
    
      
    always @(posedge sda_line) begin
    #1;
    
        if(scl == 1)
            flag_reg <= 0;        //stopping condition detected;
          
    end
    
    always @(negedge sda_master_enable) begin
    
        if(addr_flag == 0) begin
                
            if(sda_master_enable == 0) begin
                sda_enable = 1;
                if (addr_data == slave_addr) begin                         
                    sda = 1'b0;
                    addr_data <= 8'b00000000;
                    addr_data_out[7:0] <= 8'b00000000;
    
                    addr_count <= 4'b1010;
                    addr_count_out <= 4'b10;  
                    addr_flag<=1;
    
                end
                
                else begin
                    sda = 1'b1;         //NACK
                    addr_data <= 8'b00000000;
                    addr_data_out[7:0] <= 8'b00000000;
                    addr_count <= 4'b1010;
                    addr_count_out <= 4'b1010;  
                    addr_flag<=0;               //If NACK then resend data from master and re store it in slave
                    
                end          
            end
        
        end
        
        else if(addr_flag == 1) begin
                sda_enable = 1;
                sda<=1'b0;     
                      
        end
        

    end
    
    
    always @(posedge sda_master_enable) begin
        if(sda_master_enable == 1) begin
        
            sda_enable = 0;
        end
        
    end
    
    assign flag = flag_reg;       //Do notconfuse non blocking /blocking  sign to assign sign here "=" simply means they are equal so when ever the reg changes the wire changes;
    //Above is the good choice to see reg output in testbench waveform since testbench only takes wires:)
    
    





endmodule

////////////////////////////////////////////////////////////

module clock_signal (
  output reg val
);

  initial begin
    val = 0;
    forever #5 val = ~val;  // 10 nanosecond main clock ;Frequency = 100MHz gud!! 
    // BUT For standard i2c speed we want 100KHz or 10us clock
  end
endmodule


/////////////////////////////////////////////////////////////////////////////////


module clock_divider(output i2c_clk);
wire ref_clk;
wire reset;
reg i2c_clk = 1;
reg [10:0] counter = 0;

clock_signal cd_cs(.val(ref_clk));


always @(posedge ref_clk) begin

    if(counter == (500)) begin
        i2c_clk = ~ i2c_clk;
        counter = 0;
    end
    
    else begin
        counter = counter + 1;  // up counter is always efficient than down counter bcus ripple carry is gud!!
    end
    
end



endmodule


/////////////////////////////////////////
 

            RW_STATE: begin
                sda<=rw_reg;
                state_out <= RW_STATE;
                state<=ADDR_ACK_STATE;


                
                end
            ADDR_ACK_STATE: begin
                sda_enable = 0;  

                state_out <= ADDR_ACK_STATE;
               end 

            DATA_STATE: begin   
                sda_enable = 1;    

                if(data_count == 0) begin
                    sda<=data_reg[data_count];
                    state_out <= DATA_STATE;
                    state<=DATA_ACK_STATE;

                end
                else begin
                    sda<=data_reg[data_count];
                    data_count = data_count-1;  // DATA will work according to sysclk; 
                    // you have to configure scl accordingly to match i2c rule;
                end      
            end
            
            DATA_ACK_STATE: begin
                sda_enable = 0;
                data_ack_bit = sda_line;
                state_out <= DATA_STATE;
                              
                state <= (data_ack_bit) ? DATA_STATE : STOP_STATE;

                
            
                
            end
            
            
            STOP_STATE: begin
                sda_enable <= 1;            
                sda<= 1;
                scl<=1;
                state_out <= STOP_STATE;
          
            end
            
                   
          default: begin sda<=1;scl<=1; end        
        endcase  
    end
    
    else if(reset == 1) begin
        sda<=1;
        scl <= 1;
    end
    
    
    state_out <= state;

    
end

always @(posedge scl) begin
    if(state_out == ADDR_ACK_STATE) begin
        sda = sda_line;  // Capture it properly
        addr_ack_bit = sda;


        $display("ACK Bit Read: %b", sda);
        if(addr_ack_bit == 1) begin
            state <= ADDR_STATE;  // Retry address phase if no ACK
        end
        else if(addr_ack_bit == 0) begin
            state <= DATA_STATE;  // Proceed to data transmission
        end
    end
end





    





always @(clk) begin
    if(state == ADDR_STATE || state == RW_STATE || state == ADDR_ACK_STATE || state == DATA_STATE ||state == DATA_ACK_STATE) begin    //Starting of scl after completing starting state;
        scl <= ~clk;   
    end
    
    if(state_out == DATA_ACK_STATE) begin
        scl <= 1;
    end
end 

always @(sda_enable) begin
    sda_master_enable = sda_enable;
end




endmodule



///////////////////////////////////////////////////////////////

module slave(input scl,sda_master_enable,inout sda_line,output addr_data_out,addr_count_out,flag);

    reg sda,sda_enable = 0;  // Controls when slave drives SDA
    wire clk;
    reg flag_reg = 1'bz;
    wire flag;
    reg [7:0] addr_data =  8'b00000000;
    reg [7:0] addr_data_out;
    reg [3:0] addr_count = 4'b1010; //here from 9 to 0 10 states // we require 8 bits (7+1)  //+1 bit for starting posedge of scl from Hi-im state; 
    reg [3:0] addr_count_out;
    reg addr_flag = 0;
    
    parameter slave_addr = 8'hD2;
   
    
    assign sda_line = sda_enable ? sda : 1'bz; // To drive the inout net
    
    clock_divider master_cd(.i2c_clk(clk));



       
    always @(negedge clk) begin
        
    
        if(flag_reg == 1) begin

            
           
            

            if(addr_flag == 0) begin
                if(addr_count <= 9 && addr_count >= 2)  begin
                     sda = sda_line;              //no non-blocking for sda because we want it right now and here, nd not on next clock cycle
                    
                    addr_data = addr_data | (sda << addr_count-2) ; //same case with addr_data
                    addr_data_out[7:0] <= addr_data[7:0];
                    
                    addr_count <= addr_count -1;           //Some fucked up shit combining bloacking and non blocking is not advisable but for now its giving me correct result so gud!!
                    addr_count_out <= addr_count -1; 
                end
                
                
                else begin
                    addr_count <= addr_count -1;
                    addr_count_out <= addr_count -1;                          //earlier it was addr_count_out <= addr_count  ,,,,which was two step process first addt_count updates in one cycle and then addr_count_out;
    
                end
                
            end
                         
                
         

            
      
        end    
        
        
    end    
    
    always @(negedge sda_line) begin
    #1;
    
        if(scl == 1)
            flag_reg <= 1;   //Starting condition detected
         
    end
    
      
    always @(posedge sda_line) begin
    #1;
    
        if(scl == 1)
            flag_reg <= 0;        //stopping condition detected;
          
    end
    
    always @(negedge sda_master_enable) begin
    
        if(addr_flag == 0) begin
                
            if(sda_master_enable == 0) begin
                sda_enable = 1;
                if (addr_data == slave_addr) begin                         
                    sda = 1'b0;
                    addr_data <= 8'b00000000;
                    addr_data_out[7:0] <= 8'b00000000;
    
                    addr_count <= 4'b1010;
                    addr_count_out <= 4'b10;  
                    addr_flag<=1;
    
                end
                
                else begin
                    sda = 1'b1;         //NACK
                    addr_data <= 8'b00000000;
                    addr_data_out[7:0] <= 8'b00000000;
                    addr_count <= 4'b1010;
                    addr_count_out <= 4'b1010;  
                    addr_flag<=0;               //If NACK then resend data from master and re store it in slave
                    
                end          
            end
        
        end
        
        else if(addr_flag == 1) begin
                sda_enable = 1;
                sda<=1'b0;     
                      
        end
        

    end
    
    
    always @(posedge sda_master_enable) begin
        if(sda_master_enable == 1) begin
        
            sda_enable = 0;
        end
        
    end
    
    assign flag = flag_reg;       //Do notconfuse non blocking /blocking  sign to assign sign here "=" simply means they are equal so when ever the reg changes the wire changes;
    //Above is the good choice to see reg output in testbench waveform since testbench only takes wires:)
    
    





endmodule

////////////////////////////////////////////////////////////

module clock_signal (
  output reg val
);

  initial begin
    val = 0;
    forever #5 val = ~val;  // 10 nanosecond main clock ;Frequency = 100MHz gud!! 
    // BUT For standard i2c speed we want 100KHz or 10us clock
  end
endmodule


/////////////////////////////////////////////////////////////////////////////////


module clock_divider(output i2c_clk);
wire ref_clk;
wire reset;
reg i2c_clk = 1;
reg [10:0] counter = 0;

clock_signal cd_cs(.val(ref_clk));


always @(posedge ref_clk) begin

    if(counter == (500)) begin
        i2c_clk = ~ i2c_clk;
        counter = 0;
    end
    
    else begin
        counter = counter + 1;  // up counter is always efficient than down counter bcus ripple carry is gud!!
    end
    
end



endmodule


/////////////////////////////////////////

module main(input reset);

wire scl,clk;
wire sda_line;
wire sda_master_enable;
master main_master(.reset(reset),.sda_line(sda_line),.scl(scl),.sda_master_enable(sda_master_enable));

slave main_slave(.sda_line(sda_line),.scl(scl),.sda_master_enable(sda_master_enable));


endmodule

////////////////////////////////////////////////////////////////////////////////////

module master(input reset, inout sda_line, output reg scl,[2:0]state_out,wire sda_master_enable);



wire clk,reset;
reg sda,sda_enable = 1;
reg [2:0]state = 3'b000;
reg [2:0] state_out;
reg sda_master_enable;
reg [6:0]addr_reg = 7'h69;   //69 = 1101001
reg [2:0]count = 3'd6;
reg rw_reg = 0;          //FOR NOW transmitting data from master;
reg [7:0] data_reg = 8'b10001010;
reg data_out;
reg addr_ack_bit = 1;
reg data_ack_bit;
reg ack_flag = 0;

reg [2:0]data_count = 3'd7;



parameter   IDLE_STATE = 3'b000,
            START_STATE = 3'b001,
            ADDR_STATE = 3'b010,
            RW_STATE = 3'b011,
            ADDR_ACK_STATE = 3'b100,
            DATA_STATE = 3'b101,
            DATA_ACK_STATE = 3'b110,
            STOP_STATE = 3'b111;
            

clock_divider master_cd(.i2c_clk(clk));



assign sda_line = (sda_enable) ? sda : 1'bz;  // Master drives SDA only when sda_enable = 1



always @(posedge clk) begin
    if(reset == 0) begin
        case(state)
            IDLE_STATE: begin
                sda<=1;scl<=1;
                state_out <= IDLE_STATE;

                state<=START_STATE;

            end
            START_STATE: begin
                sda<=0;
                state_out <= START_STATE;

                state<=ADDR_STATE;

            end
            ADDR_STATE: begin
                sda_enable = 1;
                       
                if(count == 0) begin
                    sda<=addr_reg[count];
                    state_out <= ADDR_STATE;

                    state<=RW_STATE;
                    count<=3'd6;

                end
                else begin
                    sda<=addr_reg[count];
                    count = count-1;  // DATA will work according to sysclk; 
                    // you have to configure scl accordingly to match i2c rule;
                end 
            end 
            RW_STATE: begin
                sda<=rw_reg;
                state_out <= RW_STATE;
                state<=ADDR_ACK_STATE;


                
                end
            ADDR_ACK_STATE: begin
                sda_enable = 0;  

                state_out <= ADDR_ACK_STATE;
               end 

            DATA_STATE: begin   
                sda_enable = 1;    

                if(data_count == 0) begin
                    sda<=data_reg[data_count];
                    state_out <= DATA_STATE;
                    state<=DATA_ACK_STATE;

                end
                else begin
                    sda<=data_reg[data_count];
                    data_count = data_count-1;  // DATA will work according to sysclk; 
                    // you have to configure scl accordingly to match i2c rule;
                end      
            end
            
            DATA_ACK_STATE: begin
                sda_enable = 0;
                data_ack_bit = sda_line;
                state_out <= DATA_STATE;
                              
                state <= (data_ack_bit) ? DATA_STATE : STOP_STATE;

                
            
                
            end
            
            
            STOP_STATE: begin
                sda_enable <= 1;            
                sda<= 1;
                scl<=1;
                state_out <= STOP_STATE;
          
            end
            
                   
          default: begin sda<=1;scl<=1; end        
        endcase  
    end
    
    else if(reset == 1) begin
        sda<=1;
        scl <= 1;
    end
    
    
    state_out <= state;

    
end

always @(posedge scl) begin
    if(state_out == ADDR_ACK_STATE) begin
        sda = sda_line;  // Capture it properly
        addr_ack_bit = sda;


        $display("ACK Bit Read: %b", sda);
        if(addr_ack_bit == 1) begin
            state <= ADDR_STATE;  // Retry address phase if no ACK
        end
        else if(addr_ack_bit == 0) begin
            state <= DATA_STATE;  // Proceed to data transmission
        end
    end
end





    





always @(clk) begin
    if(state == ADDR_STATE || state == RW_STATE || state == ADDR_ACK_STATE || state == DATA_STATE ||state == DATA_ACK_STATE) begin    //Starting of scl after completing starting state;
        scl <= ~clk;   
    end
    
    if(state_out == DATA_ACK_STATE) begin
        scl <= 1;
    end
end 

always @(sda_enable) begin
    sda_master_enable = sda_enable;
end




endmodule



///////////////////////////////////////////////////////////////

module slave(input scl,sda_master_enable,inout sda_line,output addr_data_out,addr_count_out,flag);

    reg sda,sda_enable = 0;  // Controls when slave drives SDA
    wire clk;
    reg flag_reg = 1'bz;
    wire flag;
    reg [7:0] addr_data =  8'b00000000;
    reg [7:0] addr_data_out;
    reg [3:0] addr_count = 4'b1010; //here from 9 to 0 10 states // we require 8 bits (7+1)  //+1 bit for starting posedge of scl from Hi-im state; 
    reg [3:0] addr_count_out;
    reg addr_flag = 0;
    
    parameter slave_addr = 8'hD1;
   
    
    assign sda_line = sda_enable ? sda : 1'bz; // To drive the inout net
    
    clock_divider master_cd(.i2c_clk(clk));



       
    always @(negedge clk) begin
        
    
        if(flag_reg == 1) begin

            
           
            

            if(addr_flag == 0) begin
                if(addr_count <= 9 && addr_count >= 2)  begin
                     sda = sda_line;              //no non-blocking for sda because we want it right now and here, nd not on next clock cycle
                    
                    addr_data = addr_data | (sda << addr_count-2) ; //same case with addr_data
                    addr_data_out[7:0] <= addr_data[7:0];
                    
                    addr_count <= addr_count -1;           //Some fucked up shit combining bloacking and non blocking is not advisable but for now its giving me correct result so gud!!
                    addr_count_out <= addr_count -1; 
                end
                
                
                else begin
                    addr_count <= addr_count -1;
                    addr_count_out <= addr_count -1;                          //earlier it was addr_count_out <= addr_count  ,,,,which was two step process first addt_count updates in one cycle and then addr_count_out;
    
                end
                
            end
                         
                
         

            
      
        end    
        
        
    end    
    
    always @(negedge sda_line) begin
    #1;
    
        if(scl == 1)
            flag_reg <= 1;   //Starting condition detected
         
    end
    
      
    always @(posedge sda_line) begin
    #1;
    
        if(scl == 1)
            flag_reg <= 0;        //stopping condition detected;
          
    end
    
    always @(negedge sda_master_enable) begin
    
        if(addr_flag == 0) begin
                
            if(sda_master_enable == 0) begin
                sda_enable = 1;
                if (addr_data == slave_addr) begin                         
                    sda = 1'b0;
                    addr_data <= 8'b00000000;
                    addr_data_out[7:0] <= 8'b00000000;
    
                    addr_count <= 4'b1010;
                    addr_count_out <= 4'b10;  
                    addr_flag<=1;
    
                end
                
                else begin
                    sda = 1'b1;         //NACK
                    addr_data <= 8'b00000000;
                    addr_data_out[7:0] <= 8'b00000000;
                    addr_count <= 4'b1010;
                    addr_count_out <= 4'b1010;  
                    addr_flag<=0;               //If NACK then resend data from master and re store it in slave
                    
                end          
            end
        
        end
        
        else if(addr_flag == 1) begin
                sda_enable = 1;
                sda<=1'b0;     
                      
        end
        

    end
    
    
    always @(posedge sda_master_enable) begin
        if(sda_master_enable == 1) begin
        
            sda_enable = 0;
        end
        
    end
    
    assign flag = flag_reg;       //Do notconfuse non blocking /blocking  sign to assign sign here "=" simply means they are equal so when ever the reg changes the wire changes;
    //Above is the good choice to see reg output in testbench waveform since testbench only takes wires:)
    
    





endmodule

////////////////////////////////////////////////////////////

module clock_signal (
  output reg val
);

  initial begin
    val = 0;
    forever #5 val = ~val;  // 10 nanosecond main clock ;Frequency = 100MHz gud!! 
    // BUT For standard i2c speed we want 100KHz or 10us clock
  end
endmodule


/////////////////////////////////////////////////////////////////////////////////


module clock_divider(output i2c_clk);
wire ref_clk;
wire reset;
reg i2c_clk = 1;
reg [10:0] counter = 0;

clock_signal cd_cs(.val(ref_clk));


always @(posedge ref_clk) begin

    if(counter == (500)) begin
        i2c_clk = ~ i2c_clk;
        counter = 0;
    end
    
    else begin
        counter = counter + 1;  // up counter is always efficient than down counter bcus ripple carry is gud!!
    end
    
end



endmodule


/////////////////////////////////////////
 
edited title
Source Link
toolic
  • 16.4k
  • 6
  • 29
  • 221

Wrote I2C serial communication protocol for uniuniversity project, Please suggest any changes and further steps

For now i have only implemented simple i2c protocolI2C protocol where only master transmits the data. Also there is ack_bit for Address only. For state 5 i.e. data_byte its always acknowledged.

Wrote I2C protocol for uni project, Please suggest any changes and further steps

For now i have only implemented simple i2c protocol where only master transmits the data. Also there is ack_bit for Address only. For state 5 i.e. data_byte its always acknowledged.

I2C serial communication protocol for university project

For now i have only implemented simple I2C protocol where only master transmits the data. Also there is ack_bit for Address only. For state 5 i.e. data_byte its always acknowledged.

Source Link
Loading