数字IC验证虚拟项目总结

之前面试的时候把项目里大致的结构和scoreboard里的代码整理了出来,这样每次面试前不用再返回去看源码,花一点时间看下这个简略版就OK了,agent中有关driver和monitor的写法的话主要还是根据spec来,只要通信协议记得,即使代码忘了大概的思路也能说出来。

AHB to APB bridge

  • 模块作用:AHB to APB bridge同步桥用来实现AHB端和APB端的数据的转换。
  • 环境组成:

env:包含了两个vip以及scb,在connect_phase中将两个agent的monitor中的port连接到scb的tlm_fifo的export中。

fuv_cov:对ahb侧的haddr、hwrite、hburst、hsize进行采样,在对地址进行采样的时候将边界地址单独列出来。

scb:定义了两个tlm_analysis_fifo以及port,再将其相连,将ahb及apb的trans分别填充到两个port中。数据的比对:AHB-PKT的地址与APB-PKT的地址、AHB-PKT的wrdata与APB-PKT的data、hwrite与APB-PKT读写信号的对比、AHB-PKT的hprot与APB-PKT的prot信号的对比、AHB-PKT的hrsp与APB-PKT的slverr的对比、AHB-PKT的hwrite信号拉高分别进行byte、Hword、word的写操作时,更新了apb侧的哪个字节通道(pstrb信号)。

  • apb_sequence:slv_rdy(约束中slverr=0,nready_num=0)
    slv_nrdy(约束中slverr=0,nready_num inside{[1:5]})
    slv_slverr(约束中slverr=1,nready_num inside{[1:5]})

  • ahb_sequence:burst(hsel == 1’b1)
    single_write32(hsel == 1’b1;htrans == ahbl_mst_pkg::NSEQ; hsize == ahbl_mst_pkg::WORD; hburst == ahbl_mst_pkg::SINGLE;hwrite == 1’b1)
    single_read32(hsel == 1’b1; htrans == ahbl_mst_pkg::NSEQ; hsize == ahbl_mst_pkg::WORD; hburst == ahbl_mst_pkg::SINGLE; hwrite == 1’b0)

  • testcase:

base_test:在test层中例化env。

single_read32:组合ahb_single_read32与apb_slv_rdy两个seq。

single_write32_slv_nrdy:组合ahb_single_write32与apb_slv_nrdy两个seq。
burst:先启动ahb_burst,然后再启动apb_slv_nrdy,再通过num_apb_seq计算启动的apb的seq的个数,当num_apb_seq大于ahb的

get_bst_beats()获得的bst_beats个数时再退出。
关于bst_beats:

在这里插入图片描述

burst_slverr:类似上个case,只不过加入了apb的slverr。

tight_transfer:两个ahb_mst和一个apb_slv进行burst操作。

  • 两个vip:

APB-agent:
trans:对addr、data、prot、strb、slverr、nready_num等信号进行注册。
monitor:把在interface上监测到的信号转换到pkt中,再写进analysis_port中。
driver:apb作为slv时,wdata与waddr是input,rdata与raddr是output。
写操作时,将wdata与waddr从interface上读出写进apb的mem中,读操作时,将rdata与raddr从mem中取出驱动到interface上。

AHB-agent:ahb作为mst,hwdata和hwaddr是output,hrdata和hraddr是input。
trans:对相应的信号做相对应的约束。
monitor:分别在data_phase和address_phase中将interface上监测到的信号转换到pkt中,再写进analysis_port中。
driver:分别在data_phase和address_phase中将pkt里的数据通过interface驱动到DUT上。

