第五讲 任务、函数和编译预处理
C++学习资料-函数和编译预处理

int maxi(int a,int b) { return a>b?a:b;}
19:01
5.2 形参与实参的结合方式
值传递:实参将它的值传递给形参变量
int max(int x,int y)
a: 20
{x=100;return(x>y?x:y);}
3*f(2)
}
递归调用包括两个过程: 2*f(1)
递推和回代过程.
1
1*2*3*4*5 1*2*3*4 1*2*3 1*2
递推过程 回代过程
19:01
5.3 递归调用的较复杂例子
河内塔问题:A(n)C(借助B )
A柱
B柱
C柱
设A柱上有n个盘子,盘子大小不等,大盘子在下,小盘 子在上,要求将A柱上盘子移到C柱上,每次只能移动 一个盘子,在移动过程中可以借助于任一柱子,但必须 保证三根柱子上的盘子都是大盘子在下,小盘子在上. 要求编一个程序打印出移动盘子的步骤.
40 20
20 40
19:01
5.3 函数的嵌套调用
在函数体内定义另一个函数是不允许的, 每个C++函数都具有平等的地位.但在函 数调用时可以嵌套调用:
A函数{ B函数;
}
B函数{ C函数;
}
C函数{ 函数体;
}
19:01
5.3 函数的递归调用
在函数的嵌套调用中:
函数调用其本身: 称为直接递归
A函数{ A函数;
#include "iostream.h"
int maxi(int a,int b) { return a>b?a:b;}
函数与编译预处理实验报告

函数与编译预处理实验报告一、实验目的本次实验旨在通过编写程序,掌握函数与编译预处理的相关知识,了解函数的调用和返回机制以及编译预处理的作用。
二、实验环境操作系统:Windows 10开发工具:Code::Blocks 17.12编程语言:C语言三、实验内容1. 函数的定义和调用函数是C语言中的一个重要概念,它可以将一段代码封装成一个功能单元,方便代码重用和维护。
在本次实验中,我们需要掌握如何定义函数,并且了解函数的调用过程。
在C语言中,函数通常由以下几部分组成:返回类型函数名(参数列表){函数体;return 返回值;}其中,返回类型指定了函数返回值的类型;函数名是唯一标识符,用于调用该函数;参数列表指定了该函数需要传入的参数;函数体是一段具体的代码逻辑;return语句则将结果返回给调用者。
在调用一个函数时,我们需要按照以下格式进行:返回值变量 = 函数名(参数列表);其中,返回值变量接收该函数返回的结果;参数列表则按照定义顺序传入相应参数。
如果该函数不需要传入任何参数,则可以省略参数列表。
2. 函数指针除了直接调用一个已经定义好的函数外,我们还可以使用函数指针来间接调用一个函数。
函数指针和普通指针类似,它指向的是一个函数的地址。
通过函数指针,我们可以在运行时动态地确定需要调用哪个函数。
在C语言中,声明一个函数指针的方法如下:返回类型 (*指针变量名)(参数列表);其中,括号中的*表示这是一个指针变量;指针变量名则是该变量的标识符;参数列表和返回类型与被指向的函数相同。
通过以下代码可以将一个已经定义好的函数赋值给一个函数指针:int max(int a, int b){return a > b ? a : b;}int (*p)(int, int) = max;在上述代码中,p就是一个用于存储max函数地址的函数指针。
3. 编译预处理编译预处理是C语言中一项重要的功能,在编译过程中会对源代码进行一些预处理操作。
c++程序设计教程 第五章 编译预处理

cout<<"area="<<area<<endl;
re将tu实rn参0x;,y替换字符串“a*b”中的形参a,b后,
} 非形参字符“*ቤተ መጻሕፍቲ ባይዱ保持不变,预编译后A行实际
的语句代码为: area=x*y;
7
例5.4 重新做5.3
#include<iostream>
#define S(a,b) a*b
程序执行后的结果为:
#define S(a,b) a*b 这里,参数表中的参数a,b称为宏名的形式参数,源程 序语句中的宏名仍使用右端的字符串替换,只不过替换时将 字符串中的形式参数用语句中宏名所带的实际参数取代而已。 带参数的宏替换过程可描述如下: 按#define命令行中指定的字符串从左至右置换宏名, 字符串中的形参以相应的实参代替,字符串中的非形参字符 保持不变。
(4)对程序中用双引号括起来的字符串内容,即使与宏名相同,也不进行置 换。
例5.2 写出下面程序的运行结果 #include<iostream > #define PI 3.1415926 #define R 3.0
程序执行后的结果为: PERI=18.8496 AREA=28.2743
#define PERI 2.0*PI*R
2
例5.1 不带参数的宏替换。
#include<iostream >
#define PI 3.1415926 using namespace std; int main( ) { double area,r,peri;
cout<<"请输入圆的半径: ";
程序执行后的结果为: 请输入圆的半径: 3↙ 圆的面积为: 28.2743 圆的周长为: 18.8496
编译预处理

