Verilog HDL函数与任务的使用

位流涟漪
• 阅读 588
⭐本专栏针对FPGA进行入门学习,从数电中常见的逻辑代数讲起,结合Verilog HDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模。
🔥文章和代码已归档至【Github仓库:hardware-tutorial】,需要的朋友们自取。或者关注公众号【AIShareLab】,回复 FPGA 也可获取。

函数(function)说明语句

函数的定义

函数定义部分可以出现在模块说明中的任何位置,其语法格式如下:

function <返回值类型或位宽> <函数名>;
    <输入参量与类型声明>
    <局部变量声明>
    行为语句;
endfunction

函数的调用

函数调用是表达式的一部分,其格式如下:

<函数名> (<输入表达式1>,……<输入表达式n>);

其中输入表达式的排列顺序必须与各个输入端口在函数定义结构中的排列顺序一致。

关于函数的几点说明

1) 函数不能由时间控制语句甚至延迟运算符组成。
2) 函数至少有一个输入参数声明。
3) 函数可以由函数调用组成,但函数不能由任务组成。
4) 函数在零模拟时间内执行,并在调用时返回单个值。
5) 在编写可综合 RTL时,不建议使用函数。
6) 函数用于编写行为或可仿真模型。
7) 函数不应具有非阻塞赋值。

例 用定义fu3nction与调用function的方法完成4选1数据选择器设计。

(1)设计块(Design Block)代码如下:

`timescale  1ns/1ns    //定义时间单位
module  SEL4to1  ( A, B, C, D, SEL, F );
    input  A, B, C, D;
    input  [1:0] SEL;
    output  F;
  assign F= SEL4to1FUNC ( A, B, C, D, SEL );//调用函数
    //定义函数
    function  SEL4to1FUNC;    //注意此行不需要端口名列表
      input  A1, B1, C1, D1;  //函数的输入参量声明
      input  [1:0] SEL1;      //函数的输入参量声明
      case(SEL1)
        2'd0: SEL4to1FUNC = A1;
        2'd1: SEL4to1FUNC = B1;
        2'd2: SEL4to1FUNC = C1;
        2'd3: SEL4to1FUNC = D1;
      endcase
    endfunction
endmodule

(2)激励块(Test Bench)

`timescale  1ns/1ns    //定义时间单位
module Test_SEL4to1();
//declare variables to be connected to inputs
  reg IN0, IN1, IN2, IN3;
  reg [1:0]SEL;
  wire OUT;      //Declare output wire
//Instantiate the Design Block
  SEL4to1 mymux(.A(IN0), .B(IN1), .C(IN2), .D(IN3), .SEL(SEL), .F(OUT) );

//Stimulate the inputs
initial
  begin
    IN0 = 1;  IN1 = 0; IN2 = 0; IN3 = 0; //set input lines
    #10  $display ($time, "\t IN0= %b, IN1= %b, IN2= %b, 
                   IN3= %b \n", N0, IN1, IN2, IN3);  
    #10   SEL = 2'b00;   //choose IN0
    #30   SEL = 2'b01;   //choose IN1
    #30   SEL = 2'b10;   //choose IN2
    #100  SEL = 2'b11;   //choose IN3
    #100 $stop;          //总仿真时间为280ns
  end
 
always begin
       #5 IN2 = ~IN2;   //每隔 5ns,IN2改变一次状态
   end
always begin
       #10 IN3 = ~IN3;  //每隔10ns,IN3改变一次状态
   end
//Monitor the outputs
initial
      $monitor ($time,  "\t SEL=%b,  OUT = %b \n", SEL, OUT);
endmodule 

(3)仿真结果:

4选1数据选择器的仿真波形

Verilog HDL函数与任务的使用

例:2选1数据选择器(Design Block)

module MUX2_1(A,B,SEL,OUT);
    output OUT;
    input A,B,SEL;

    assign OUT = SEL2_1_FUNC(A,B,SEL); //调用函数
    
    //定义函数
    function SEL2_1_FUNC; //此行不需要端口名列表
      input A,B,SEL;      //函数的输入参量声明
     if (SEL==0) 
           SEL2_1_FUNC = A;
     else  SEL2_1_FUNC = B;
    endfunction

endmodule

例:使用函数计数1的个数的模块。

module count_one_function (data_in, out);
  input      [7:0] data_in;
  output reg [3:0] out;
  always @(data_in)
     out = count_1s_in_byte(data_in);

  // function declaration from here.
  function [3:0] count_1s_in_byte(input [7:0] data_in);
     integer i;
     begin
    count_1s_in_byte = 0;
    for(i=0; i<=7; i=i+1)
      if(data_in[i] == 1)
        count_1s_in_byte = count_1s_in_byte +1;
     end
  endfunction
endmodule    

任务(task)说明语句

任务的定义

task <任务名>;
    端口与类型说明;
   变量声明;
   语句1;
   语句2;
   .....
   语句n;
endtask

任务的调用

一个任务由任务调用语句调用,任务调用语句给出传入任务的参数值和接收结果的变量值,其语法如下:

<任务名>  (端口1,端口2,……,端口n);