APB - UART

  • 模块作用:APB-UART模块可以实现串行数据和并行数据的转换,发送和接收逻辑分别用FIFO来存储数据,CPU可以通过APB总线访问该模块,进而间接的实现对UART串行数据的访问。
    在进行数据发送操作时,需要发送的数据通过APB总线被写入到该模块后,会暂时存储在Transmit FIFO中,发送逻辑模块会在特定的时刻从Transmit FIFO中取走数据,并添上起始位、奇偶校验位以及停止位,形成一个完整的数据帧。最后发送逻辑会将该数据帧放入到发送端口另一端的移位寄存器中,按照特定的波特率将数据串行移位,实现数据发送的功能。
    在进行数据接收操作时,串行数据通过接收端口后会进入到接收逻辑模块,该模块对数据进行格式检测后,会将其中的起始位、校验位以及停止位移除,并把剩下的数据暂时存储在Receive FIFO中,等待CPU访问。
  • 环境组成:

env:在其中例化apb_agent和uart_agent,以及virtual sequencer和scb。
将agent中monitor的port连接到scb的export。
set两个agent的sequencer的句柄。
virtual sequencer:get两个agent的sequencer的句柄。

scb:在scb的中,创建了三个不同的函数来对数据进行比较。

Compare_config():此函数在configuration register上有读取操作时调用,将来自apb_monitor的值与配置了configuration后的scoreboard进行比较,这里的配置主要指uart_config中的波特率、帧长、奇偶校验以及停止位这几个参数。
(apb_pkt.PRDATA与baud_rate_reg、frame_len_reg、parity_config_reg、stop_bits_config_reg的比对)

Compare_transmission():此函数在DUT上有传输操作时调用,将apb_driver写入到DUT上的PWDATA与uart_monitor在DUT的TX_pin上监测到的数据进行比较。
(apb_pkt.PWDATA与uart_pkt.transmitter_reg的比对)

Compare_receive():在有接受操作时,此函数被调用,将uart_driver提供给RX_pin的数据与apb_monitor从DUT接收到的PRDATA进行比较。此外该函数还比较了错误信号,因为我们有向DUT提供错误数据的机制。
(apb_pkt.PRDATA与uart_pkt.payload的比对)

run_phase():
1.if(apb_pkt_mon.PWRITE==1&&(apb_pkt_mon.PADDR == cfg.baud_config_addr || apb_pkt_mon.PADDR == cfg.frame_config_addr || apb_pkt_mon.PADDR == cfg.parity_config_addr||apb_pkt_mon.PADDR == cfg.stop_bits_config_addr))
则对scoreboard进行配置。(4个reg为在scb中配置的寄存器)

在这里插入图片描述
2.elseif(apb_pkt_mon.PWRITE== 0&&(apb_pkt_mon.PADDR== cfg.baud_config_addr||apb_pkt_mon.PADDR== cfg.frame_config_addr||apb_pkt_mon.PADDR == cfg.parity_config_addr||apb_pkt_mon.PADDR == cfg.stop_bits_config_addr))
则调用compare_config函数。
3. else if(apb_pkt_mon.PADDR==cfg.trans_data_addr)

在这里插入图片描述

4.else if(apb_pkt_mon.PADDR==cfg.receive_data_addr)