………..
area=S(3,2);
宏展开:
area=3*2;
宏展开:形参用 实参换,其它字符 保留 宏体及各形参外 一般应加括号()
例 #define POWER(x) x*x
x=4; y=6;
z=POWER(x+y); 宏展开:z=x+y*x+y; 一般写成: #define POWER(x) 宏展开: z=((x+y)*(x+y));
形式二: #ifndef 标识符
程序段1 [#else
程序段2] #endif
形式三: #if 表达式
程序段1 [#else
程序段2] #endif
1. 预处理命令是一种特殊命令,为了区别一般C语句, 必须以#开头,结尾不加分号。
2. 预处理命令可以放在程序中的任何位置,其有效范围 是从定义开始到文件结束。
3. 宏定义分为不带参数的宏定义和带参数的宏定义两种
4. 条件编译的三种形式。
整理课堂笔记 完成课后习题
文件包含(2/3)
#include “file2.c”
A
file1.c
被包含文件内容 源文件(*.c) 头文件(*.h)
B file2.c
宏定义 数据结构定义 函数说明等
file2.c A file1.c
文件包含(3/3)
文件包含可嵌套
#include “file2.c” #include “file3.c”
编译预处理包含:
宏定义 文件包含 条件编译
不带参数的宏定义 宏体可缺省,表示宏名 定义过或取消宏体
一般形式: #define 宏名 [宏体] 功能:用指定标识符(宏名)代替字符序列(宏体)
05-编译预处理课件

#define 宏名(形参表) 字符串
• 功能: 预处理程序对程序中所有带实参表的宏名进行宏展开替换。
• 有参宏的调用和宏展开:
- 调用格式:宏名(实参表)
- 宏展开:首先进行宏展开,然后用宏调用提供的实参字符串,直接
置换宏定义命令行中相应形参字符串,非形参字符保持不变。
7
例12 带参数宏定义
#include<stdio.h> ##ddeeffinneeXX(aa)aa**aaint main()
两种格式: #include "文件名"
先在当前目录下查找, 再到系统指定目录下 查找。
#include <文件名>
在系统指定目录下查
• 只包含源文件,不包含可执行文件和目标文找件。
• 一个#include只能包含一个文件。
• 可以将常用的符号常量、带参数的宏定义、外部变量及构造类型
的变量等定义在一个独立的文件中,为其他文件共享。
换。
• 当宏定义在一行写不下,换行时需在行尾加换行字符 "\"。
4
例10 使用宏定义求圆的周长和面积。
#include<stdio.h> #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R int main() {
宏展开: 44++55**44++55
{{
printf("%d\n", X(4+5));
rreettuurrnn00;;
}}
如何使程序的运行结果为 81
?
#define X(a) (a)*(a)
第5章 函数与预处理PPT课件

