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

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

3天内不再提示

Verilog赋值和结构说明语句

FPGA之家 来源:时沿科技 作者:Nemo_Yxc 2022-03-15 11:51 次阅读

“本文主要分享了在Verilog设计过程中一些经验与知识点,主要包块语句、阻塞赋值和非阻塞赋值以及结构说明语句(initial, always, task, function)。”

01

块语句

顺序块 begin…end

块内的语句是按照顺序执行的;

块内的每条语句延时控制都是相对于上条语句结束的时刻;

仿真时,执行到最后一条语句该语句块执行结束。

并行块fork…end

块内的语句是按照独立的同时开始执行的;

块内的每条语句延时控制都是相对于程序进入该语句块的时刻而言;

仿真时,所需最长时间的语句执行结束后,该语句块执行结束。

例:

reg  [7:0]    l1,l2;  reg[7:0]k1,k2;initialbeginl1=0;l2=0;#15l1=2;#10l2=8;endinitialforkk1=0;k2=0;#15k1=2;#10k2=8;join
仿真结果如下:

c6f5f9e0-9198-11ec-952b-dac502259ad0.png

从仿真结果可以看出:在顺序块中,15ns的时候,l1被赋值为8’h2,在25ns的时候,l2被赋值为8’h8;而在并行块中,10ns的时候,k2被赋值为8’h8,在15ns的时候,k1被赋值为8’h2。可以很容易明白顺序块和并行块的特性。

02

阻塞赋值和非阻塞赋值

  • 阻塞赋值(Blocking)

阻塞赋值用“=”表示:在赋值时,先计算等号(“=”)右边部分的值,这时赋值语句不允许其他的语句干扰,直到赋值完成,也就是说“阻塞”是指在当前的赋值完成前阻塞其他类型的赋值任务
  • 非阻塞赋值(Non_Blocking)

非阻塞赋值用“<=”表示:在赋值操作时刻开始计算非阻塞赋值右边部分的值,赋值操作结束时刻才更新左边部分

例1:组合逻辑中的阻塞与非阻塞

阻塞代码如下:
always@(a,b,c,d)  begin    i1 = a & b;    i2 = c & d;    i3 = i1 & i2;end
仿真结果如下:

c71bc0a8-9198-11ec-952b-dac502259ad0.png

非阻塞代码如下:
always@(a,b,c,d)  begin    i1 <= a & b;    i2 <= c & d;    i3 <= i1 & i2;end

仿真结果如下:

c73d7d74-9198-11ec-952b-dac502259ad0.png

可以看出i1和i2在阻塞和非阻塞中结果相同,但是i3的结果却不同。这是因为在阻塞赋值中,i3的赋值使用的是i1和i2更新后的值,而非阻塞赋值中i3的赋值则使用的是i1和i2更新前的值。要想解决这一问题,则需要将“always@(a,b,c,d)”改成“always@(a,b,c,d,i1,i2)”代码如下:
always@(a,b,c,d,i1,i2)  begin    i1<=a&b;    i2 <= c & d;    i3 <= i1 & i2;  end
仿真结果如下:

c75bfbbe-9198-11ec-952b-dac502259ad0.png

综上,组合逻辑中更适合用阻塞赋值语句

例2:时序逻辑中的阻塞和非阻塞。

以反馈振荡器的代码为例。非阻塞赋值代码:
always@(posedge  clk,posedge  rst)    begin      if(rst)  a1 <=0;      else    a1 <=a2;    endalways@(posedge  clk,posedge  rst)    begin      if(rst)  a2 <=1;      else    a2 <=a1;end

阻塞赋值代码:

always@(posedge  clk,posedge  rst)  begin      if(rst)   b1 = 0;      else      b1 = b2;  endalways@(posedgeclk,posedgerst)  begin      if(rst)   b2 = 1;      else      b2 = b1;  end

仿真结果如下:

c77723c6-9198-11ec-952b-dac502259ad0.png

可以看出阻塞赋值语句并不能达到我们想要的效果;而且综合后阻塞赋值语句中,无法确定哪个always块中的时钟沿先到达,哪个always块中的时钟后到达,所以存在一个冒险竞争的问题。综上,时序逻辑中更适合用非阻塞赋值语句

03

结构说明语句(initial, always, task, function)

  • 语句initial

