【真实场景面试问题-2】
1 介绍一下低功耗设计手段–clock gating 和 clock domain;
芯片的低功耗设计尤其是在关注能耗的场景:移动设备、物联网和嵌入式系统;时钟门控(Clock Gating)和时钟域(Clock Domain)是两种常用的低功耗设计手段。
1.1 时钟门控–clock gating
时钟门控是通过在不活跃的时钟周期内关闭时钟信号来减少动态功耗的技术。动态功耗主要由时钟树的切换活动引起,因此通过减少不必要的时钟切换,可以显著降低功耗。以下是基于寄存器的时钟门控和基于锁存器的时钟门控;
1.2 多时钟域–clock domain
时钟域是指在设计中使用多个不同的时钟信号来驱动不同的模块或子系统,实现更精细的功耗管理和性能优化。
1.3 基于多电压域
动态电压频率技术,是一种通过将不同电路模块的工作电压及工作频率降低到恰好满足系统最低要求,来实时降低系统中不同电路模块功耗的方法。
1.4 多阈值库
如果想要MOS管导通,低阈值的cell需要的导通电压更低,所以相比高阈值的cell,它导通的更快,与此同时,它的漏电也越多;
1.5 RTL设计
RTL设计时的指导思想:
2 在UVM的验证框架中,base_test中基本会做哪些?
bast_test是每个子test都会extend的class,因此首先base_test的重要性不言而喻:
2.1 组件环境和配置
class内申明和build_phase下例化:
- 比如创建和配置验证环境env(包括:agent/scoreboard/refer_model)等;
- 配置或传递参数:配置组件内各种参数; 通过env.agent.xx.xx等的方式最方便;
2.2 复用task或者function
对于通用的task或者function放在base_test下,方便直接复用;
2.3 main_phase和final_phase
- main_phase: 因为是sub-test启动时都会首先执行base-test的main_phase,因此可在base-test执行比如复位、初始化寄存器配置等;
- final_phase: 设置测试结果error等输出FAIL/SUCC等,报告错误和警告信息,提供详细的错误日志;
典型的UVM验证环境下的base_test:
class base_test extends uvm_test;
// 注册到工厂
`uvm_component_utils(base_test)
// 环境句柄
env my_env;
// 构造函数
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
// 构建阶段
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 创建环境
my_env = env::type_id::create("my_env", this);
// 绑定虚拟接口
if (!uvm_config_db#(virtual my_if)::get(this, "", "vif", my_env.vif)) begin
`uvm_fatal("NOVIF", {"virtual interface must be set for: ", get_full_name(), ".vif"})
end
// 读取配置文件
uvm_config_db#(int)::set(this, "*", "clk_period", 10);
endfunction
// 运行阶段
virtual task run_phase(uvm_phase phase);
super.run_phase(phase);
// 启动测试序列
phase.raise_objection(this);
`uvm_info("BASE_TEST", "Starting test sequence", UVM_LOW)
seq_base seq;
seq = seq_base::type_id::create("seq", this);
seq.start(my_env.agent.sequencer);
`uvm_info("BASE_TEST", "Test sequence completed", UVM_LOW)
phase.drop_objection(this);
endtask
// 最终阶段
virtual function void final_phase(uvm_phase phase);
super.final_phase(phase);
// 报告测试结果
if (my_env.scoreboard.error_count == 0) begin
`uvm_info("BASE_TEST", "Test passed", UVM_LOW)
end else begin
`uvm_error("BASE_TEST", $sformatf("Test failed with %0d errors", my_env.scoreboard.error_count))
end
// 生成覆盖率报告
$display("Coverage Report:");
$display("Functional Coverage: %0d%%", my_env.coverage_model.get_coverage());
endfunction
endclass
2 sequence如何发送自己的transaction,以及如何启动?
sequence用于生成和发送自己的transaction到sequencer,进而由driver来解析transaction来达到DUT的接口上;
在sequence的body中来例化和发送transaction–uvm_do/with:
virtual task body();
my_transaction req;
// 生成并发送第一个交易
`uvm_do_with(req, { write == 1; addr == 32'h1000; })
`uvm_info("SEQ", "First transaction sent", UVM_MEDIUM)
// 生成并发送第二个交易
`uvm_do_with(req, { write == 0; addr == 32'h2000; })
`uvm_info("SEQ", "Second transaction sent", UVM_MEDIUM)
// 生成并发送随机数量的交易
repeat (10) begin
`uvm_do(req)
`uvm_info("SEQ", "Random transaction sent", UVM_MEDIUM)
end
endtask
driver中一直尝试不断接收transaction并解析赋值到接口上:
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
// 获取虚拟接口
if (!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif)) begin
`uvm_fatal("NOVIF", {"virtual interface must be set for: ", get_full_name(), ".vif"})
end
endfunction
// 运行阶段
virtual task run_phase(uvm_phase phase);
my_transaction tr;
forever begin
// 从 sequencer 获取 transaction
seq_item_port.get_next_item(tr);
// 将 transaction 发送到 DUT
vif.data <= tr.data;
vif.addr <= tr.addr;
vif.write <= tr.write;
vif.valid <= 1;
@(posedge vif.clk);
vif.valid <= 0;
// 通知 sequencer 交易已完成
seq_item_port.item_done();
end
endtask
【总结】
定义 Transaction 类:定义传输类,描述数据包或命令。
定义 Sequence 类:定义序列类,生成和发送交易。
启动 Sequence:在 test 或 sequence 中启动序列。
Driver 接收并发送 Transaction:driver 从 sequencer 接收交易并将其发送到 DUT;
- PCIE有几种复位方式?
----热复位、冷复位、功能复位和链路复位;
- 热复位:热复位是在系统不关机的情况下,对PCIe设备进行的一种复位操作。这个复位只影响PCIe设备,不会重新启动整个系统。
作用:热复位通常用于重新初始化设备,特别是在设备固件更新后,需要重新加载设备配置的情况下。它不会影响设备的电源状态或重新训练链路。 - 功能复位:主要针对的是支持多个功能的PCIe设备(Multi-Fun PCIe Device),可以实现只对特定的Function复位,而其他的Function不受影响。
作用:功能复位可以快速恢复设备某个模块的正常运行,而不需要执行完整的设备复位,从而减少系统停机时间。 - 冷复位:因为切断电源再重新连接导致的复位;
作用:在硬件复位后,设备会重新初始化,并重新执行链路训练,确保PCIe链路能够正常建立; - 链路复位:链路复位是对PCIe链路本身进行的复位操作,而不是对整个设备。它可以通过重新训练链路的方式进行。
作用:链路复位通常用于修复链路中的暂时性错误或者在设备进入低功耗模式后重新激活链路。链路复位后,链路的配置可能会发生变化,例如链路速率和宽度。
4.PCIE建链的训练过程?
PCIe链路训练是一种为了确保两个或更多PCIe设备能够有效、准确地通信的过程。在PCIE的正常建链过程汇总简单分为这三个步骤即可:
1.Detect:来检测可以连接的PCIE设备,确认PCIE链路上可以work的lane;
detect.quite状态–>固定12ms进入detect.active–>发送detect序列,确定lane–>再发一次确定lane–>polling状态;
2.polling:发送TS1和TS2序列,进行位锁定/字符块锁定等–>进入config状态;
3.config:主要作用为完成pcie链路的主要配置工作主要包括,link number 和 lane number,以及对各个lane通过设置FTS来进行deskew。然后进入L0状态使PCIe链路正常工作;
4.L0状态:该状态为PCIe链路正常工作的状态,host可以访问device的配置空间以及与之进行数据交互。
5.PCIE数据链路层如何确保数据传输的可靠性和正确性?
数据链路层添加DLLP header;
1、为TLP分配Sequence ID;
2、为TLP增加LCRC;
3、将TLP在Retry Buffer备份;
4、发送端检查接收端返回的DLLPs;
【ref】
1.https://www.cnblogs.com/hxing/p/14509169.html
2.https://blog.csdn.net/Luckiers/article/details/130469457