容称为函数体。在函数体中也有类型说明, 这是对函数体内部所
6
用到的变量的类型说明。【例4.1】中的printst(),print_hello( ) 函数
0
都是无参函数。在很多情况下都不要求无参函数有返回值,因此
环 境
可以不写类型说明符。
返回本节目录
13
)
5.2.1 函数的定义
《 2.有参函数的一般形式
言 程
序 2. C程序实例(2)
设 计 》
(Visual C++ .
6
0
环 境
返回本节6目录
)
5.1.1 C程序实例(1)
《 1.C程序实例1
C
语
【例5.1】简单的函数调用的例子
言
/*功能:定义两个输出函数并在主函数中调用*/
程
/*程序代码文件名:l5_1.cpp/
序
main()
设 计 》
{ printst();
计
(5) 内联函数和重载函数
》
(6)作用域
(7)变量及函数的存储类型
(8) 编译预处理
(Visual C++ .
6
0 环 境 )
返回本书目录
3
第5章 函数与预处理
《
C
语
5.1 函数应用的C程序实例
言
5.2 函数的定义
程 序
5.3 函数调用
设
5.4 函数的嵌套调用和递归调用
计 》
5.5内联函数和重载函数
程
int max(int n1, int n2)
/*定义一个函数max()*/
序
{ return (n1>n2?n1:n2); }
函数与编译预处理实验报告

函数与编译预处理实验报告1. 背景函数与编译预处理是计算机编程中非常重要的两个概念,它们对于程序的结构和执行效率都起着关键作用。
函数是一段可重复使用的代码块,通过将任务划分为多个函数可以提高代码的可读性与维护性。
而编译预处理则是在编译过程中对源代码进行预处理,包括宏展开、文件包含和条件编译等操作。
本次实验通过设计并实现一段使用函数和编译预处理的程序,旨在加深对函数和编译预处理的理解,掌握它们的基本概念和使用方法,并通过实践感受它们对程序结构和性能的影响。
2. 分析2.1 需求在实验中,我们需要设计一个问题,通过函数和编译预处理来实现对问题的解决。
首先,我们需要确定问题的具体要求和输入输出规范。
只有明确了问题的需求,才能设计出合适的函数和合理的编译预处理指令。
2.2 设计根据实验要求,我们可以设计一个简单的问题:计算一个整数的平方。
用户输入一个整数,程序输出该整数的平方。
这是一个简单的计算问题,可以通过函数和编译预处理来实现。
我们可以设计一个函数calculate_square用于计算平方,并通过编译预处理指令来实现输入输出的控制。
具体的实现细节如下:#include <stdio.h>// 函数:计算平方int calculate_square(int x) {return x * x;}// 编译预处理指令:实现输入输出控制#define ENABLE_INPUT_OUTPUT#ifdef ENABLE_INPUT_OUTPUTint main() {int num;printf("Please enter an integer: ");scanf("%d", &num);int result = calculate_square(num);printf("The square of %d is %d.\n", num, result);return 0;}#endif上述代码中,我们定义了一个函数calculate_square用于计算整数的平方。
中国铁道出版社C++_5_函数和编译预处理

C++程序设计----第三章 函数与编译处理
图3.1是一个程序中函数调用的示意图。
main()
func1()
func2()
func3()
func4()
func5()
图3.1
3- 7
C++程序设计----第三章 函数与编译处理
例3.1 在主函数中调用其他函数。 #include <iostream.h> //*****ex3_1.cpp***** int calc_sum(int n) //定义calc_sum()函数 { int k,s; s=0; for (k=1;k<=n;k++) s=s+k; return s; } void print_word() //定义print_word()函数 { cout<<"Hello,C++!"<<endl; //输出一行文字 } void main() { int n; cin>>n; if (n>1) cout<<"the sum is:"<< calc_sum(n)<<endl; //调用calc_sum()函数 print_word(); //调用rint_word()函数 3- 8 }
3- 14
C++程序设计----第三章 函数与编译处理
3.2.2 函数的声明
void A(){…….......................}//函数A定义在B之前 函数的声明与函数定义的规律 void B(){A;….......................}//函数B中调用函数A 如果函数的定义在调用之前就不要函数的声明。 void B();//函数的声明,因为B函数定义在A函数之后 如果函数的定义在调用之后,那么必须在调用的 A(){B;……………………….}//函数A中调用函数B 前面必须进行函数的声明。 B(){………………………….}//函数B的定义 函数的声明可以放在任何位置,关键是一定要放
实验五 函数与编译预处理