关于任务的几点说明

1) 任务可以由时间控制语句甚至延迟操作符组成。
2) 任务可以有输入和输出声明。
3) 任务可以由函数调用组成,但函数不能由任务组成。
4) 任务可以有输出参数,在调用时不用于返回值。
5) 任务可用于调用其他任务。
6) 在编写可综合RTL时,不建议使用任务。
7) 任务用于编写行为或可仿真模型。

例:使用任务从给定字符串中计算1的个数。

module count_one_task (data_in, out);
  input      [7:0] data_in;
  output reg [3:0] out;
  always @(data_in)
     count_1s_in_byte(data_in, out);

  // task declaration from here.
  task count_1s_in_byte(input      [7:0] data_in, 
                        output reg [3:0] count
                        );
     integer i;
     begin               // task functional description
    count = 0;
    for(i=0; i<=7; i=i+1)
      if(data_in[i] == 1)
        count = count + 1;
     end
  endtask
endmodule    

参考文献:

  1. Verilog HDL与FPGA数字系统设计,罗杰,机械工业出版社,2015年04月
  2. Verilog HDL与CPLD/FPGA项目开发教程(第2版), 聂章龙, 机械工业出版社, 2015年12月
  3. Verilog HDL数字设计与综合(第2版), Samir Palnitkar著,夏宇闻等译, 电子工业出版社, 2015年08月
  4. Verilog HDL入门(第3版), J. BHASKER 著 夏宇闻甘伟 译, 北京航空航天大学出版社, 2019年03月

欢迎关注公众号【AIShareLab】,一起交流更多相关知识,前沿算法,Paper解读,项目源码,面经总结。

点赞
收藏
评论区
推荐文章
架构师日记-深入理解软件设计模式 | 京东云技术团队
本文从设计模式与编程语言的关系,设计模式与架构模式的区别,设计原则和设计模式的关系等几个维度进行了分析和解答。关于设计模式应该如何学习和应用的问题,给出了学习意见和实践心得。
黎明之道 黎明之道
4年前
天池比赛数据挖掘心电图模型调参
Task4建模与调参4.1学习目标学习机器学习模型的建模过程与调参流程完成相应学习打卡任务4.2内容介绍逻辑回归模型:理解逻辑回归模型;逻辑回归模型的应用;逻辑回归的优缺点;树模型:理解树模型;树模型的应用;树模型的优缺点;集成模型基于bagging思想的集成
Stella981 Stella981
3年前
OFBiz 快速入门——续二
OFBiz快速入门——续二2011年03月17日星期四00:03OFBiz 快速入门2.5 创建一个文件,取名为(controller.xml),被OFBiz webapp控制器使用的。在没有额外增加功能时,这个文件内容非常的小与简单,如下:<?xml version"1.0" encoding"UTF8"?<siteco
Stella981 Stella981
3年前
Kafka学习(学习过程记录)
Apachekafka这,仅是我学习过程中记录的笔记。确定了一个待研究的主题,对这个主题进行全方面的剖析。笔记是用来方便我回顾与学习的,欢迎大家与我进行交流沟通,共同成长。不止是技术。Kafka介绍与面向MQ编程模式介绍springboot整合ApacheKafka!image20200131104759
Wesley13 Wesley13
3年前
FPGA逻辑设计回顾(5)多比特信号的CDC处理方式之MUX同步器
前言多比特信号跨时钟域处理的场景与方案MUX同步器参考资料前言信号的跨时钟传输的方法很多,在上篇专栏中,就说了两种有关单比特脉冲信号的跨时钟域传输问题,FPGA逻辑设计回顾(4)亚稳态与单比特脉冲信号的CDC处理问题\1\,建议大家看看,后面我还
Stella981 Stella981
3年前
HBase和ElasticSearch索引类型及存储位置
本篇博文主要对HyperBase(HBase)、Search(ElasticSearch)的索引类型及具体存储位置进行概要总结,让大家从整体上了解TDH平台中HyperBase和Search索引的管理。后续会在大数据核心原理与实践专栏中对索引相关知识进行详细讲解。ESSearch索引类型存放位置在早期ESSearch1.X版本,会将索引存在
Wesley13 Wesley13
3年前
Java 并发编程之 JMM & volatile 详解
本文从计算机模型开始,以及CPU与内存、IO总线之间的交互关系到CPU缓存一致性协议的逻辑进行了阐述,并对JMM的思想与作用进行了详细的说明。针对volatile关键字从字节码以及汇编指令层面解释了它是如何保证可见性与有序性的,最后对volatile进行了拓展,从实战的角度更了解关键字的运用。一、现代计算机理论模型与工作原理
深度学习与图神经网络研修
深度学习与图神经网络研修时间2022年10月13日—2022年10月17日直播特色:1、采用深入浅出的方法,结合实例并配以大量代码练习,重点讲解深度学习框架模型、科学算法、训练过程技巧。2、能够把握深度学习的技术发展趋势,可以熟练掌握深度学习核心技术、实践技巧,同时针对工作中存在的疑难问题进行分析讲解和专题讨论,有效的提升学员解决复杂问题的能力;3