文章目录
一、systemVerilog数据类型
1.1 队列的操作
- queue_name.size //返回queue的大小
- queue_name.insert(index,item) //在index索引处插入item元素
- queue_name.delete(index) //刪掉某元素或整个queue
- queue_name.pop_front() //去除第一个元素(队首)
- queue_name.pop_back() //去除最后一个元素(队尾)
- queue_name.push_front() //插入元素到queue(0)(队首)
- queue_name.push_back() //插入元素到queue($)(队尾)
1.2 队列和各种数组之间的关系
数据类型 | 物理内存 | 索引 |
---|---|---|
固定数组 | 编译时创建,之后不能修改 | 数字 |
动态数组 | 仿真时创建,仿真期间可以改变 | 数字 |
队列 | 仿真时push-pop可以改变队列大小 | 数字 |
关联数组 | 仿真时分配内存 | 数字、字符串、类 |
- 动态数组:可以在仿真时分配空间或者调整宽度,这样仿真中就可以使用最小的存储空间。
- 关联数组:用来保存稀疏矩阵的元素,当一个非常大的地址空间进行寻址时,sv只对实际写入的元素分配空间,比定宽数组和动态数组所占用的空间要小得对。
- 队列:结合了链表和数组的优点,可以在队列的任意位置增加或者删除元素,这类操作在性能上比动态数组小得多,可以通过索引对任意元素进行访问。
1.3 mailbox和queue的关系
- mailbox必须通过new()例化,而队列只需声明
- mailbox可存储不同数据类型(不建议),队列只能存储相同类型的数据
- mailbox中的put()和get()是阻塞方法。而队列对应的存取方式为push_back pop_front()为非阻塞,会立即返回 ,在使用queue取数时应先填写 wait(queue.size()>0)。此外,还需注意,如果调用阻塞方法应使用task,非阻塞方法既可以用task也function
- 对于变量操作,在传递形式参数时,mailbox传递的是指针。而queue的形式参数声明是ref方向
二、Verilog时序电路
2.1 数字电路主要分为哪几类?为什么使用触发器或锁存器?
数字电路主要分为两类:1)组合逻辑电路;2)时序电路;使用触发器的原因:用触发器是因为触发器能保存数据,保存电路状态;触发器是在时钟边沿触发,用时钟同步是让整个电路能同步整齐划一的工作;乘法器的计算部分是组合逻辑,不需要触发器,计算后的结果可以用触发器保存起来。具体为什么使用触发器?
2.2 setup/hold violation
2.3 亚稳态的原因以及消除方法有哪些?
2.4 阻塞赋值与非阻塞赋值的区别与联系是什么?
- 阻塞赋值:在always块中,后一句赋值要等到前一句执行完成之后才开始。
- 非阻塞赋值:1)赋值开始时刻,计算所有非阻塞赋值语句右边表达式(RHS)的值。2)赋值结束时刻,更新所有左边表达式(LHS)的值。非阻塞只能用于寄存器的赋值,只能用在initial/always 过程块中。非阻塞不可以用于连续赋值。
2.5 触发器与锁存器的联系与区别?如果锁存器高电平来说建立保持时间是怎么样的?
触发器与锁存器的联系与区别
(1) 寄存器是同步时钟控制,而锁存器是电位信号控制。锁存器一般由电平信号控制,属于电平敏感型。寄存器一般由时钟信号控制,属于边沿敏感型。
(2) 寄存器的输出端平时不随输入端的变化而变化,只有在时钟有效时才将输入端的数据送输出端(打入寄存器),而锁存器的输出端平时总随输入端变化而变化,只有当锁存器信号到达时,才将输出端的状态锁存起来,使其不再随输入端的变化而变化。
可见,寄存器和锁存器具有不同的应用场合,取决于控制方式以及控制信号和数据之间的时间关系:若数据有效一定滞后于控制信号有效(锁存信号(控制信号)来了以后,才将输出端的状态/数据锁存起来),只能使用锁存器;如果数据提前于控制信号而到达且要求同步操作,则可以用寄存器来存放数据。
换言之,控制信号/时钟信号先来,数据后来,用锁存器;
控制信号/时钟信号后来,数据先来,用寄存器。
Latch的建立时间与保持时间。
锁存器的建立和保持时间是以最后CLK高电平消失时间点为基准的,如下图所示:
建立时间(tsetup):
建立时间是在CLK高电平消失之前的最小建立时间
保持时间(thold):
建立时间是在CLK高电平消失之后的最小保持时间
TClk-Q:是CLK电平触发时到数据Q改变