0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

介绍Verilog的2大类时序控制方法

冬至子 来源:数字IC与好好生活的两居室 作者:除夕之夜啊 2023-06-02 11:44 次阅读

Verilog 提供了 2 大类时序控制方法:时延控制和事件控制。事件控制主要分为边沿触发事件控制与电平敏感事件控制。

时延控制

基于时延的时序控制出现在表达式中,它指定了语句从开始执行到执行完毕之间的时间间隔。

时延可以是数字、标识符或者表达式。

根据在表达式中的位置差异,时延控制又可以分为常规时延与内嵌时延。

◆常规时延

遇到常规延时时,该语句需要等待一定时间,然后将计算结果赋值给目标信号

格式为:#delay procedural_statement,例如:

reg  value_test ;
reg  value_general ;
#10  value_general    = value_test ;

该时延方式的另一种写法是直接将井号 “#” 独立成一个时延执行语句,例如:

#10 ;
value_ single         = value_test ;

◆内嵌时延

遇到内嵌延时时,该语句先将计算结果保存,然后等待一定的时间后赋值给目标信号。

内嵌时延控制加在赋值号之后。例如:

reg  value_test ;
reg  value_embed ;
value_embed        = #10 value_test ;

需要说明的是,这 2 种时延控制方式的效果是有所不同的。

当延时语句的赋值符号右端是常量时,2 种时延控制都能达到相同的延时赋值效果。

当延时语句的赋值符号右端是变量时,2 种时延控制可能会产生不同的延时赋值效果。

◆例如下面仿真代码:

