面试题集

总结一些面试题集

verilog

边沿检测

写出上升沿检测,下降沿检测,边沿检测代码

1
2
3
4
5
6
7
8
9
@always @(posedge clk, negedge rstn)
if(!rstn)
in_d1 <= 0;
else
in_d1 <= in;

assign o_rise = in & (~in_d1);
assign o_fall = (~in) & in_d1;
assign o_edge = in ^ in_d1;

System verilog

interface和virtual interface区别

interface是个硬件块,等价于module概念。virtual interface是个软件块,可以理解为指向硬件块的指针。

硬件块和软件块的区别

module静态对象,compile time construct

class动态对象,run time construct

virtual function和pure virtual function

virtual function,函数重载,子类可重载父类的函数

pure virtual function,纯虚函数,不可实例化,必须继承并重载该函数

coverage种类

function coverage功能覆盖率

code coverage代码覆盖率,line,fsm,condition,toggle

UVM

phase有哪些,哪些消耗仿真时间

build_phase
connect_phase
end_of_elaboration_phase
start_of_simulation_phase

reset_phase(pre/post),耗时
configure_phase(pre/post),耗时
main_phase(pre/post),耗时
shutdown_phase(pre/post),耗时

extract_phase
check_phase
report_phase
final_phase

run_phase,耗时

执行顺序

build_phase:自上而下。需要上层先将下层类实例化,才能调用下层类的build_phase。同一层次以字典顺序执行。深度优先。
例如:
aa bb
/ \ / \
cc dd ee ff
aa->cc->dd->bb->ee->ff

除build_phase之外的function phase:自下而上,先下层类的,后上层类的。

task phase:自下而上启动,同时运行。

uvm采用深度优先原则build

new和create区别

new是直接实例化类。

create是利用factory机制创建类,会将类注册到factory中。

env::type_id::create("env",this);

factory有什么用

  1. 通过字符串创建一个类。

    关键:参数化类,静态变量,静态函数,联合数组

  2. override功能。用一个子类替换掉父类。

    将所有override信息记录下来,在创建时替换掉,所以不能用new的方式创建类,需要调用特定函数。

C语言

strlen和sizeof

strlen是函数,sizeof是运算符

sizeof可用类型做参数,strlen只能用char*做参数,切必须以\0结尾

数组做sizeof不退化,传递给strlen就退化成指针

strlen的结果在运行时计算出来,是计算字符串的实际长度;而sizeof是类型占用内存的大小,在编译时就得到的。

将一个地址某一bit清零

*(volatile unsigned int * 0x8000) =(*(volatile unsigned int * 0x8000)) & 0xfffffffe;

指针

指向指针的指针:int **a;

一个有10个指针的数组:int * a[10];

一个指向有10个整型数组的指针:int (*a)[10];

一个指向函数的指针:int (*a)(int)

一个有10个指针的数组,指针指向一个函数:int (*a[10])(int)

函数指针:void (*f)()

函数返回指针:void * f()

const指针:const int * p或者int const *p,*p是const的,p可变

指向const的指针:int * const p,p是const的,*p可变

static作用

退出一块后仍然存在的局部变量

不能被其他文件访问的全局变量,函数

const作用

只读

为读代码的人传递有用信息

为保护那些不希望被改变的参数,防止被无意修改

volatile作用

可能会被意想不到改变,编译器每次都小心地重新读取这个变量的值,而不取寄存器的备份(告诉编译器取消优化)

并行设备的硬件寄存器

中断子程序中会访问的非自动变量(全局变量)

多线程应用中被几个任务共享的值

大端小端

大端:数据高字节存放在低地址,低字节存放在高地址,与阅读习惯一致。

小端:数据高字节放在高地址,低字节放在低地址。

int value = 0x12345678;

小端 大端
高地址 12 78
34 56
56 34
低地址 78 12
1
2
3
4
5
6
7
8
int is_little_endian(){
union w{
int a;
char b;
}c;
c.a = 1;
return (c.b == 1);
}

宏定义

定义宏取两个值里面小的值

1
#define MIN(A,B) ((A)<=(B)?(A):(B))

定义宏交换两个值

1
2
3
#define SWAP(X,Y)	(X) = (X) ^ (Y); \
(Y) = (X) ^ (Y); \
(X) = (X) ^ (Y);

判断float是否等于零

1
2
const float EPSINON = 0.00001;
if(x >= -EPSINON && x<=EPSINON)

假设有一个没有头指针的单链表,一个指针指向此链表中间的一个节点(非头,非尾),请将该节点删除

假设该节点是B,下一个节点是C,那将B节点的内容替换为C节点内容,再删掉C节点就可以了。