语法格式如下:
initial begin  // Add code hereend
一般initial语句用于测试文件的编写;但是随着编译器的进步,现在也可以综合,常用于一些变量的初始化。无论是用在什么场景,initial语句只执行一次。
  • 语句always

语法格式如下: always <时序控制> <语句>

例1:生成仿真时的信号波形

always可以用于仿真时的波形生成:always #5 clk = ~clk;这个例子就形成了一个周期为10ns(时间单位ns根据`timescale确定)的方波,常用来描述时钟信号(如果将#5去掉,那么会生成一个延迟为0的无限循环跳变过程,会发生仿真锁死,这是不推荐的)。仿真结果如下:

c79f5666-9198-11ec-952b-dac502259ad0.png

例2:

实现锁存器和触发器

always@(posedge  clk or posedge   rst)   begin    if(rst)  cnt <= 0;      else    cnt <= cnt + 1;  endalways@(posedge  clk , posedge   rst)  begin    //add codesend
多个敏感事件可以用“or”或者“,”区分(rst为复位信号,可以是posedge也可以是negedge)。

c7c624a8-9198-11ec-952b-dac502259ad0.png

例3:实现组合逻辑

利用always实现组合逻辑时,要将所有的信号放进敏感列表,而时序逻辑中则不需要。
always@(aorborc)  beginx=x+1;end
上面的代码表示,a、b、c中任意电平发生变化,begin…end语句就会被触发。仿真结果如下所示:

c7e60fde-9198-11ec-952b-dac502259ad0.png

always@(a or b or c or d or e)     begin       out = a + b + c + d + e;end
如上所示,因为敏感列表比较长,容易写错,所以Verilog又提供了两个特殊的符号:@*和@(*)。简化代码如下:
always@(*)beginout=a+b+c+d+ e;end
仿真结果如下图所示:

c808a6a2-9198-11ec-952b-dac502259ad0.png

注意:always模块内被赋值的每一个信号都必须定义为reg型
  • 语句task

语句task的定义:

task <任务名>;

<端口及数据类型声明语句>;

<语句1>;

<语句n>;

endtask

示例代码如下:
reg      [7:0]      j,k,i,x;  always@(posedge  clk  or posedge  rst)    begin      if(rst)        begin          i <= 0;          j <= 0;          k <= 0;          x <= 0;          task1(i,j,k);        end      else        begin          i <= i + 1;          x <= i + 10;          task1(i,j,k);        endend  task task1;      input    [7:0]      i;      output   [7:0]      j1;      output   [7:0]      k1;    begin      j1 = i + 10;      k1 = i + 11;    endendtask
仿真结果如下图所示:

c825969a-9198-11ec-952b-dac502259ad0.png

  • 语句function

函数(function)的目的是返回一个用于表达式的值。

语句function的定义:

function<返回值的类型或范围>(函数名)

<端口说明语句>

<变量类型说明语句>

begin

end

endfunction

示意代码如下:
  reg      [7:0]      i,j;  reg      [8:0]      sum_data;    always@(posedge  clk  or posedge  rst)    begin      if(rst)        begin          i <= 100;          j <= 31;          sum_data <= sum(i,j);        end      else        begin          i <= i + 1;          j <= j + 2;          sum_data <= sum(i,j);        end    end
  function  [8:0]  sum;    input  [7:0]  i1;    input  [7:0]  j1;      begin        sum = i1 + j1;      end  endfunction

仿真结果如下图所示:

c85401ba-9198-11ec-952b-dac502259ad0.png

注意:initial、always、task和function都是可以综合的

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Verilog
    +关注

    关注

    28

    文章

    1343

    浏览量

    109970