`timescale 1ns/1ns

module test ;
    reg  value_test ;
    reg  value_general, value_embed, value_single ;

    //signal source
    initial begin
        value_test        = 0 ;
        #25 ;      value_test        = 1 ;
        #35 ;      value_test        = 0 ;        //absolute 60ns
        #40 ;      value_test        = 1 ;        //absolute 100ns
        #10 ;      value_test        = 0 ;        //absolute 110ns
    end

    //(1)general delay control
    initial begin
        value_general     = 1;
        #10 value_general  = value_test ; //10ns, value_test=0
        #45 value_general  = value_test ; //55ns, value_test=1
        #30 value_general  = value_test ; //85ns, value_test=0
        #20 value_general  = value_test ; //105ns, value_test=1
    end

    //(2)embedded delay control
    initial begin
        value_embed       = 1;
        value_embed  = #10 value_test ; //0ns, value_test=0
        value_embed  = #45 value_test ; //10ns, value_test=0
        value_embed  = #30 value_test ; //55ns, value_test=1
        value_embed  = #20 value_test ; //85ns, value_test=0
    end

    //(3)single delay control
    initial begin
        value_single      = 1;
        #10 ;
        value_single = value_test ; //10ns, value_test=0
        #45 ;
        value_single = value_test ; //55ns, value_test=1
        #30 ;
        value_single = value_test ; //85ns, value_test=0
        #20 ;
        value_single = value_test ; //105ns, value_test=1
    end

    always begin
        #10;
        if ($time >= 150) begin
            $finish ;
        end
    end

endmodule

◆仿真结果如下,由图可知:

(1)一般延时的两种表达方式执行的结果都是一致的。

(2)一般时延赋值方式:遇到延迟语句后先延迟一定的时间,然后将当前操作数赋值给目标信号,并没有“惯性延迟”的特点,不会漏掉相对较窄的脉冲。

(3)内嵌时延赋值方式:遇到延迟语句后,先计算出表达式右端的结果,然后再延迟一定的时间,赋值给目标信号。

图片

◆下面分析下内嵌延时的赋值过程:

(1) value_embed = #10 value_test ; //0ns, value_test=0

0ns 时,执行此延时语句。

先将 0 赋值给信号 value_embed, 延迟 10ns 输出为 0;

(2) value_embed = #45 value_test ; //10ns, value_test=0

10ns 时,执行此延时语句。

由于此时 value_test 仍然为 0,所以 value_embed 值不变。

即到 55ns 时,value_embed 值仍然保持为 0。

(3) value_embed = #30 value_test ; //55ns, value_test=1

同理,55ns 时,value_test 值为 1,将其赋值给 value_embed 并延迟 30ns 输出。

所以 85ns 时,value_embed 输出为 1。

(4) value_embed = #20 value_test ; //85ns, value_test=0

同理,105ns 时,value_embed 输出为 0。

边沿触发事件控制

在 Verilog 中,事件是指某一个 reg 或 wire 型变量发生了值的变化。

基于事件触发的时序控制又主要分为以下几种。

◆一般事件控制

事件控制用符号 @ 表示。

语句执行的条件是信号的值发生特定的变化。

关键字 posedge 指信号发生边沿正向跳变,negedge 指信号发生负向边沿跳变,未指明跳变方向时,则 2 种情况的边沿变化都会触发相关事件。例如:

//信号clk只要发生变化,就执行q<=d,双边沿d触发器模型< span="" >
always @(clk) q <= d ;               
//在信号clk上升沿时刻,执行q<=d,正边沿d触发器模型< span="" >
always @(posedge clk) q <= d ; 
//在信号clk下降沿时刻,执行q<=d,负边沿d触发器模型< span="" >
always @(negedge clk) q <= d ;
//立刻计算d的值,并在clk上升沿时刻赋值给q,不推荐这种写法
q = @(posedge clk) d ;

◆命名事件控制

用户可以声明 event(事件)类型的变量,并触发该变量来识别该事件是否发生。

命名事件用关键字 event 来声明,触发信号用 “->” 表示。例如:

event     start_receiving ;
always @( posedge clk_samp) begin
       - > start_receiving ;       //采样时钟上升沿作为时间触发时刻
end

always @(start_receiving) begin
    data_buf = {data_if[0], data_if[1]} ; //触发时刻,对多维数据整合
end

◆敏感列表

当多个信号或事件中任意一个发生变化都能够触发语句的执行时,Verilog 中使用“或”表达式来描述这种情况,用关键字 “or” 连接多个事件或信号。这些事件或信号组成的列表称为“敏感列表”。当然,or 也可以用逗号 “,” 来代替。例如:

//带有低有效复位端的D触发器模型
always @(posedge clk or negedge rstn)    begin     
//always @(posedge clk , negedge rstn)    begin     
//也可以使用逗号陈列多个事件触发
    if(! rstn)begin
           q <= 1’b ;     
       end
    else begin
        q <= d ;
    end
end

当组合逻辑输入变量很多时,那么编写敏感列表会很繁琐。此时,更为简洁的写法是 @* 或@(*),表示对语句块中的所有输入变量的变化都是敏感的。例如:

always @(*) begin
//always @(a, b, c, d, e, f, g, h, i, j, k, l, m) begin 
//两种写法等价
    assign s = a? b+c : d ? e+f : g ? h+i : j ? k+l : m ;
end

电平敏感事件控制

前面所讨论的事件控制都是需要等待信号值的变化或事件的触发,使用 “@+敏感列表” 的方式来表示的。Verilog 中还支持使用电平作为敏感信号来控制时序,即后面语句的执行需要等待某个条件为真。Verilog 中使用关键字 wait 来表示这种电平敏感情况。例如:

initial begin
    wait (start_enable) ;      //等待 start 信号
    forever begin
           //start信号使能后,在clk_samp上升沿,对数据进行整合
        @(posedge clk_samp)  ;
        data_buf = {data_if[0], data_if[1]} ;      
       end
end
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Verilog
    +关注

    关注

    28

    文章

    1343

    浏览量

    109918
  • 触发器
    +关注

    关注

    14

    文章

    1995

    浏览量

    61009
  • 时序控制器
    +关注

    关注

    0

    文章

    17

    浏览量

    11208
  • CLK
    CLK
    +关注

    关注

    0

    文章

    127

    浏览量

    17097
收藏 人收藏

    评论

    相关推荐

    C6678上电芯片时序控制,以及配置端口电平时序Verilog代码

    请问能提供C6678上电芯片时序控制,以及配置端口电平和时序Verilog代码吗?
    发表于 06-21 04:32

    简单而有效的电源时序控制方法介绍

    电源时序控制的优缺点,同时介绍利用ADP5134内部精密使能引脚实现时序控制的一种简单而有效的方法
    发表于 07-03 08:15

    FPGA学习指南合集:Verilog HDL那些事儿(建模篇,时序篇,整合篇)

    控制精度。这显然是非常“传统”而且“古老”的方法,虽然有效但往往就是最费精神和时间的。相反的,主动式是一种讲求在代码上和想象上实现“精密控时”的设计方法。主动式的设计方法是基于“理想
    发表于 04-20 15:45

    STM32微控制器主要分为四大类

    STM32微控制器主要分为四大类:1、STM32 ARM Cortex 32位微控制器。2、STM32 ARM Cortex MPUs。3、STM8 8位MCU。4、经典MCU。如下图
    发表于 08-11 07:42

    IIC总线时序启动时序

    配合实现,传输速率包含标注准(100kps)、快速(400kps)、高速(3.4Mbps)三大类2. IIC总线时序启动时序:当SCL为高电平时,SDA下降沿,表示启动。...
    发表于 11-29 06:20

    Verilog HDL语言实现时序逻辑电路

    Verilog HDL语言实现时序逻辑电路 在Verilog HDL语言中,时序逻辑电路使用always语句块来实现。例如,实现一个带有异步复位信号的D触发器
    发表于 02-08 11:46 4653次阅读

    Verilog HDL语言的文件调用问题:include使用方法介绍

    本文简单介绍在使用Verilog HDL语言时文件的调用问题之include使用方法介绍及举例说明,详见本文...
    发表于 01-24 14:40 6725次阅读
    <b class='flag-5'>Verilog</b> HDL语言的文件调用问题:include使用<b class='flag-5'>方法</b><b class='flag-5'>介绍</b>

    时序图和图的关系

    图和时序图是在软件系统设计中直接和程序代码相关联的图,准确地说,程序代码是由图直接产生,而时序图可以定义图的
    发表于 10-29 11:21 6760次阅读
    <b class='flag-5'>时序</b>图和<b class='flag-5'>类</b>图的关系

    如何使用Verilog-HDL做CPLD设计的时序逻辑电路的实现

    本文档的主要内容详细介绍的是如何使用Verilog-HDL做CPLD设计的时序逻辑电路的实现。
    发表于 12-12 16:25 9次下载
    如何使用<b class='flag-5'>Verilog</b>-HDL做CPLD设计的<b class='flag-5'>时序</b>逻辑电路的实现

    在写Verilog时对时序约束的四大步骤的详细资料说明

    本文档的主要内容详细介绍的是在写Verilog时对时序约束的四大步骤的详细资料说明包括了:一、 时钟,二、 Input delays,三、 Output delays,四、 时序例外
    发表于 08-30 08:00 32次下载
    在写<b class='flag-5'>Verilog</b>时对<b class='flag-5'>时序</b>约束的四大步骤的详细资料说明

    面向时序事件的动态矩阵聚方法RDMC

    时间序列事件聚是研究事件分类及挖掘分析的基础。现有聚方法多直接针对具有时间属性且结构复杂的持续事件聚,未考虑聚对象的转化,聚
    发表于 03-25 15:51 8次下载
    面向<b class='flag-5'>时序</b>事件的动态矩阵聚<b class='flag-5'>类</b><b class='flag-5'>方法</b>RDMC

    Verilog HDL提供了哪两种类型的显式时序控制

    Verilog HDL提供了两种类型的显式时序控制:一种是延迟控制,即定义执行语句的延迟时间;另一种是事件控制,只有当某一事件发生时才允许该
    的头像 发表于 07-02 10:52 1731次阅读

    Verilog的设计方法介绍

    Verilog 的设计多采用自上而下的设计方法(top-down)。即先定义顶层模块功能,进而分析要构成顶层模块的必要子模块;
    的头像 发表于 05-29 15:44 1410次阅读
    <b class='flag-5'>Verilog</b>的设计<b class='flag-5'>方法</b><b class='flag-5'>介绍</b>

    电源时序控制的正确方法,你掌握了吗?

    电源时序控制的正确方法,你掌握了吗?
    的头像 发表于 12-15 09:27 1273次阅读
    电源<b class='flag-5'>时序</b><b class='flag-5'>控制</b>的正确<b class='flag-5'>方法</b>,你掌握了吗?

    电源时序器的原理及使用方法是什么

    电源时序器是一种用于控制多个电源设备按照一定顺序开启或关闭的电子设备。它广泛应用于音响、舞台灯光、电视广播、工业自动化等领域。本文将介绍电源时序器的原理及使用
    的头像 发表于 07-08 14:16 1887次阅读