System Verilog学习笔记
0赞之前用到是Verilog 但是写过一段时间发现同一个模块同和几次 几次结果都不一样 有时之前是好的 但是之后再次编译时发现 功能和之前的不一样 最后发现综合出来的东西和之前不一样 这是由于verilog 语法不严谨(初学者不好把握 没有几年的功底这个是写不好的 ) 为了使 写出来的代码和自己想要生成的电路是一样的 所以就想学学这个System Verilog (听说这个功能很强大)
时序电路的关键字:
always 熟悉Verilog的应该都知道
always_comb 用于组合电路 自动判断敏感列表 这个只能表示没有存储功能的纯组合逻辑
always_latch 纯锁存器
always_ff 跳变沿触发的D触发器
例:
always_comb //这个自动加入了敏感列表
begin
tmp1 = a & b;
tmp2 = c & d;
y = tmp1 | tmp2;
end
下面这样就会产生错误,因为它产生了一个锁存器
always_comb
if (en) q <= 0 ;
所以这个要用
always_latch
if (en) q <= d;
下面的例子又是错误的
always_latch
if (en) q< = d;
else q <= q;
因为它产生了一个组合逻辑反馈环 不会生成锁存器
always_ff @(posedge clk, negedge rst_n)
if (!rst_n) q< = 0;
else q <= d ;
对于这个就和原来的always块产生时序逻辑电路一样 但是当敏感列表中为电平敏感时就会出错、
always_ff @(clk, rst_n)
if (!rst_n) q< = 0;
else q <= q;
在System V中又有一个关键字 enum 这是一个枚举类型的关键字 对于状态机这个是很有用的例:一个三段状态机
module fsm_svla_3
(output reg rd,ds,
input go, ws, clk,rst_n );
enum { IDLE ,
READ ,
DLY ,
DONE ,
XX } state, next;
always @(posedge clk, negedge rst_n)
if (!rst_n) state <= IDLE;
else state <= next;
always @* begin
next = xx;
case (state)
IDLE: if (go) next = READ;
else next = IDLE;
READ: next = DLY;
DLY: if (!ws) next = DONE;
else next = READ;
DONE: next = IDLE;
end
always @(posedge clk, negedge rst_n)
if (!rst_n) begin
rd <= 1’b0;
ds <= 1’b0;
end
else begin
rd <= 1’b0;
ds <= 1’b0;
case (next)
READ: rd <= 1’b1;
DLY: rd <= 1’b1;
DONE: ds <= 1’b1;
endcase
end
endmodule
默认情况下 IDLE是从零递增的 这样看起来更直观