在这里插入图片描述

  • assertion(property):
    1.在setup_state中,PSELx应该是HIGH,PENABLE应该是LOW,set_up可以通过检测PSELx的上升沿来确定。
    2.access_state发生在setup_state后的一个循环之后,所以PENABLE应该在PSELx拉高的下一个周期拉高。
    3.在setup_state中,PWRITE和PADDR不应该是未知的。
    4.在setup_state中,写操作期间PWDATA的值不应该是未知的。
    5.在access_state中,PWRITE和PADDR的值不应该更改。
    6.PWDATA在整个写周期中应该保持不变。
    7.在读操作中,PRDATA的值在断言PREADY时不应该是未知的。
    8.对于多个读/写操作,PSELx不一定要去断言,但在所有事务完成之前,其仍然保持HIGH。所以我们必须检查每次PENABLE拉高时,PSELx应该在一个cycle之前断言。

  • tb:DUT和assertion的接口端口。
    Set agent的interface句柄。

  • 测试计划:
    1.通过在配置寄存器中存储特定的值来设置config。配置元素如下:波特率,帧大小,奇偶校验,停止位,可以通过使用APB接口提供的PADDR变量来访问它们的特定配置地址。
    2.首先通过运行config sequence将配置设置写入DUT,然后将一些数据写入PWDATA端口,并通过TX-pin串行(逐位)读取数据。输出应该是相同的。加载在PWDATA上的数据应该在TX-pin上串行接收。
    3.在RX引脚上逐位加载数据,然后在preready时从PRDATA端口读取数据。同样,我们可以先运行随机配置设置,然后根据相应的配置设置运行此测试。
    4.发送一个帧,其中包含损坏的停止位。DUT应响应输出PSLVERR位拉高。设置DUT为random config,然后运行此测试。
    5.发送包含损坏的奇偶校验位的帧。DUT应响应PSLVERR为高。设置DUT为random config,然后运行此测试。
    6.设置random config,随机奇偶校验错误和帧错误。使DUT处于receive模式,包括在RX引脚上逐位发送数据,然后在PREADY时从PRDATA端口读取数据。
    7.测试过程与上述随机序列相同。唯一会发生的变化是使用时钟和复位驱动器序列,时钟会有不同的周期,并会在每次transaction后进行重置。

  • APB-agent(driver、sequencer、monitor、config)

apb_config:slave_Addr、psel_Index的注册,定义AddrCalcFunc()函数。

apb_monitor:将从interface上监测到的信号驱动到trans_collected中(即apb_transaction),再在PREADY信号拉低后,将trans_collected中的数据write到item_collected_port_mon中。

apb_driver:get两个cfg的句柄。
将apb_transaction驱动到DUT上。
在这里插入图片描述

  • UART-agent(driver、sequencer、monitor、config)

uart_config:定义baudRateFunc()函数,将bRate转换为baud_rate。
from APB agent:frame_len、n_sb、parity、bRate
to UART monitor:baud_rate
对frame_len、n_sb、parity、bRate进行相应的约束。

uart_transaction:

在这里插入图片描述

uart_monitor:根据波特率只对interface上监测到的data value(payload)进行采样,忽略奇偶位和停止位,不进行采样。首先,每帧的有效载荷被临时存储在本地寄存器中,在接收到所有帧后,寄存器的值被传递给transaction,然后通过analysis_port发送到scb。

在这里插入图片描述

uart_driver:transaction level to signal level
将seq_item级的value驱动到interface上。其包含了所有的信号

在这里插入图片描述

APB - I2C

  • 模块作用:接收来自APB总线的数据,通过两组FIFO和移位寄存器,将从APB到I2C的数据进行串并转换。(类似APB-UART)进行写操作时,数据会先写到DW_APB_I2C的TX FIFO中。并且通过APB写入到DW_APB_I2C的IC_TAR寄存器的地址值,先把这个发到I2C线上,寻找对应的I2C设备。有设备回应后,再把寄存在DW_APB_I2C 内部TX FIFO的数据,通过TX shift一拍一拍的打到I2C线上,这样I2C上的SLAVE就可以收到写入的数据。
    进行读操作时,APB上先给DW_APB_I2C发过来一个地址,并且对应一个数据,但是这个数据可能不是要发送到I2C上的数据,而是要写入DW_APB_I2C内部对应的控制寄存器的值。配置完成之后,DW_APB_I2C开始把地址发送到I2C线上,寻找对应的I2C设备。设备确认传输方向后,把数据一拍一拍打到I2C线上,然后DW_APB_I2C把这个数据经过RX SHIFT和RX FIFO,以并行数据的形式打到APB线上,然后apb master就可以拿到这个数据。
  • 环境组成:
    rkv_i2c_pkg:lvc_apb_pkg 、lvc_i2c_pkg 、 ral_rkv_i2c、 rkv_i2c_configs
    rkv_i2c_master_scoreboard 、rkv_i2c_cgm 、rkv_i2c_virtual_sequencer
    rkv_i2c_env、 rkv_element_sequences 、rkv_i2c_virtual_sequences
    rkv_i2c_tests、 rkv_user_element_sequences、 rkv_i2c_user_virtual_sequences
    rkv_i2c_user_tests

