EmbDev.net

Forum: FPGA, VHDL & Verilog Build an I2C protocol using systemverilog


von Fitrahhadi S. (fitrahhadi_s)


Attached files:

Rate this post
useful
not useful
Hi.. Im newbie in FPGA(2 weeks). i've tried to build an I2C protocol 
using Sytemverilog. Well my design is based on i2c timing diagram but 
i'm not sure whether it is correct or not. However, i've already 
simulated using Modelsim and im quite happy with the result. Well the 
problem is why the result is different to simulation? FYI: Im using 
Quartus software (Altera based) and the FPGA board is De0-nano from 
Terasic. I'm glad if anyone give me a respond to my problem. Thankyou.

This is my coding.


//i2c as Master
module i2cprotocol (inout SDA, output logic SCL, output logic [7:0]DATA, 
input clk);

logic SDA_Utopia ;
logic [4:0] num;
assign SDA = SDA_Utopia;

always
begin
 i2c_start();
 i2c_write(8'hA0);
 i2c_write(8'h00);
 i2c_write(8'hA1);
 i2c_stop();
end

task i2c_start();
@(posedge clk);
SDA_Utopia <= 1'b1;
SCL<= 1'b1;
@(posedge clk);
SDA_Utopia <= 1'b0;
SCL <= 1'b1;
@(posedge clk);
SDA_Utopia <= 1'b0;
SCL <= 1'b0;
endtask


task i2c_stop();
@(posedge clk);
SDA_Utopia <= 1'b0;
SCL <= 1'b1;
@(posedge clk);
SDA_Utopia <= 1'b1;
SCL <= 1'b1;
endtask

task i2c_write(input logic [7:0] data); //data 8-bit
for(num=0;num<=8;num++)       //7 bit-Address
begin
@(posedge clk or negedge clk);
  if (num == 8)
    begin
    SDA_Utopia <= 1'b0; //1-bit ACK
   SCL <= 1'b0;
    end
    else
    begin
    SDA_Utopia <= data[7-num];
    SCL <= 1'b0;
    end

    @(posedge clk or negedge clk);
    SCL <= 1'b1;
    @(posedge clk or negedge clk);
    SCL <= 1'b0;

  end
  num = 0;
endtask

task i2c_read(output logic [7:0] data_out, input logic ACKNACK);
  for(num=0;num<=8;num++)       //7 bit-Address
  begin
  @(posedge clk or negedge clk);
     if (num == 8)
        begin
        SDA_Utopia <= ACKNACK; //1-bit ACK
        SCL <= 1'b0;
        end
        else
        begin
        data_out[7-num ]<=SDA;
        SCL <= 1'b0;
        end

    @(posedge clk or negedge clk);
    SCL <= 1'b1;
    @(posedge clk or negedge clk);
    SCL <= 1'b0;
  end
   num = 0;
endtask



endmodule




Subchan

von Lattice User (Guest)


Rate this post
useful
not useful
In standard Verilog your code will only work for simulation, as you use 
sequenziell contructs, (task, @() outside always). Hardware is parallel 
and there is no such thing like a sequenziell loop or waiting on the 
next clockedge with @(). In other words you need to implement a state 
machine.

Disclaimer: I can't speak for Systemverilog and also not for Quartus, 
but i think my answer applies anyway.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
> but i think my answer applies anyway.
I agree totally.

I do not know SystemVerilog or even Verilog, but I know hardware and 
VHDL in depth. What I see here is C with a Verilog syntax. Whats 
completely wrong is the way of thinking, the mindset:
You are thinking sequential "C" (Line 5 happens after line 4...),
not parallel "hardware" (all of it happens always all the time...).

At this point it does not make any sense to give you any further 
hints...
Next step for you is to learn "hardware": do the "hello world!" of 
hardware (a blinking LED, a chasing light)!

von durga (Guest)


Rate this post
useful
not useful
where is the address and acknowledgement handling mechanism

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.