《C语言程序设计》实验报告实验五函数与编译预处理学号201002314 姓名李光一、实验目的1、掌握函数定义及调用的方法,正确理解函数调用时实参和形参的对应关系2、掌握并正确使用数组作为函数参数;3、掌握函数的嵌套调用和递归调用的方法;4、理解变量的作用域和生存期;5、掌握宏定义、文件包含的方法。
二、实验内容1、分析下面的程序并上机运行程序,要求写出3组以上程序的运行结果。
#include <stdio.h> /*程序需要使用C语言提供的标准函数库*/int fun(int k) /*此函数用于计算阶乘*/{int result=1,i;for(i=1;i<=k;i++) /*循环k次*/{result=result*i;}return result;}void main() /*主函数*/{int n;printf("Input n please(1<=n<=10)");scanf("%d",&n); /*输入一个数*/printf("%d!=%d\n",n,fun(n)); /*输出结果*/}『运行结果:』2、编写程序,输出2~n之间的所有素数,n由键盘输入。
要求判断素数的过程要写在函数中,由主函数调用实现,并写出2组以上程序运行结果。
程序代码:#include<stdio.h>#include<math.h>void fun(int n){int a,b;for (a=2;a<=n;a++){for (b=2;b<=a-1;b++){if (a%b==0)break;if (b==a-1){printf ("%3d ",a);}}}}void main(){ int t;printf("input t=");scanf("%d",&t);fun(t);printf("\n");} 『运行结果:』3、编程实现输入8个学生某门功课的成绩,用函数求出平均分,并在主函数中输出平均分以及高于平均分的同学的成绩。
第五章 编译预处理综述

宏定义
宏提供了一种文本替换机制,可分为两类: 不带参数的宏和带参数的宏。
3 2 、带参数的宏定义是指在宏名后面跟有形参表,在替换时,仅用 、预处理命令 1、不带参数的宏定义命令是将一个标识符定义为一个字符序列。 #undef和预处理运算符#注意见书 、 ## P69 (1)~(6) 例如,已知半径,求圆的周长和面积。 #include<iostream.h> 实参替换宏体中与形参表中相同的标识符,宏体中其余部分不变。 #undef 其定义格式: 与#define 命令相对应,是取消宏定义的命令。 字符串化运算符 #:若将 #放在替换文本中的某个形参之前,宏替 // 宏定义 #define PI 3.14159 其定义格式: 格式如下: #define <标识符 > [< 字符序列>] 换时对应的参数将被转化成一个字符串。 void main() < 区别两种定义符号常量的方法: #undef #define <宏名 宏名 > >(<参数表 >) <宏体 > 替换文本 宏名 { const修饰符和#define预处理命令。 调用带参数的宏: 宏定义的生存期是以定义时起,到被取消时为止。 字符连接运算符 ## :用于将两个字符序列连接起来,形成一个 执行时,预处理程序将把源程序中出现在宏定义之后的所有宏名 double r,l,s; 例如,#define SQ(x) x*x 如果始终没有被取消,则到该文件结束为止。 宏名 [ 空格 ]( 实参表 ) 新的字符序列。 cout<<“Input radius:”; 逐一替换成相应的替换文本。这样的替换过程称为宏替换。 语句 s=SQ(a+b); cin>>r; 将被替换为:s=a+b*a+b; // 宏替换为 :l=2*3.14159*r; l=2*PI*r; 带参宏与函数的差异:见书 P71~72 (1)~(4) 若是,#define SQ(x) (x)*(x) // 宏替换为: s=3.14159*r*r; s=PI*r*r; 事实上带参宏的优越性已被内联函数所替代。 则上述语句将被替换为: cout<<“L=”<<l<<‘\n’<<“S=”<<s<<endl; s=(a+b)*(a+b); }
函数和编译预处理.doc