rkv_i2c_env:在env中例化rkv_i2c_config、rkv_i2c_if、apb_mst、i2c_mst、i2c_slv、
scb、virtual sqr、cgm、rgm、adapter、predictor、

在build_phase中get 到rkv_i2c_config、rkv_i2c_if、rgm的句柄,并set rgm、lvc_apb_config、scb、sqr、cgm的句柄。

在connect_phase中,将apb_mst和i2c_slv的monitor中的port连接到scb中的imp和cgm的imp上,将vip中的sequencer连接到virtual sequencer上。并对寄存器模型进行集成。

在这里插入图片描述
Virtual sequencer:传递三个sequencer、rkv_i2c_config、rgm的句柄。

Config:在defines中定义中断的ID,在config中定义两个使能信号:
master_scoreboard_enable,coverage_model_enable。在do_i2c_cfg()函数中对master_cfg与slave_cfg进行配置。

Scb:定义analysis import,run_phase()有四个函数:i2c_refmod(),i2c_write_comparer(),i2c_read_comparer(),i2c_mon_interrupt()。

write_apb_master:将lvc_apb_transfer中的transaction压进apb_trans_observed。

write_i2c_slave:将lvc_i2c_slave_transaction中的transaction压进write_data_observed或read_data_observed。

i2c_refmod():当apb_trans_observed的size()大于0时,将transaction从中pop出来,并将其push进write_data_expected()或read_data_expected()中。
(write_count_expected++ read_count_expected++)

i2c_write_comparer():比对write_data
在这里插入图片描述

i2c_read_comparer():比对read_data

在这里插入图片描述
compare_transaction():比对exp与obs,如果不匹配,则mismatch_detected=1,且mismatch_count++。

i2c_mon_interrupt(): monitored aborted/exceptional interrupt asserted, and disable scoreboard.
在这里插入图片描述
I2C的sequence和testcase没写,太多了,建议记几个比较典型的就可以了,比如说常见的寄存器是怎么验的。以及element sequence,virtual sequence,test case之间是怎么样的一个关系,比如在element sequence中定义具体要测试的signal和transfer,在virtual sequence中调用和管理element sequence,在test case中对virtual sequence进行挂载以及对objection进行控制。。

  • 8
    点赞
  • 161
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
数字IC验证工程师负责验证和测试数字集成电路的设计是否符合规格和功能要求。他们使用各种工具和技术来评估电路的性能和功能,并确保其能够正确地工作。 首先,数字IC验证工程师需要理解电路的设计规格和功能要求。他们会仔细阅读电路设计文档,并与设计工程师进行讨论,以确保对设计的理解正确无误。然后,他们会制定验证计划,包括测试策略和测试计划。 接下来,数字IC验证工程师会使用仿真工具,如Verilog或VHDL,来编写测试用例并进行仿真。他们会模拟电路的行为并执行测试用例,以验证电路的性能和功能。如果发现问题或错误,他们会与设计工程师合作进行故障排除和修改。 为了提高测试覆盖率,数字IC验证工程师会使用其他工具和技术,如基于事务的验证(Transaction-based Verification)和随机测试(Random Testing)。这些方法可以生成更多的测试用例,并帮助发现潜在的设计错误。 此外,数字IC验证工程师还需要与其他团队成员密切合作,如电路设计工程师、物理设计工程师和软件开发工程师。他们会参与电路设计和物理实现的评审会议,并提供反馈和建议。他们还会与软件开发工程师合作,以确保电路可以正确地与软件进行互动。 总之,数字IC验证工程师在电路验证和测试方面扮演着重要角色。他们需要具备深入的电路知识和技术能力,以确保数字集成电路的设计正确无误,并满足相关要求。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值