verilog语句执行顺序
- 每个语句块,是事件(event)触发执行的
- 主要分为
- 连续赋值语句assign
- 过程赋值语句always, initial(只执行一次)
- 连续和过程之间是并行执行的,只要满足出发条件即可
- assign是在后面的输入发生变化时进行执行
- always是在敏感列表发生变化时进行执行
- initial是不可综合的
- 阻塞和非阻塞赋值
- 所有过程赋值中非阻塞赋值都是同时并行赋值的
- 阻塞赋值是一条一条进行的
- 阻塞赋值其实也是可以实现阻塞赋值的,主要是要理解非阻塞赋值实质上是把每一个旧数据给了寄存器,只需要把更新的值只给第一位置即可(即最后赋值,电路顺序不同,影响最后的功能)
- 总结说,非阻塞赋值不存在顺序先后,而阻塞存在先后执行关系,电路结果可能不同
- 基础规则
- 描述组合逻辑使用=赋值
- 描述时序逻辑使用<=赋值
- 不要在多个语句块中对同一个变量赋值—多驱动不可综合
- 在一个always块内,该块的一次触发,对同一个信号最多只能赋值一次
- 设计思考
- 为什么我们在设计过程中对于组合逻辑不使用复位信号?
- 一个电路结构主要由组合逻辑和时序逻辑构成,然而当我们对时序逻辑器件进行复位后,那么组合逻辑器件的输出是一定的,因此,没必要多此一举将复位信号的接入组合逻辑。
- 为什么我们在设计过程中对于组合逻辑不使用复位信号?
基于verilog的小电路模型
- 边缘检测
//上升沿检测器 wire clk,rstn; wire din; reg din_dly; wire pulse; assign pulse = din & (!din_dly); always @(posedge clk or negedge rstn) begin if(!rstn) din_dly <= 1'b0; else din_dly <= din; end
- 计数器—当信号en高电平一次,则记录一次
module counter( input wire en, input wire clk, input wire rstn, output reg [3:0] cnt ); always @(posedge clk or negedge rstn) begin if(!rstn) cnt <= 4'b0000; else if(en) cnt <= cnt + 4'b0001; end endmodule
- 移位寄存器
- 按照周期整体向某个方向移动
- 一次可以整体移动Nbit
- 可以左移也可以右移
module Shift-Register( input wire din, input wire rstn, input wire clk, output reg [3:0] sf ); always @(posedge clk or negedge rstn) begin if(!rstn) sf <= 4'b0000; else sf <= {sf[2:0], din}; end endmodule