函数和编译预处理函数和编译预处理(第五章)一、单项选择题1.关于函数,以下正确的描述是(B)A,函数的定义可以嵌套,但函数的调用不可以嵌套B,函数的定义不可以嵌套,但函数的调用可以嵌套C,函数的定义可以嵌套,函数的调用也可以嵌套D,函数的定义和函数的调用都不M以嵌套2.关键字inline用于定义内联函数,定义时,是将该关键字(D )A.取代定义函数的类型标识符B.取代被定义的函数名C.加在类型标识符之后D.加在类型标识符之前3.以下不正确的描述为(B )A.在函数之外定义的变量称为外部变量,外部变量是全局变量。
B.在函数之内说明的外部变量是局部变量,仅在本函数中有效。
C.在函数之外说明的静态变量也是全局变量,其作用域是文件作用域。
D.文件作用的域范围是一个程序文件,但必须符合“定义在前,使用在后”的规则。
4.以下正确的描述为(C )A,每个C++程序必须在开头用预处理命令^include <iostream. h>B,预处理命令必须位于C++源程序的首部C.在C++中,预处理命令都以#开头D.C++语言的预处理命令只能实现宏定义和条件编译的功能5.在下面的函数原型说明中,存在着语法错误的是(D )A.void BC(int a, int) ;B. void BD(int , int);C. void BE(int , int=5) ;D. int BF(int x ; int y);6.下列哪个不是重载函数在调用时选择的依据(C )A.形参类型B.形参个数C.函数返回值类型D.函数名7.在一个源程序文件中有以下函数定义,其中(D )是重载函数。
A.ABCB. BCDC. ACDD.全部A) int sum (float x, int y) B) float sum (float x, int y, char z) (. . . )C) float sum (float x, float y) D) int sum(int x, int y, char z) (. . . )8.有一个函数原型abc(float x, float y);该函数的返回值类型为(C )A.voidB. doubleC. intD. float9.在程序中,函数声明语句正确位置是(D )A.随便任何位置B.不包含在另一函数中的任何位置。
函数和编译预处理第5章

引言
随着模拟对象的复杂性增加,程序将会变得越来 越复杂和冗长。在编写一个较大的程序时,为了 便于管理,可以采用一些较好的编程策略,常用 的方法是按功能或操作将程序分割成一些具有特 定功能的、相对独立的且便于管理和阅读的小模 块。本章主要介绍这种分割工具之一:函数,包 括函数的定义、函数的调用、参数的传递方法、 内联函数、函数的重载、变量的作用域等,另外 简要介绍编译预处理以及程序多文件组织的编译 和连接方法。
函数调用的使用方式
对于有返回值的函数,可以用两种方式调 用:一种方式是函数调用出现在表达式中, 其值(也称为函数值)参与表达式的运算; 另一种方式是用一个语句来实现调用,即 在调用格式后加上一个分号,构成函数调 用语句,在这种情况下,函数返回值不起 任何的作用。 对于没有返回值的函数,函数调用只能通 过函数调用语句实现。
函数的定义和调用
函数概述 函数定义 函数调用
5.1
函数概述
5.1.1
C++中的函数就是具有特定功能的模块。函数是构 成C++程序的基本单位,C++程序的运行都是由主 函数(main())开始,然后通过一系列函数调用来 实现各种功能。 从用户角度看,函数包括用户自定义函数和系统 库函数。 从函数的形式来看,函数可以分为无参函数、有 参函数、无返回值函数和有返回值函数等 。 除了main()函数以外,一个函数既可以被其它函 数调用,也可以调用其它函数。 图5-l反映了函数的层次组织结构以及相互之间的 调用关系 。
函数原型说明的一般格式
《类型》 <函数名>(<形参表>); 或 《类型》 <函数名>(<形参类型说明表>); 函数原型说明的形参和返回值的类型必须 与对应的函数定义一致,对于第一种格式, 原型说明中形参表的形参名可以和定义时 的形参名不一致,又由于形参在原型说明 中并不起任何作用,因此可以省略形参名 (即第二种格式)。
第五讲 任务、函数和编译预处理

