-1

I was trying to make a simple Master in Verilog. For now it should just send a Slave adress. It seems there is a problem in my process clock == 0. Because I get the following Error Message: Error (10028): Can't resolve multiple constant drivers for net "sda_reg" at Master.v(33) I have read that there is a problem when i change a value (in this case sda_reg) at the same time, but due the fact that sda_reg get modifidied in different states I don't state the problem:

Code:

module Master
(button,clk,scl,sda);


    inout scl;
    inout sda;
    input clk;
    input button;



    reg ack_reg;
    reg[2:0] ack_counter;
    reg sda_reg;
    reg scl_reg;

    reg[7:0] i2c_adress;
    reg read_write;


    //states
    reg[1:0] state;
    parameter idle=0, start=1, send=2;

    initial begin
            ack_reg = 1'b0;
            ack_counter = 3'b0;
            sda_reg = 1'b0;
            i2c_adress = 8'b11011101;
    end


    always@(posedge clk) begin
            case(state)
                idle: begin
                    if(button) begin
                            state <= start;
                        end
                end
                start: begin
                    sda_reg <= 1'b0;
                    state <= send;
                end /*
                send: begin
                    if(ack_counter == 8 && sda) begin
                            state <= idle;
                        end
                end */

            endcase
        end

    always@(clk == 0) begin
            case(state)
                send: begin
                    //Counter for 8 bits
                    ack_counter <= ack_counter +1;
                    //Getting the Most Important bit
                    sda_reg <= i2c_adress[7];
                    //Shifting Adress for one bit 
                    i2c_adress <= i2c_adress << 1;
                end
            endcase
        end

    //Wire data to output       
    assign sda = sda_reg;
    assign scl = clk;



endmodule
Kara
  • 6,115
  • 16
  • 50
  • 57
Tobias
  • 9
  • 8
  • I tried that before. Same Error. – Tobias Nov 26 '18 at 19:46
  • You should change (drive) a variable in one `always` only. – Oldfart Nov 26 '18 at 19:56
  • Yes that would help but do'nt i have to change the i2c data line while the clk = 0 but to start it i have to change i2c data on clk = 1 ? – Tobias Nov 26 '18 at 19:57
  • Implementing I2C in Verilog this way is very, very difficult. I only have done it using oversampling (using a higher frequency clock) – Oldfart Nov 26 '18 at 19:59
  • Which tool gives you this message? At compilation? runtime? Potentially it is legal verilog and should work. You might try to create 2 versions of sda_reg and use a ternary operator i.e. `assign sda = state == send ? sda_reg_send : sda_reg_start` – Serge Nov 26 '18 at 21:29

1 Answers1

0
inout scl; // Why this bidirectional?
inout sda;

always@(clk == 0) // What does it mean?

Because sda is inout, you must use output tri-state buffer. When you read data from sda, tri-state buffer output set to high-Z (direction == 0) Example:

assign sda = (direction) ? sda_reg : 1'bZ;

Before you redesign this code, please read about bidirectinal signals.

strannyi
  • 26
  • 4