1、systemverilog的队列特性
1.1队列的基础操作
方法 | 语法 | 时间复杂度 | 示例 | 结果 |
---|---|---|---|---|
头部插入 | q.push_front(item) |
O(1) | q.push_front(5) |
[5, ...] |
尾部插入 | q.push_back(item) |
O(1) | q.push_back(8) |
[..., 8] |
头部删除 | q.pop_front() |
O(1) | x = q.pop_front() |
[...] |
尾部删除 | q.pop_back() |
O(1) | x = q.pop_back() |
[...] |
任意插入 | q.insert(index, item) |
O(n) | q.insert(2, 10) |
在索引2插入 |
任意删除 | q.delete(index) |
O(n) | q.delete(1) |
删除索引1 |
1.2队列的特殊操作
// 队列拼接
int a[$] = {1,2};
int b[$] = {3,4};
a = {a, 5}; // [1,2,5]
b = {a, b}; // [1,2,5,3,4]
// 范围操作
int q[$] = {0,1,2,3,4};
q = q[1:3]; // [1,2,3] 保留索引1到3
q = q[2:$]; // [3] 保留索引2到末尾
// 排序操作
q.sort(); // 升序排序
q.rsort(); // 降序排序
q.shuffle(); // 随机排序
1.3队列的应用场景
1. 数据缓冲器实现
class fifo_buffer;
int buffer[$];
int max_size = 8;
function void push(input int data);
if(buffer.size() < max_size) begin
buffer.push_back(data);
end
endfunction
function int pop();
if(buffer.size() > 0) begin
return buffer.pop_front();
end
return -1; // 错误码
endfunction
endclass
2. 事务处理管道// 多阶段事务处理
transaction_t pipe_queue[$];
always @(posedge clk) begin
// 阶段1:解码
if(!pipe_queue.size()) begin
pipe_queue.push_back(new_trans);
end
// 阶段2:执行
if(pipe_queue.size() > 0) begin
process(pipe_queue[0]);
pipe_queue = pipe_queue[1:$]; // 移除已处理事务
end
end
1.4专项练习
执行以下操作后,队列a的值是:
int a[$] = {1,2};
initial begin
a.insert(1,3);//(1)
a.push_front(8);//(2)
a = {a,6};//(3)
end
解析:
由(1)得在索引1 处插入3变成{1,3,2}
由(2)得在队列前面插入8变成{8,1,3,2}
由(3)得拼接队列得{8,1,3,2,6}
2、四值逻辑到二值逻辑转换
四值逻辑 → 二值逻辑转换 :x
/z
转为 0
。
例如:bit [3:0] a;
reg [3:0] b=4'b10x0;
assign a = b;
最后a会变成4'b1000。
1. 二值逻辑 vs 四值逻辑
类型 | 值范围 | 典型用途 | 关键字/示例 |
---|---|---|---|
二值逻辑 | 0 , 1 |
高性能仿真、测试平台 | bit , byte , int |
四值逻辑 | 0 , 1 , x , z |
RTL 设计、精确建模 | reg , logic , wire |
关键细节:
logic
是四值类型,可替代reg
和wire
,但不能用于多驱动(如双向总线)。bit
是二值类型,默认无符号,仿真速度更快。
2. 有符号 vs 无符号
类型 | 默认符号性 | 显式声明 | 示例 |
---|---|---|---|
有符号 | integer , int |
logic signed |
logic signed [3:0] a; |
无符号 | reg , bit |
logic unsigned |
bit [3:0] b = 4'b1111; |
关键细节:
- 默认符号性 :
integer
、int
、shortint
、longint
默认有符号。reg
、logic
、bit
、byte
默认无符号。
- 混合运算规则 :
- 若操作数中有一个无符号,则结果视为无符号(可能导致意外负值转换)。
adding
System Verilog引进了一些新的数据类型,如下:
双状态数据类型
队列、动态和关联数组
类和结构
联合和合并结构
字符串
枚举类型
class niuniu;
logic[31:0] a, b, c[8];
function new();
a = 3;
foreach (c[i])
c[i] = 1;
endfunction
endclass
A
代码存在问题,function非void却没有返回值
B
c代表一个8bit的数组
C
这个类的定义是正确的
D
都不对
解析:
1. function new()
• 在 SystemVerilog 中,类的构造函数是 new 方法。new 方法是类的构造器,用来初始化类的成员变量。
• new 方法如果没有明确指定返回值类型,则默认是 void,表示没有返回值。因此,代码中 function new() 定义没有返回值是完全合法的。
2. logic[31:0] a, b, c[8];
• 这里,a 和 b 都是 32 位宽的 logic 类型变量。
• c[8] 声明了一个长度为 8 的数组,数组中的每个元素是 logic[31:0],即每个元素也是 32 位宽的 logic 类型。
这意味着 c 是一个 8 个元素的数组,每个元素都是 32 位宽的逻辑变量。注意,这里的 c 不是一个简单的 8 位数组,而是一个包含 8 个 32 位元素的数组。
3. foreach (c[i]) c[i] = 1;
• foreach 是 SystemVerilog 中的一个语法,用来遍历数组中的每个元素。
• 这里,foreach 循环遍历 c 数组中的每个元素,并将每个元素的值设置为 1。
相关知识点总结:
-
new构造函数:在 SystemVerilog 中,new 是类的构造函数。如果不明确指定返回类型,则默认是 void,表示没有返回值。new 方法用于初始化类的成员变量。
-
数组声明:在 SystemVerilog 中,数组可以指定每个元素的位宽。例如,logic[31:0] c[8] 表示 c 是一个包含 8 个元素的数组,每个元素是 32 位宽的 logic 类型。
-
foreach语句:foreach 是一种用于遍历数组的结构。它会遍历数组中的所有元素,并执行相应的操作。
-
类型声明与数组大小:要特别注意,logic[31:0] c[8] 定义的是一个包含 8 个 32 位元素的数组,而不是 8 位数组。