verilog2008--TJU. ASIC Center---Arnold Shi
任务的调用
一个任务由任务调用语句调用。任务调用语句给出传入任 务的参数值和接收结果的变量值,一个任务调用能够修改 被其他任务调用读取的局部变量的值. 任务调用语句是过程性语句,可以在always 语句或 initial 语句中使用。形式如下: task_id [(expr1, expr2 ,...,exprN )] ; 任务调用语句中参数列表必须与任务定义中的输入、输出 和输入输出参数说明的顺序匹配。参数要按值传递,不能 按地址传递。 因为任务调用语句是过程性语句,所以任务调用中的输出 和输入输出参数必须是寄存器类型的
verilog2008--TJU. ASIC Center---Arnold Shi
任务使用举例2
任务的输入和输出在任务开 始处声明。这些输入和输 出的顺序决定了它们在任 务调用中的顺序 task Rotate_Left; inout [1:16] In_Arr; input [0:3] Start_Bit, Stop_Bit, Rotate_By; reg Fill_Value; integer Mac1, Mac3; begin
TJIC
第五讲 任务、函数和编译预处理
天津大学电子科学与技术系 史再峰 shizaifeng@
verilog2009--TJU. ASIC Center---Arnoldsk)
函数(function) 系统任务和系统函数
2
3 4
编译预处理
verilog2008--TJU. ASIC Center---Arnold Shi
end
交通灯例子(续)
//定义交通灯开启时间的任务 task light; output color; input [31:0] tics; begin repeat(tics) @(posedge clock); //等待tics个时钟的上升沿
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
verilog2008--TJU. ASIC Center---Arnold Shi
第二种解答
module sort4(clk,reset,ra,rb,rc,rd,a); output [7:0] ra,rb,rc,rd; input [7:0] a; input clk,reset; reg [7:0] ra,rb,rc,rd; reg [7:0] va,vb,vc,vd; always @ (posedge clk) begin if(!reset) begin va<=0; vb<=0; vc<=0; vd<=0; end else va<=a; end ... .....
verilog2008--TJU. ASIC Center---Arnold Shi
目 录
1 2 3 4
任务(task) 任务(task) 函数(function) 函数(function) 系统任务和系统函数 编译预处理
verilog2008--TJU. ASIC Center---Arnold Shi
verilog2008--TJU. ASIC Center---Arnold Shi
任务调用举例(用全局变量传递数据) 任务调用举例(用全局变量传递数据)
module Global_Var; reg [0:7] RamQ[0:63]; integer Index; reg CheckBit; task GetParity; input Address; output ParityBit; ParityBit = ^ RamQ [Address]; endtask initial for(Index=0; Index<=63; Index=Index+1) begin GetParity(Index,CheckBit); $display("Parity bit of memory word %d is %b.", Index, CheckBit); end endmodule
交通灯例子( 交通灯例子(续)
//定义交通灯开启时间的任务 task light; output color; input [31:0] tics; begin repeat(tics) @(posedge clock); //等待tics个时钟的上升沿 color=off;//关灯 endmodule end endtask //产生时钟脉冲的always块 always begin #100 clock=0; #100 clock=1; end
verilog2008--TJU. ASIC Center---Arnold Shi
任务定义举例
moduleHas_Task; parameterMAXBITS = 8; task Reverse_Bits; input [MAXBITS-1:0]Din; output [MAXBITS-1:0]Dout; integer K; begin for (K=0;K<MAXBITS;K=K+1) Dout [MAXBITS-K] = Din[K]; end endtask ... endmodule
for (Mac3=1; Mac3<=Rotate_By; Mac3=Mac3+1) begin Fill_Value = In_Arr[Stop_Bit]; for (Mac1=Stop_Bit; Mac1>=Start_Bit+1; Mac1 = Mac1-1) In_Arr [Mac1] = In_Arr[Mac1-1]; In_Arr [Start_Bit] = Fill_Value; end end endtask
verilog2008--TJU. ASIC Center---Arnold Shi
任务的调用
一个任务由任务调用语句调用。任务调用语句给出传入任 务的参数值和接收结果的变量值,一个任务调用能够修改 被其他任务调用读取的局部变量的值. 任务调用语句是过程性语句,可以在always 语句或 initial 语句中使用。形式如下: task_id [(expr1, expr2 ,...,exprN )] ; 任务调用语句中参数列表必须与任务定义中的输入、 任务调用语句中参数列表必须与任务定义中的输入、输出 和输入输出参数说明的顺序匹配。参数要按值传递,不能 和输入输出参数说明的顺序匹配 按地址传递。 因为任务调用语句是过程性语句,所以任务调用中的输出 和输入输出参数必须是寄存器类型 寄存器类型的 寄存器类型
function说明语句
函数可以在模块不同位置执行共同代码。函数与任务的不同之处是函 数只能返回一个值,它不能包含任何时延或时序控制 不能包含任何时延或时序控制(必须立即执 不能包含任何时延或时序控制 行),并且它不能调用其它的任务 不能调用其它的任务。此外,函数必须带有至少一个输 不能调用其它的任务 入,在函数中允许没有输出或输入输出说明。函数可以调用其它的函 数。 函数的目的是返回一个用于表达式的值 返回一个用于表达式的值。 返回一个用于表达式的值 定义函数的语法: function <返回值的类型或范围> (函数名); <端口说明语句> <变量类型说明语句> begin <语句> ........ end endfunction 请注意<返回值的类型或范围>这一项是可选项,如缺省则返回值为一 位寄存器类型数据。
TJIC
第五讲 任务、函数和编译预处理 任务、
天津大学电子科学与技术系 史再峰 shizaifeng@
verilog2008--TJU. ASIC Center---Arnold Shi
sk) 任务(task) 函数(function) 函数(function) 系统任务和系统函数 编译预处理
verilog2008--TJU. ASIC Center---Arnold Shi
red=on; //开红灯 light(red,red_tics);//调用等待任务 green=on; //开绿灯 light(green,green_tics);//等待 amber=on; //开黄灯 light(amber,amber_tics); //等待 end
verilog2008--TJU. ASIC Center---Arnold Shi
函数实例
module Function_Example ..... parameter MAXBITS=8; function [MAXBITS-1:0] Reverse_Bits; input [MAXBITS-1:0] Din; integer K; begin for(K=0; K<MAXBITS; K=K+1) Reverse_Bits [MAXBITS-K] = Din[K]; end endfunction ... endmodule
verilog2008--TJU. ASIC Center---Arnold Shi
练习题解答
module sort4 (ra,rb,rc,rd,a,b,c,d); output [7:0] ra,rb,rc,rd; input [7:0] a,b,c,d; reg [7:0] ra,rb,rc,rd; reg [7:0] va,vb,vc,vd; task change; //make comparing inout[7:0] x,y; reg[7:0] tmp; if(x>y) begin tmp=x; x=y; y=tmp; end endtask always @ (a or b or c or d) begin {va,vb,vc,vd}={a,b,c,d}; change(va,vb); change(vb,vc); change(vc,vd); change(va,vb); change(vb,vc); change(va,vb); {ra,rb,rc,rd}={va,vb,vc,vd}; end endmodule
verilog2008--TJU. ASIC Center---Arnold Shi
任务使用举例2 任务使用举例2
任务的输入和输出在任务开 始处声明。这些输入和输 出的顺序决定了它们在任 务调用中的顺序 task Rotate_Left; inout [1:16] In_Arr; input [0:3] Start_Bit, Stop_Bit, Rotate_By; reg Fill_Value; integer Mac1, Mac3; begin
verilog2008--TJU. ASIC Center---Arnold Shi
任务调用举例(带有时序控制) 任务调用举例(带有时序控制)
任务可以带有时序控制, 或等待特定事件的发生。 但是,输出参数的值直到 任务退出时才传递给调用 参数
module TaskWait; reg NoClock; task GenerateWaveform; output ClockQ; begin ClockQ=1; #2 ClockQ=0; #2 ClockQ=1; #2 ClockQ=0; end endtask initial GenarateWaveform (NoClock); endmodule 任务GenerateWaveform ClockQ的 GenerateWaveform对 任务GenerateWaveform对ClockQ的 赋值不出现在NoClock NoClock上 赋值不出现在NoClock上,只有对 ClockQ的最终赋值 的最终赋值0 ClockQ的最终赋值0在任务返回后 出现在NoClock NoClock上 出现在NoClock上。为避免这一情 形出现,最好将ClockQ ClockQ声明为全 形出现,最好将ClockQ声明为全 局寄存器类型, 局寄存器类型,即在任务之外声 明它。 明它。
这个例子描述了一个简单 的交通灯的时序控制,并 且该交通灯有它自己的时 钟产生器。