I2C验证的上拉电路逻辑问题

本文详细介绍了在验证I2C协议时如何在Verilog中模拟上拉电阻和线与逻辑。通过使用三态门、wire类型的信号以及tri1类型来实现总线的弱驱动和上拉功能。在RTL设计中,针对master和slave端的不同逻辑进行了阐述,同时在测试环境中,通过控制信号确保在无数据输出时释放总线,从而有效地模拟了I2C的低有效驱动特性。
摘要由CSDN通过智能技术生成

最近在做I2C的验证,在模拟上拉电阻逻辑时遇到了一些问题,记录本文希望做一个经验总结。

I2C是一种双向二线同步串行总线,拥有一条串行数据线(SDA)和串行时钟线(SCL),支持多主多从,包含冲突检测和仲裁功能,连接到I2C总线上的每个设备都有一个唯一的地址。I2C支持多主多从的能力源于上拉和线与逻辑。SDA和SCL线都是双向电路,空闲时被上拉电阻连到高电平。设备通过漏极开路或集电极开路连接到总线以实现线与逻辑,此时只要任一设备输出低电平,总线即为低电平。因此I2C总线是一个低有效驱动逻辑,它的高电平可以理解为弱信号,而低电平是强信号。

在RTL设计i2c slave端逻辑时,不考虑从机控制scl线的功能(I2C可支持),数据线会有sdi和sdo两条输入/输出信号和sdo_oen控制信号,并通过三态门连接到SDA总线(IO Pad),确保仅可输出0和z态(不可输出1)。在搭建验证环境(master模型)时,其实有两种方式,一种方式是和slave端一样,将输入和输出分成两条线,同样通过pad连接到SDA总线上,并对SDA信号做上拉(pullup)处理。但我在最初设计master interface时仅采用了一条sda信号,需要采用如下方式解决。首先,在interface模块定义wire类型的sda_out信号,用于连接DUT的SDA pad口,由于logic类型只能有一个驱动,因此多驱动总线需声明为wire类型。采用三元运算符对sda_out做驱动,然后将其上拉,在interface里用pullup()会报错,需采用weak或pull强度模型实现上拉(verilog默认强度为strong0和strong1,注意强度模型和wand、trireg等关键字都是不可综合的,仅用于仿真)。

// cci_master_interface.sv
logic   sda;        // for driver&monitor
wire    sda_out;

assign  sda_out = sda === 1'b0 ? 1'b0 : 1'bz;
assign  (weak0, weak1) sda_out = 1'b1;  // pullup, weak drive when sda_out is 1

或者,也可以直接将sda_out声明为tri1类型,无驱动源时其逻辑值为1(默认强度级别为pull)。

tri1    sda_out;

在tb例化DUT时,采用如下方式连接。DUT的sda pad口直接assign为sda_out,同时用三元运算符也对sda_out驱动,在从机无输出时驱动z以释放总线。

// cci_slv_tb.sv
assign  sda = m_cci_mst_if.sda_out; 
assign  m_cci_mst_if.sda_out = `CCI_TOP.sdo_oen === 1'b0 ? 1'b0 : 1'bz;

同样,由于在验证环境的master driver内只有一条sda信号,因此需要在无数据输出时(如read data阶段),需要驱动1以释放总线。

// cci_master_driver.sv
vif.sda <= 1'b1;    // release 

这样就基本上模拟了I2C的上拉和线与逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小破同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值