原文标题:Verilog基础知识学习笔记(二)

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Verilog语言中阻塞和非阻塞赋值的不同

    来源:《Verilog数字系统设计(夏宇闻)》 阻塞和非阻塞赋值的语言结构Verilog 语言中最难理解概念之一。甚至有些很有经验的Verilog
    的头像 发表于 08-17 16:18 6346次阅读

    考虑x和z在verilog条件语句中的使用情况

    首先,考虑x和z在verilog条件语句中的使用情况,然后我们再考虑在verilog中用x和z给其他reg/wire赋值的情况。
    的头像 发表于 11-02 09:40 1698次阅读
    考虑x和z在<b class='flag-5'>verilog</b>条件<b class='flag-5'>语句</b>中的使用情况

    炼狱传奇-赋值语句之战

    Verilog HDL语言中存在两种赋值语言:● 非阻塞型赋值语句● 阻塞型赋值语句1. 非阻塞
    发表于 03-22 10:23

    Verilog过程赋值语句提问

    `在书上看到的,讲解阻塞型赋值语句时,举了一个例子说的是,本想采用触发器的方式,设计一个延时来使得dreg的输出比areg慢3个时钟节拍,但是结果是dreg的输出只比areg慢一个时钟节拍输出程序
    发表于 09-20 15:10

    verilog中generate语句的用法分享

    不同的赋值语句或者逻辑语句,如果在参数量很大的的情况下,原本的列举就会显得心有余而力不足。c语言中常用for语句来解决此类问题,verilog
    发表于 12-23 16:59

    verilog语句中,非阻塞赋值和小于等于均使用符号“<=”,如何区分<=所表示的含义?

    )中,\"<=\"作为非阻塞赋值的一部分。 verilog中,一个语法结构不可能同时允许“表达式”和“语句”, 如果某处可以出现表达式,那么就不允许出现
    发表于 08-08 09:32

    FPGA视频教程之Verilog中两种不同的赋值语句的资料说明

    本文档的主要内容详细介绍的是FPGA视频教程之Verilog中两种不同的赋值语句的资料说明免费下载。
    发表于 03-27 10:55 6次下载
    FPGA视频教程之<b class='flag-5'>Verilog</b>中两种不同的<b class='flag-5'>赋值</b><b class='flag-5'>语句</b>的资料<b class='flag-5'>说明</b>

    verilog中阻塞赋值和非阻塞赋值到底有什么区别

    1、阻塞赋值操作符用等号(即 = )表示。“阻塞”是指在进程语句(initial和always)中,当前的赋值语句阻断了其后的语句,也就是说
    发表于 04-25 08:00 0次下载
    <b class='flag-5'>verilog</b>中阻塞<b class='flag-5'>赋值</b>和非阻塞<b class='flag-5'>赋值</b>到底有什么区别

    Verilog中的赋值语句的区别

    连续赋值语句总是处于激活状态。只要任意一个操作数发生变化,表达式就会被立即重新计算,并且将结果赋给等号左边的线网。
    的头像 发表于 11-26 10:04 3534次阅读
    <b class='flag-5'>Verilog</b>中的<b class='flag-5'>赋值</b><b class='flag-5'>语句</b>的区别

    Verilog HDL语言中连续赋值的特征

    数据流模型化 本章讲述Verilog HDL语言中连续赋值的特征。连续赋值用于数据流行为建模;相反,过程赋值用于(下章的主题)顺序行为建模。组合逻辑电路的行为最好使用连续
    的头像 发表于 03-05 15:38 4101次阅读
    <b class='flag-5'>Verilog</b> HDL语言中连续<b class='flag-5'>赋值</b>的特征

    verilog中的initial语句说明

    解释verilog HDL中的initial语句的用法。
    发表于 05-31 09:11 0次下载

    简述Verilog HDL中阻塞语句和非阻塞语句的区别

      在Verilog中有两种类型的赋值语句:阻塞赋值语句(“=”)和非阻塞赋值
    的头像 发表于 12-02 18:24 6022次阅读
    简述<b class='flag-5'>Verilog</b> HDL中阻塞<b class='flag-5'>语句</b>和非阻塞<b class='flag-5'>语句</b>的区别

    Verilog设计过程中的一些经验与知识点

     “ 本文主要分享了在Verilog设计过程中一些经验与知识点,主要包括块语句、阻塞赋值和非阻塞赋值 以及结构
    的头像 发表于 03-15 12:19 2326次阅读

    verilog中阻塞赋值和非阻塞赋值的区别

    阻塞赋值操作符用等号(即 = )表示。“阻塞”是指在进程语句(initial和always)中,当前的赋值语句阻断了其后的语句,也就是说后面
    发表于 12-19 16:49 7219次阅读

    Verilog中的If语句和case语句介绍

    。这些语句统称为顺序语句。case 语句和 if 语句都是 verilog 中顺序语句的示例。在
    的头像 发表于 05-11 15:37 4290次阅读
    <b class='flag-5'>Verilog</b>中的If<b class='flag-5'>语句</b>和case<b class='flag-5'>语句</b>介绍