Search code examples
verilogfpgaquartus

How to wait for edges in always block?


I am trying to write something like this:

always@(posedge bus_start)
begin
    @(posedge scl) buffer[7] = sda;
    @(posedge scl) buffer[6] = sda;
    @(posedge scl) buffer[5] = sda;
    @(posedge scl) buffer[4] = sda;
    @(posedge scl) buffer[3] = sda;
    @(posedge scl) buffer[2] = sda;
    @(posedge scl) buffer[1] = sda;
    @(posedge scl) buffer[0] = sda;
end

But it is not synthesizable according to the error I got.

I may use FSM to solve this, but that could make it complicated, is there any way to make it synthesizable?


Solution

  • It looks like you're trying to capture data from an I2C interface. Here is a simple solution for capturing 8 bits of data from sda and storing that into a register called buffer.

    // starts on rising edge of scl or bus_start
    always@(posedge bus_start or posedge scl) 
    begin
        buffer[0] <= sda; // loads sda into the lowest bit of buffer
        buffer[7:1] <= buffer[6:0]; // shifts the lower 6 bits one to
                                    // the left, acting as a shift register
    end
    

    More information about I2C in verilog can be found here In addition, a basic I2C slave can be found here (you must register and login to view the source code).