blob: 0118067b56019dabb581fdd7c9c7579189349164 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
import i2c_agent_pkg::*;
interface i2c_if;
logic clk_i;
logic rst_ni;
// standard i2c interface pins
logic scl_i;
logic scl_o;
logic sda_i;
logic sda_o;
// debug signal
bus_status_e bus_status;
int num_rd_trans;
int num_wr_trans;
clocking drv_rx_cb @(posedge clk_i);
input rst_ni;
input sda_i;
input scl_i;
endclocking: drv_rx_cb
modport drv_rx_mp(clocking drv_rx_cb);
clocking drv_tx_cb @(posedge clk_i);
output sda_o;
output scl_o;
endclocking: drv_tx_cb
modport drv_tx_mp(clocking drv_tx_cb);
clocking mon_rx_cb @(negedge clk_i);
input rst_ni;
input sda_i;
input scl_i;
endclocking: mon_rx_cb
modport mon_rx_mp(clocking mon_rx_cb);
clocking mon_tx_cb @(negedge clk_i);
output sda_o;
output scl_o;
endclocking: mon_tx_cb
modport mon_tx_mp(clocking mon_tx_cb);
//---------------------------------
// common tasks
//---------------------------------
task automatic wait_for_idle();
wait(rst_ni == 1'b1);
wait(scl_i == 1'b1);
wait(scl_i == 1'b1 && sda_i == 1'b1);
// much less than standard value (4.7us) defined by i2c spec and less than timeout
#1us;
wait(scl_i == 1'b1 && sda_i == 1'b1);
#10ps;
endtask : wait_for_idle
task automatic wait_for_dly(int dly);
repeat (dly) @(posedge clk_i);
endtask : wait_for_dly
task automatic wait_for_start_from_host(int thd_sta);
wait(scl_i == 1'b1 && sda_i == 1'b1);
wait(sda_i == 1'b0);
wait_for_dly(thd_sta);
wait(scl_i == 1'b0);
bus_status = HostSendStart;
endtask: wait_for_start_from_host
task automatic wait_for_repstart_from_host(int tsu_sta);
wait(scl_i == 1'b0 && sda_i == 1'b1);
wait(scl_i == 1'b1);
wait_for_dly(tsu_sta);
wait(sda_i == 1'b1);
bus_status = HostSendRestart;
endtask: wait_for_repstart_from_host
task automatic wait_for_start_repstart_from_host(int thd_sta, int tsu_sta);
fork
begin : isolation_fork_start_or_restart
fork
begin
wait_for_start_from_host(thd_sta);
end
begin
wait_for_repstart_from_host(tsu_sta);
end
join_any
disable fork;
end : isolation_fork_start_or_restart
join
endtask : wait_for_start_repstart_from_host
task automatic wait_for_stop_from_host(int tsu_sto);
wait(scl_i == 1'b0 && scl_i == 1'b0)
wait(scl_i == 1'b1);
wait_for_dly(tsu_sto);
wait(scl_i == 1'b1);
bus_status = HostSendStop;
endtask: wait_for_stop_from_host
task automatic wait_for_stop_or_restart_from_host(int tsu_sta, int tsu_sto);
fork
begin : isolation_fork_stop_or_restart
fork
begin
wait_for_stop_from_host(tsu_sto);
end
begin
wait_for_repstart_from_host(tsu_sta);
end
join_any
disable fork;
end : isolation_fork_stop_or_restart
join
endtask: wait_for_stop_or_restart_from_host
task automatic wait_for_bus_free(int delay_ns);
wait(scl_o == 1'b1 && sda_o == 1'b1)
#(delay_ns * 1ns) bus_status = BusFree;
endtask : wait_for_bus_free
task automatic wait_for_ack_from_host(int tvd_ack);
wait(scl_i == 1'b0 && scl_i == 1'b1)
wait_for_dly(tvd_ack);
wait(scl_i == 1'b0);
bus_status = HostSendAck;
endtask: wait_for_ack_from_host
task automatic wait_for_nack_from_host(int tvd_ack);
wait(scl_i == 1'b0 && scl_i == 1'b1)
wait_for_dly(tvd_ack);
wait(scl_i == 1'b0);
bus_status = HostSendNoAck;
endtask: wait_for_nack_from_host
task automatic wait_for_ack_by_device(int tvd_ack);
wait(scl_o == 1'b0 && sda_o == 1'b1)
wait_for_dly(tvd_ack);
wait(sda_o == 1'b0);
bus_status = TargetSendAck;
endtask: wait_for_ack_by_device
task automatic send_ack_by_device(int tvd_ack);
scl_o = 1'b0;
sda_o = 1'b1;
wait_for_dly(tvd_ack);
sda_o = 1'b0;
bus_status = TargetSendAck;
endtask: send_ack_by_device
endinterface : i2c_if