精华内容
下载资源
问答
  • 多分类模型任务模型(Multi-task Model)的区别在于: 多分类模型:样本集包含多个类别,但是一个样本只属于一类。 多任务模型:样本集包含多个类别,一个样本可以属于多个类别。 一、多分类模型 1、多分类...

    多分类模型和多任务模型(Multi-task Model)的区别在于:

    多分类模型:样本集包含多个类别,但是一个样本只属于一类。

    多任务模型:样本集包含多个类别,一个样本可以属于多个类别。

    一、多分类模型

    1、多分类模型使用交叉熵损失函数。

    在计算时其实就是-log(pt),

    对一个样本来说,pt就是该样本真实的类别,模型预测样本属于该类别的概率。例如某样本的label是[0,1,0],模型预测softmax输出的各类别概率值为[0.1,0.6,0.3]。该样本属于第二类别,模型预测该样本属于第二类别的概率是0.6。这就是pt。pt实际上就是个阶段函数。

    存在一种特殊情况,二分类。既一个事件只存在两种可能性。称之为0-1分布问题(二项分布的特例),对于这类问题,熵的计算方法可以简化为如下算式: 

    numpy实现如下:

    (ps:其实在tensorflow实现这些函数更加复杂,考虑了很多种避免梯度爆炸的情况。例如避免出现y_prd=0或者1的情况(log(0)为-inf,导致loss无穷大),以下的代码实现只是为了更简洁的阐述,是不严谨的实现代码)

    y_true = np.array([0,1,0])
    y_pred = np.array([0.1,0.7,0.2])
    print(-y_true*np.log(y_pred))
    print(np.sum(-y_true*np.log(y_pred)))
    #输出:
        [-0.          0.35667494 -0.        ]
        0.35667494393873245

    2、二分类模型

    二分类的模型有两种情况:输出节点只有一个,输出节点包含两个。这两种情况的损失函数都使用二分类的交叉熵损失函数。以下分别说明

    1)只有一个输出节点

    模型只有一个输出节点时。该节点的激活函数使用sigmoid函数而不是softmax函数。如果该节点的值大于0.5则属于一类。小于0.5属于另外一类。

    举例说明该情况的loss计算

    如果某一样本的类别label=1,模型预测的pred=0.8,则此时的

    用numpy实现的代码如下:

    y_true = np.array([0])
    y_pred = np.array([0.2])
    print(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred))
    print(np.mean(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred),axis=-1))
    #输出:
        [0.22314355]
        0.2231435513142097
    y_true = np.array([1])
    y_pred = np.array([0.8])
    print(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred))
    print(np.mean(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred),axis=-1))
    #输出:
        [0.22314355]
        0.2231435513142097

    2)有两个输出节点。

    将label进行one-hot编码,输出层使用softmax激活函数。

    例如label=[1,0],pred=[0.7,0.3]

    此时的loss fn仍然使用 binary_crossentropy,loss fn会计算每个节点的loss然后求平均。由于两个节点概率互斥,所以其loss总是相等,再求平均所以其loss等同于只使用一个节点的loss。

    y_true = np.array([0,1])
    y_pred = np.array([0.2,0.8])
    print(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred))
    print(np.mean(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred),axis=-1))
    #输出:
        [0.22314355 0.22314355]
        0.2231435513142097

    二、多任务模型(Multi-task model)

    用于二分类的binary_crossentropy损失函数也可用与多任务模型。

    其实在tensorflow 实现sigmoid_cross_entropy_with_logits的源码注释中提到。该loss fn用于类别独立不互斥的情况。也就是一张图像可以包含多个类别。

    def sigmoid_cross_entropy_with_logits(  # pylint: disable=invalid-name
        _sentinel=None,
        labels=None,
        logits=None,
        name=None):
      """Computes sigmoid cross entropy given `logits`.
    
      Measures the probability error in discrete classification tasks in which each
      class is independent and not mutually exclusive.  For instance, one could
      perform multilabel classification where a picture can contain both an elephant
      and a dog at the same time.

    binary_crossentropy为什么可以用于多任务模型的训练。

    这是由于binary_crossentropy会计算输出层中每一个节点的损失,一个节点对应于一个类别,其实也就是计算每一个类别的损失。然后求平均作为最终该图像的loss。用numpy实现如下:

    import numpy as np
    y_true = np.array([0,1,1])
    y_pred = np.array([0.1,0.7,0.8])
    print(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred))
    print(np.mean(-y_true*(np.log(y_pred))-(1-y_true)*np.log(1-y_pred),axis=-1))
    #输出:
        [0.10536052 0.35667494 0.22314355]
        0.22839300363692283

     

    展开全文
  • verilog 中任务函数区别

    千次阅读 2014-09-09 16:56:09
    区别: 1.函数可以返回一个值而任务可以返回

    区别:

    1.函数可以返回一个值而任务可以返回多个值


    2.函数一经调用必须立即执行,里面不能包含任何的时序控制,而task中可以有时序控制


    3.函数可以调用函数,但不可以调用任务,任务既可以调用函数也可以调用任务


    4.函数必须要有一个输入参数,而任务可以没有参数输入。


    4.任务输出的信号,在模块中必须定义为reg信号


    任务和函数的共同点:


    1.任务和函数必须在模块内定义,其作用范围仅适用于该模块,可以在模块内多次调用。


    2.任务和函数中可以声明局部变量,如寄存器,时间,整数,实数和事件,但是不能声明线网类型的变量。


    3.任务和函数中只能使用行为级语句,但是不能包含always和initial块,设计者可以在always和initial块中调用任务和函数。


    常用的系统任务与函数:


    1.显示任务    display  write


    2.文件输入输出任务   fopen,   fclose,  readmemb, readmemh


    3.仿真控制任务


    4.时序验证任务


    5.PLA建模任务


    6.随即建模任务


    7.仿真时间函数  time,  stime


    8.实数变换函数

     

    9.随即函数


    任务和函数能不能综合,取决于是否有延时控制,或者时间控制的语句则是不能综合的,其他情况可以综合

    
    展开全文
  • Verilog中函数任务比较

    千次阅读 2018-09-23 14:25:36
    任务和函数只能实现组合逻辑,而对时序逻辑无能为力。 1 任务  任务就是一段封装在“task-endtask”之间的程序。任务是通过调用来执行的,而且只有在调用时才执行,如果定义了任务,但是在整个过程中都没有调用...

    http://blog.163.com/taofenfang_05/blog/static/64214093201181692057682/

    任务和函数只能实现组合逻辑,而对时序逻辑无能为力。

    1  任务

        任务就是一段封装在“task-endtask”之间的程序。任务是通过调用来执行的,而且只有在调用时才执行,如果定义了任务,但是在整个过程中都没有调用它,那么这个任务是不会执行的。调用某个任务时可能需要它处理某些数据并返回操作结果,所以任务应当有接收数据的输入端和返回数据的输出端。

        任务可以彼此调用,而且任务内还可以调用函数。任务是不可综合的,它只能用于仿真。

    (1)任务定义

        任务定义的形式如下:

        task task_id    // 任务名

             [declaration]   //端口定义

             procedural_statement  //任务的具体操作语句

        endtask

        其中,task_id是任务名;可选项declaration是端口声明语句和变量声明语句,任务接收输入值和返回输出值就是通过此处声明的端口进行的;procedural_statement是一段用来完成这个任务操作的过程语句,如果过程语句多于一条,应将其放在语句块内。

        一些注意事项:

    a. 在任务定义结构中不能出现initial和always过程块。

    b. 任务的输入、输出端口和双向端口数量不受限制,甚至可以没有输入、输出端口和双向端口。

    (2)任务调用

        任务调用语句可以在initial语句和always语句中使用,其语法形式如下:

        task_id[(expr1, expr2, ........, exprN)];

        task_id是要调用的任务名,expr1, expr2, ........是参数列表。参数列表给出传入任务的数据(进入任务的输入端)和接收返回结果的变量(从任务的输出端接收返回结果),任务调用语句中参数列表的顺序必须与任务定义中的端口声明顺序相同。任务调用语句是过程性语句,所以任务调用中接收返回数据的变量必须是寄存器类型。      

        调用任务时,可以引用任务声明所在的模块内定义的任何变量。

        任务内可以带有时序控制,如时延。但任务的输出值必须等到整个任务的全部语句都执行完之后才能返回。

    2   函数

        和任务一样,verilog的函数也是一段可以完成特定操作的程序,这段程序处于关键词“function-endfunction”之间。

    (1)函数定义

        函数定义和任务定义一样,可以出现在模块内的任何位置,其形式如下:

        function [range] function_id;

            input_declaration

            other_declarations

            procedural_statement

        endfunction

        其中[range]参数指定返回值的类型或位宽,默认是1比特数据。

        function_id为所定义函数的名称,对函数的调用也是通过函数名来完成的,而且它在函数结构体内代表一个内部变量,函数调用的返回值就是通过函数名变量传递给调用语句的。

    一些注意事项:

    a. 函数定义只能在模块中完成,不能出现在过程块中;

    b. 函数至少要有一个输入端口,但不能包含输出和双向端口;

    c. 在函数结构中,不能使用任何形式的时间控制语句(#、wait等),也不能使用disable中止语句;

    d. 函数定义结构体总不能出现过程块语句;

    e. 函数内部可以调用函数,但不能调用过程。

        函数的定义中并没有声明输出,函数定义时,在函数内部已经隐性的声明了一个寄存器变量,该寄存器变量与函数名同名并且取值范围也相同。

    (2)函数调用

        函数也是在被调用时才被执行的,调用函数的语句:func_id(expr1, expr2, ........., exprN),其中,func_id是要调用的函数名,expr1, expr2, ......exprN是传递给函数的输入参数列表,该输入参数列表的顺序必须与函数定义时声明其输入的顺序相同。

        在函数内部声明的所有寄存器都是静态的,当函数被调用时,这些寄存器的值不能被改变。

    一些注意事项:

    a. 函数调用可以在过程块中完成,也可以在assign这样的连续赋值语句中出现;

    b. 函数调用语句不能单独作为一条语句出现,只能作为赋值语句的右端操作数。

    3  任务与函数比较

    比较点          任务                函数

    输入输出      可以有任意多个输入输出        至少一输入,不能有输出和双向端口           

    调用         任务只能在过程语句中调用,     函数可作为赋值操作的表达式,

                             而不能在连续赋值语句中调用          用于过程赋值和连续赋值语句

    触发事件控制    任务不能出现always语句;             函数中不能出现always、#,

                             可以包含延时控制语句(#),         这样的语句,要保证函数执行

                             但只能面向仿真,不能综合              在零时间内完成

    调用其他           可以调用其他任务和函数                  只能调用函数,不能调用任务

    返回值              通过输出端口传递返回值                  通过函数名返回,只有一个返回值

    其他说明          任务调用语句可以作为一条               函数调用语句不能单独作为

                            完整的语句出现                                一条语句,出现只能作为赋

                                                                                    值语句的右端操作数

    中断                可以由disable中断                           不允许由disable中断

    展开全文
  • 系统任务4.1 显示任务4.1.1 displaywrite任务4.1.2 strobe监控4.1.3 连续监控4.2 文件I/O任务和函数4.2.1 打开文件关闭文件4.2.2 文件输出4.2.3 数据转换为字符串4.2.4 读取文件内容4.2.5 文件I/O错误状态4.2.6 ...

    阅读《IEEE Standard for Verilog 2005》时,做一些整理和记录。


    1.概述

    任务和函数也属于过程块,多用于仿真文件设计中,使用两者的目的有所区别:

    • 函数(function):对输入的值执行一些处理,返回一个新的值。因此至少有一个input类型的参数,不能有inout或output类型的参数。函数在一个仿真时间单位内执行完毕,因此不能包含任务、不能使用非阻塞赋值。使用上都是把函数作为表达式中的一个操作数。

    • 任务(task):其实作用与module差不多,只是能在过程块中调用,实现的功能比函数更加广泛。任务可以包含时序控制语句,也可以调用其它任务和函数;可以使用任意类型的参数,也可以没有参数。

    比如,将一个数据按位取反后得到一个新的数据,将这个功能用任务的形式实现,调用时形式如下:

    switch_bytess(old_word, new_word);
    

    将这个功能用函数的形式实现,调用时形式如下:

    new_word = switch_bytess(old_word);
    

    接下来分别介绍任务和函数的一些用法,再给出Verilog支持的系统任务和系统函数。


    2.函数(function)

    函数用作表达式中的一个操作数。一个函数的声明架构如下([ ]中的内容表示可选):

    function [automatic] [范围或类型] 函数名 (端口列表);
    	...
    endfunction
    
    // example
    function [7:0] getbyte(input [15:0] address); begin
    	...
    	getbyte = ...;
    end
    endfunction
    
    

    函数的默认返回值时一个标量,可以使用“[范围或类型]”将返回值设置为real、integer、time、realtime或矢量。

    定义函数时,函数内部会隐式地定义一个和函数名相同的数据。函数内部可以直接使用这个数据,这个数据的值便是函数的返回值。


    3.任务(task)

    一个任务的声明架构如下([ ]中的内容表示可选):

    task [automatic] 任务名 (端口列表);
    	...
    endtask
    
    // example
    task my_task (input a, b, inout c, output d, e);
    begin
    	...
    	c = ...;
    	d = ...;
    	e = ...;
    end
    endtask
    

    任务的定义和module差不多,只不过端口列表中的参数可以是任意数据类型。

    本系列第10篇中介绍过“命名块+disable”的用法,disable对任务同样适用。使用“disable+任务名”可以提前终止任务的执行。


    4.系统任务

    系统任务和系统函数是Verilog标准的一部分,都以字符"$"为开头。系统任务可划分为六类,下面分别给出一些常用任务的用法。VCD(value change dump)相关的系统任务不在这里罗列。

    4.1 显示任务

    显示任务又可以分为三类。

    4.1.1 display和write任务

    这类任务用于显示信息,包括 d i s p l a y 、 display、 displaydisplayb、 d i s p l a y o 、 displayo、 displayodisplayh和 w r i t e 、 write、 writewriteb、 w r i t e o 、 writeo、 writeowriteh两组。这两组的唯一区别在于:$display会自动在末尾加上换行符"\n",$write任务不会。

    下表给出打印信息中支持的转义字符:

    参数功能
    \n换行符
    \t制表符(TAB)
    \\显示 \ 符号
    \"显示 " 符号
    \ddd以八进制的方式指定显示的字符
    %%显示 % 符号

    \、"、%三个符号再字符串中都有特殊含义,因此需要采用转义字符的方式打印。"\ddd"比较少见,比如P的ASCII码为(80)10,对应(120)8,则字符串中的"\120"会显示"P"。

    如果任务的表达式参数没有对应的格式控制,$display / $write的默认格式为十进制、$displayb / $writeb的默认格式为二进制、$displayo / $writeo的默认格式为八进制、$displayh / $writeh的默认格式为十进制。如下面代码:

    reg [7:0] cnt = 50;
    
    initial  begin
        $display("cnt: ", cnt);
        $displayh("cnt: ", cnt);
        $displayo("cnt: ", cnt);
        $displayb("cnt: ", cnt);
    end
    

    运行仿真时显示的信息为:

    cnt:  50
    cnt: 32
    cnt: 062
    cnt: 00110010
    

    如果上面代码中都加上格式控制"%d",则四个任务等效,显示的都是十进制的50。下表给出支持的格式控制(参数中的字母不区分大小写),大部分和C语言相同:

    参数功能
    %h16进制格式
    %d10进制格式
    %o8进制格式
    %b2进制格式
    %cASCII字符格式
    %s字符串格式
    %e以指数形式显示实数
    %f以小数形式显示实数
    %g以最简短的方式显示实数
    %t时间格式
    %l显示库绑定信息
    %v显示网络信号强度
    %m显示层次结构名称
    %u无格式2值数据
    %z无格式4值数据

    1.向终端或文件写入值时,系统会自动决定表达式参数值的位置大小。比如一个16bit大小的数,用十六进制需要4个字符宽度(最大FFFF),用十进制需要5个字符宽度(最大65535)。如果在%和radix间加一个0,可以取消这种自动决定的机制,看下面的示例:

    reg [15:0] data = 200;
    initial $display("data: %d.", data);    // data:   200.  数据占5个字符
    initial $display("data: %0d.", data);   // data: 200.   数据占3个字符
    

    2.实数可以用%f、%e、%g三种格式显示,下面给出示例:

    real num = 12000000;
    initial  begin
        $display("%e", num);    // 1.200000e+07
        $display("%f", num);    // 12000000.000000
        $display("%g", num);    // 1.2e+07
    end
    
    real num = 12.345;
    initial  begin
        $display("%e", num);    // 1.234500e+01
        $display("%f", num);    // 12.345000
        $display("%g", num);    // 12.345
    end
    

    3.%t通常与5.1中的仿真时间函数配合使用,时间显示的格式用4.3中的$timeformat任务设置。

    4.%v用于显示标量网络的强度,由于FPGA设计中不会涉及到这方面,前面讲网络数据类型时也没有谈网络强度,这里省略。

    5.%m用于显示调用此系统任务的module、任务、函数、命名块的层次结构名称,不需要传入参数。当有多个实例调用同样的 d i s p l a y / display/ display/write任务时,使用%m可以起到区分的作用。示例如下:

    `timescale 1ns / 1ps
    module sim();
    initial begin : block1
        $display("Hierarchical name is : %m");
    end
    
    // 打印信息如下
    Hierarchical name is : sim.block1
    

    6.%L用于显示指定模块的库信息,如下:

    $display("Library Information is : %l");
    
    // 打印信息如下
    Library Information is : xil_defaultlib.sim
    

    打印的库信息与Vivado中的设置相符:

    7.%u(2值)和%z(4值)更多用在$fwrite任务中,将指定数据的二进制表示形式传给输出流,区别在于%u会将x和z视为0,%z会保留z和x的值。外部程序有的可能支持x和z,有的不支持x和z,因此采用不同的方式来传输数据。

    4.1.2 strobe监控

    这组系统任务$strobe、$strobeb、$strobeo、$strobeh可以在选择的时间点处显示仿真数据。当前仿真时刻的其它所有语句、事件执行完后,$strobe系统任务才会执行,以确保显示的是正确的数据。示例如下:

    reg [15:0] cnt = 0;
    always @ (posedge clk) cnt = $random;
    
    initial begin
        forever @(posedge clk) 
            $strobe("At time %d, data is %d", $time, cnt);
    end
    

    终端打印的信息如下:

    At time                   10, data is 13604
    At time                   30, data is 24193
    At time                   50, data is 54793
    At time                   70, data is 22115
    ......
    

    $strobe使用的参数(包括所有转义字符、格式控制)和$display完全相同。

    4.1.3 连续监控

    $monitor使用的参数(包括所有转义字符、格式控制)和$display完全相同。当$monitor任务的参数列表中有一个或多个参数的值发生变化时(不包括 t i m e 、 time、 timestime和$realtime)打印信息。这个连续地监控参数值的特性,称作连续监控

    $monitoron$monitoroff用于启用或禁用监控过程,相当于打开或关闭监控标志。打开监控标志时,无论参数值是否发生变化,会立即打印一次信息;关闭监控标志后,监控任务处于待机状态,不会执行。默认情况下, 仿真开始的时候会自动打开监控标志。

    4.2 文件I/O任务和函数

    Verilog文件操作涉及到的函数也放在这里。

    4.2.1 打开文件和关闭文件

    打开文件任务 $fopen 和关闭文件任务 $fclose 的使用方法如下:

    	mcd = $fopen("file_name");
    	fd = $fopen("file_name", type);
    	fclose(mcd);
    	fclose(fd);
    

    $fopen的输入参数都是字符串。如果没有指定type参数,返回值称作多通道描述符(MCD);如果设置了type参数,设定打开文件的方式,返回值称作文件描述符(FD)。MCD和FD都是32bit的数,二者的区别大致如下(示例代码见下一小节):

    • MCD:32bit,最高位保留不用,剩下的每bit代表一个打开的文件(置1),因此同时最多只能打开31个文件。LSB被“标准输出”文件占用。这种方法的优势是可以将多个MCD用按位或的方式组合在一起,从而同时向多个文件写入内容。这种打开方式相当于是FD的"w"方式,不支持读取文件内容。

    • FD:32bit,最高位保留不用,恒定为1。三个默认打开的文件会占用三个文件描述符:STDIN、STDOUT、STDERR。这种方法的优势是可以指定打开文件的方式,不过不支持用按位或的方式组合FD,因此不能同时写入多个文件。

    $fopen支持的文件打开方式如下表所示,支持的方式与在C语言种的含义相同:

    type参数功能
    r / rb只读,文件指针指向文件头(不删除文件已有内容);文件不存在则返回0
    r+ / r+b / rb+可读可写,文件指针指向文件头(删除文件已有内容);文件不存在则返回0
    w / wb只写,文件指针指向文件头(删除文件已有内容);文件不存在则尝试创建
    w+ / w+b / wb+可读可写,文件指针指向文件头(删除文件已有内容);文件不存在则尝试创建
    a / ab只写,文件指针指向文件末尾(不删除文件已有内容);文件不存在则尝试创建
    a+ / a+b/ ab+读写方式打开,文件指针指向文件末尾(不删除文件已有内容);文件不存在则尝试创建

    参数中的"b"用于操作二进制文件,用以区分文本文件。

    $fclose通过MCD或FD关闭了文件后,则不能再对此文件进行读、写操作,对此文件的 f m o n i t o r 和 fmonitor和 fmonitorfstrobe操作同时也会取消。相应的资源也会释放出来,用于打开其它文件。

    4.2.2 文件输出

    4.1节中介绍的“显示任务”,在文件操作中都有相对应的系统任务,列于下表:

    $fdisplay$fwrite$fstrobe$fmonitor
    $fdisplayb$fwriteb$fstrobeb$fmonitorb
    $fdisplayo$fwriteo$fstrobeo$fmonitoro
    $fdisplayh$fwriteh$fstrobeh$fmonitorh

    只不过显示任务的信息输出对象为“标准输出”,在Vivado中也就是Tcl控制台;加了"f"后,文件输出任务的信息输出对象为“文件”。唯一区别在于:文件输出任务的第一个参数是要写入文件的MCD或FD。

    此外也没有与 m o n i t o r o n 和 monitoron和 monitoronmonitoroff对应的任务。如果要关闭 f m o n i t o r 或 fmonitor或 fmonitorfstrobe任务的监控,需要用$fclose关闭文件来实现。

    下面给出一个示例代码,展示了MCD和FD的区别,以及如果通过按位或操作同时执行多个MCD的文件输出:

    reg [31:0] fd1, fd2, fd3;
    reg [31:0] mcd1, mcd2, mcd3;
    reg [31:0] file_output;
    initial begin
        // MCD FILE OPEN
        mcd1 = $fopen("test1.txt");
            if (mcd1 == 0) begin $display("mcd open1 failed!"); $finish; end
        mcd2 = $fopen("test2.txt");
            if (mcd2 == 0) begin $display("mcd open2 failed!"); $finish; end
        mcd3 = $fopen("test3.txt");
            if (mcd3 == 0) begin $display("mcd open3 failed!"); $finish; end
        // 同时写入3个文件    
        file_output = mcd1 | mcd2 | mcd3 | 1;
        $fdisplay(file_output,"mcd1: %h, mcd2: %h, mcd3: %h", mcd1, mcd2, mcd3);
        $fclose(mcd1); $fclose(mcd2); $fclose(mcd3);
        
        // FD FILE OPEN
        fd1 = $fopen("test4.txt", "r+"); 
        fd2 = $fopen("test5.txt", "r+"); 
        fd3 = $fopen("test6.txt", "r+"); 
        $display("fd1: %b, fd2: %b, fd3: %b", fd1, fd2, fd3);
        $fclose(fd1); $fclose(fd2); $fclose(fd3);
    end
    

    使用按位或运算符将多个MCD合并在一起,1(即32bit中的LSB)表示标准输出,在Vivado中是Tcl控制台。执行$fdisplay会向三个文件和Tcl控制台同时输出信息。

    终端打印信息如下,MCD和FD的值与前面所说的它们的特点相吻合:

    mcd1: 00000002, mcd2: 00000004, mcd3: 00000008
    fd1: ffffb1e0, fd2: ffffb1e1, fd3: ffffb1e2
    
    4.2.3 数据转换为字符串

    ** s w r i t e ∗ ∗ 任 务 ( 包 括 swrite** 任务(包括 swriteswriteb、 s w r i t e o 、 swriteo、 swriteoswriteh)和 $sformat 任务可以将数据以格式化的形式转换为字符串,存储到reg型变量中。它们的使用方法和 $fwrite 完全一样,只是第一个参数不是要输出的文件FD或MCD,而是要输出的reg型变量的名称。

    这两个任务的功能和C语言stdio.h库中sprintf函数的功能类似。这两个的任务的区别在于:

    • $swrite:和其它任务一样,格式控制可以放在参数列表的不同参数中;
    • $sformat:格式控制只能放在第二个参数中,其余参数全部被视作输出项(和stdio库的sprintf函数用法完全相同)。

    下面给出一个示例代码,试图将128和351两个数字拼接为字符串存放在reg变量中:

    reg [6*8:1] str_reg1, str_reg2;
    reg [8:0] str1 = 128, str2 = 351;
    initial begin
        // 格式控制放在不同的参数中
        $swrite(str_reg1,"%0d","%0d",str1,str2);//"%0d",str2);
        $display("The value of str_reg1 is : %s", str_reg1); 
        
        // 格式控制只能放在第二个参数中
        $sformat(str_reg2,"%0d","%0d",str1,str2);//"%0d",str2);
        $display("The value of str_reg2 is : %s", str_reg2); 
    end
    

    终端打印信息如下:

    The value of str_reg1 is : 128351
    ERROR: No Format provided for this argument
    ERROR: No Format provided for this argument
    The value of str_reg2 is : 437220
    

    两个任务都采用将格式控制"%d"放在两个参数内的形式。 s w r i t e 正 确 的 得 到 了 字 符 串 " 128351 " ; swrite正确的得到了字符串"128351"; swrite"128351"sformat得到的结果错误,且提示了两次ERROR信息。这正是因为$format只将第二个参数"%d"视作格式控制,其余三个参数视作输出项,导致错误发生。

    4.2.4 读取文件内容

    c = $fgetc(fd)” 用于读取FD指向文件的一个字符(相当于1byte),如果发生错误,则返回"EOF(值为-1)"。-1用二进制补码表示各bit全为1,因此存放读取结果的reg型变量c的位宽最好大于8bit,这样才能将EOF和字符"0xFF"区分开。

    **"code = u n g e t c ( c , f d ) " ∗ ∗ 用 于 向 文 件 的 b u f f e r 中 插 入 一 个 字 符 c ( 实 际 上 没 有 改 变 文 件 内 容 ) , 下 一 次 调 用 ungetc(c, fd)"** 用于向文件的buffer中插入一个字符c(实际上没有改变文件内容),下一次调用 ungetc(c,fd)"buffercgetc任务时,会读取到这个字符。如果插入成功,则返回值code为0;插入失败,返回值code为EOF。

    下面是一个测试代码,假设文本文件"test1.txt"中有一行字符串"fpgaesigner":

    integer fd;
    initial fd = $fopen("test1.txt", "r");
    
    reg [15:0] c, ins_flag;
    initial begin
        repeat (4) begin c = $fgetc(fd); $write("%c", c); end
        ins_flag = $ungetc("D", fd);         // 中间插入字符,但实际没有写入文件中
        repeat (8) begin c = $fgetc(fd); $write("%c", c); end
        c = $fgetc(fd); $write("\n%h\n", c);   // 读取错误的字符,返回EOF
        $fclose(fd);
    end
    
    // 终端打印信息
    fpgaDesigner
    ffff
    

    读取完所有字符后,再用$fgetc读取会发生错误,返回值为"0xFFFF"。

    "code = $fgets(str, fd)" 用于读取一组字符,当遇到这三种情况时会停止读取:(1)读到换行符’\n’;(2)读取的字符已经填满了reg类型的变量str;(3)读到EOF,错误发生。 出现错误时,返回值code为0;否则,返回值code为已读取的字符个数。

    看下面的示例代码,假设test1.txt中存放了两行数据“fpga”和“Designer”:

    integer fd;
    initial fd = $fopen("test1.txt", "r");
    
    reg [5*8-1:0] str, read_cnt;
    initial begin
        repeat(3) begin
            read_cnt = $fgets(str,fd); 
            $display("read cnt : %d", read_cnt);
            $display("str : %s", str);
        end
        $fclose(fd);
    end
    
    //打印信息
    read cnt :             5
    str : fpga
    
    read cnt :             5
    str : Desig
    read cnt :             3
    str :   ner
    

    换行符’\n’也会占一个字符,因此第一次$fgets对应的打印信息中有一次换行。最后一次读取时已经读到了文件末尾,因此只读取了3个字符,填充在了str的低位上。

    "code = $fscanf(fd, format, args);"“code = $sscanf(str, format, args);” 用于按照指定格式读取文件或reg变量中的内容,相当于stdio.h库中的sscanf函数。

    读取的数据按照format指定的格式存放在args列表的参数中,返回值code是输入项成功匹配的个数。示例代码如下:

    //test1.txt文本文件内容:
    dog cat 1999 2019
    pnp npn 2009 2029
    
    //示例代码:
    integer fd;
    initial fd = $fopen("test1.txt", "r");
    
    integer rdcnt;
    reg [3*8-1:0] str1, str2, data1, data2;
    reg [17*8-1:0] str = "dog cat 1999 2019";
    initial begin
        // 从文件格式化输入
        repeat (2) begin
            rdcnt = $fscanf(fd,"%s %s %d %d", str1, str2, data1, data2);
            $display("fscanf read %0d char: %s %s %d %d", rdcnt, str1, str2, data1, data2);
        end
        // 从reg输入
        rdcnt = $sscanf(str,"%s %s %d %d", str1, str2, data1, data2);
        $display("sscanf read %0d char: %s %s %d %d", rdcnt, str1, str2, data1, data2);
        $fclose(fd);
    end
    
    //终端打印信息
    fscanf read 4 char: dog cat     1999     2019
    fscanf read 4 char: pnp npn     2009     2029
    sscanf read 4 char: dog cat     1999     2019
    
    

    $fread可以批量地读取二进制数据(文本文件当然也是二进制文件,只不过是二进制数据中可以显示的ASCII子集),其用法比较多:

    	code = $fread(reg, fd);
    	code = $fread(mem, fd);
    	code = $fread(mem, fd, start);
    	code = $fread(mem, fd, start, count);
    	code = $fread(mem, fd, , count);
    

    读取的数据可以放在reg型变量或者内存mem(也就是reg的二维数组)中,其它参数的含义如下:

    • start: 读取的第一个数据装载在mem中的地址位置。没有使用该参数,则从mem的最低地址开始填装。

    • count: 向mem中装载数据数量的最大值(1byte为1个数据)。没有使用该参数,则$fread一直读取数据,直到mem填满或者数据文件已读完。

    $fread读取数据是按字节(byte)的方式。返回值code为已读取的字符数,0则表示有错误发生导致读取失败。给出一个示例,存在一个二进制文件"1.bin"内容如下:

    如下代码读取文件内容:

    integer fd;
    initial fd = $fopen("../1.bin", "rb");
    
    integer i;
    reg [15:0] data [15:0];   // mem一个元素存储2byte
    integer rdcnt;
    initial begin
        rdcnt = $fread(data,fd);  $display("read %0d data", rdcnt);
        for (i = 0; i < 16; i=i+1) 
            $write("%h ", data[i]); 
        $display;    // 补一个换行符
        $fclose(fd);
    end
    
    //终端打印信息
    read 32 data
    5478 9cec dd7b 7095 759e effb 4f2e 4410 4c04 5418 9380 48d2 22a0 9e9e 118a 8bcc 
    
    

    1byte为1个数据,因此上面的mem功能存储32个数据,读到的数据与文件内容一致。

    4.2.5 文件I/O错误状态

    所有文件I/O执行过程中如果发生了错误,会返回一个错误代码。使用" errno = $ferror(fd, str); "可以获取最近一次I/O操作的错误信息,以字符串的形式存储在reg型变量str中(位宽至少640bit),同时还会返回一个常数值errno,与特定的错误信息相对应。

    示例代码如下:

    integer fd, err, code;
    reg [639:0] errstr;
    reg data [3:0];
    initial begin 
        fd = $fopen("../test5.txt", "r");   // 打开文件
        err = $ferror(fd, errstr); $display("err %0d: %0s",err,errstr);
        code = $fscanf(fd,"%b",data);    // 读取文件内容
        err = $ferror(fd, errstr); $display("err %0d: %0s",err,errstr);
    end
    
    //打印信息
    err 0: No Error
    err -1: end of file is seen
    
    

    打开文件时,没有错误发生,errno值为0,str的值为" No Error ";在执行$fscanf时,读完文件中所有数据后,返回一个"end of file is seen"的错误。

    4.2.6 EOF检测

    " code = $feof(fd); "用于检测当前文件指针是否指向EOF(文件末尾),返回非0值表示指针已经指向文件末尾,否则返回0。示例代码如下:

    integer fd, code;
    initial begin 
        fd = $fopen("../test5.txt", "a+");   // 打开文件
        while ($feof(fd) == 0) begin
            code = $fgetc(fd);   $write("%c", code);
        end
        $display("\nFIND EOF: %0d",$feof(fd));
    end
    
    //打印信息
    FIND EOF: 1
    

    f g e t c 读 到 文 件 末 尾 时 , fgetc读到文件末尾时, fgetcfeof的返回值为1(非0)。

    4.2.7 文件定位

    " pos = $ftell(fd); " 用于获取当前文件指针指向的位置。" code = $fseek(fd, offset, operation); "" code = $rewind(fd); " 用于调整文件指针的位置。

    $fseek将文件指针按照operation设置的方式移动offset个字节。operation的含义如下表:

    功能
    0文件指针移动到offset指定的位置处
    1文件指针移动到当前位置加上offset的位置处
    2文件指针移动到EOF加上offset的位置处

    r e w i n d 相 当 于 rewind相当于 rewindfseek(fd,0,0),把文件指针重新移到文件开始位置(wind有“倒带”的意思)。文件指针移动过程中发生错误则返回-1,否则返回0。下面是一个示例代码:

    integer fd;
    reg [7:0] data [3:0];
    initial begin 
        fd = $fopen("../test5.txt", "r");   // 打开文件
        $display("after open pos: %0d", $ftell(fd));
        $fseek(fd,8,0);                       // 定位到位置“8”
        $display("after fseek pos: %0d", $ftell(fd));
        $fread(data,fd);                      // 读取数据
        $display("after read pos: %0d", $ftell(fd));
        $rewind(fd);                          // 重新定位到开头
        $display("after rewind pos: %0d", $ftell(fd));
        $fclose(fd);
    end
    
    //打印信息
    after open pos: 0
    after fseek pos: 8
    after read pos: 12
    after rewind pos: 0
    

    如果文件以“a”或“a+”的方式打开,所有输出到文件的内容只会添加到文件末尾,改变文件指针的位置不会改变文件写入的位置(事实上,当写入文件时,文件指针会自动重新定位到文件末尾)。

    疑问记录:
    一直没有搞清楚Verilog中“a+”的文件打开方式。按描述来说应该是“可读可写”。但在Vivado Simulator中测试,以a+方式打开文件,始终无法读出数据。
    打开文件后,将文件指针移动到任何位置(有数据),读取时都会提示错误" err:end of file is seen "。有待进一步查证。

    4.2.8 读取数据到内存中

    r e a d m e m b ∗ ∗ 和 ∗ ∗ readmemb** 和 ** readmembreadmemh 可以批量地把文本文件中的数据读入到内存中,是一种快速的文件读取方法,无需打开文件、关闭文件等操作。读取的文本文件只能包含以下内容:

    • 空白区:空格、换行、TAB、跳页;
    • 注释:支持所有类型的注释。使用注释和空白区的目的是为了分割不同的数字;
    • 二进制或十六进制数字: r e a d m e m b 用 于 读 取 二 进 制 数 据 , readmemb用于读取二进制数据, readmembreadmemh用于读取十六进制数据。

    两个任务的使用方法如下:

    	$readmemb/h("file_name", memory_name);
    	$readmemb/h("file_name", memory_name, start_addr);
    	$readmemb/h("file_name", memory_name, start_addr, final_addr);
    

    调用任务时可以设置数据存放在内存中的起始地址start_addr和结束地址final_addr。内存地址也可以在文本文件中定义,使用" @hhhh ",即@符号+十六进制形式的地址数据。这样牵涉到的情况比较复杂,下面以示例的形式说明:

    // test1:正常读取
    
    调用任务:$readmemh("../test5.txt");
    文本内容:A5A5 1234 8BCD 5869 2386
    内存内容:a5a5,1234,8bcd,5869,2386,
    
    // test2:调用任务时指定内存地址 => 按地址递增顺序存放在指定的地址范围内
    
    调用任务:$readmemh("../test5.txt", data, 2, 4);
    文本内容:A5A5 1234 8BCD 5869 2386
    内存内容:xxxx,xxxx,a5a5,1234,8bcd,
    
    // test3:调用任务时指定内存地址,起始地址小于结束地址 => 按地址递减顺序存放
    
    调用任务:$readmemh("../test5.txt", data, 4, 2);
    文本内容:A5A5 1234 8BCD 5869 2386
    内存内容:xxxx,xxxx,8bcd,1234,a5a5,
    
    // test4:文件内指定内存地址+注释 => 忽略注释的数据
    
    调用任务:$readmemh("../test5.txt");
    文本内容:@2 A5A5 @3 1234 //8BCD 5869 2386
    内存内容:xxxx,xxxx,a5a5,1234,xxxx,
    
    // test5:文件内指定内存地址,地址随机顺序 => 数据分别存放到指定位置
    
    调用任务:$readmemh("../test5.txt");
    文本内容:@2 A5A5 @1 1234 @4 8BCD //5869 2386
    内存内容:xxxx,1234,a5a5,xxxx,8bcd,
    
    // test6:调用任务和文件内都指定了地址 => 文件内的地址必须在任务参数地址的范围内
    
    调用任务:$readmemh("../test5.txt");
    文本内容:@2 A5A5 @1 1234 @4 8BCD //5869 2386
    内存内容:xxxx,xxxx,a5a5,xxxx,xxxx,
    报错:ERROR: Out of bounds address specified in datafile. Read terminated.
    
    

    4.3 时标任务

    这类任务用于显示和设置时标信息。$printtimescale用于显示指定模块的时间单位和精度,不加任何参数便是显示调用此任务的模块的时标信息。示例如下:

    `timescale 1ns / 1ps
    module sim();
        moda a1();
        initial $printtimescale();
        initial $printtimescale(a1);
        initial $printtimescale(a1.b1);
    endmodule
    
    `timescale 10fs / 1fs
    module moda();
        modb b1();
    endmodule
    
    `timescale 10ns / 1ns
    module modb();
    
    endmodule
    

    查看特定模块的时标信息,则要在任务参数中指定模块的层次结构信息。运行上面代码的打印信息如下:

    Timescale of (sim) is 1ns/1ps.
    Timescale of (sim.a1) is 10fs/1fs.
    Timescale of (sim.a1.b1) is 10ns/1ns.
    

    4.4 仿真控制任务

    仿真控制系统任务有两个,在不同仿真工具中的表现会有所区别。$finish结束仿真,有一个输入参数决定结束仿真时显示的消息,如下表所示(以Vivado Simulator为例):

    参数值信息示例
    0不打印信息$finish called at time : 1 us
    1打印仿真时间和位置$finish called at time : 1 us : File “C:/Users/GodWa/Desktop/test_sim/test_sim.srcs/sim_1/new/sim.v” Line 36
    2打印仿真时间、位置、仿真使用的内存和CPU时间$finish called at time : 1 us : File “…/sim.v” Line 36 Memory in use : 7204 KB (peak memory: 7204 KB) CPU usage : 15 ms

    如果调用$finish时没有加参数,则使用默认值1。$stop用于暂停仿真。但在Vivado仿真器中,除了打印的信息外,这两个系统任务的实际表现并没有明显差别。

    4.5 PLA建模任务

    Verilog提供了一组用于对PLA(可编程逻辑阵列)器件进行建模的系统任务,不过在FPGA设计和仿真文件设计中都用不到,这里省略。

    4.6 随机分析任务

    这类任务包括 $q_initialize$q_add$q_remove$q_full$q_exam用于实现随机队列模型,分别用于创建队列、向队列添加一个实体、从队列拿走一个实体、检查队列是否有放入实体的空间、提供关于队列中活动的一些统计学信息。

    目前还不会用到这类任务,待以后补充。


    5.系统函数

    系统函数可划分为五类,下面分别给出一些常用系统函数的用法。

    5.1 仿真时间函数

    Verilog提供了三个系统函数,来获取当前的仿真时间。

    $time返回一个time类型的数据(实际上就是64bit的无符号整数),表示多少个时间单位。比如下面的代码:

    initial begin
        #100;
        $display("%d", $time);
        #500;
        $display("%d", $time);
    end
    

    打印值分别是100和600,其真实含义的时间是由`timescale定义的时间单位决定的。$stime的作用和 $time完全相同,只是返回值的位宽只有32bit。

    $realtime也是同样的作用,只是返回的是实数。当时间单位不是整数时(比如有" #5.5 "这样的情况),可以使用这个系统函数来获得精确的仿真时间。

    5.2 转换函数

    $signed$unsigned比较熟悉,再看其它的转换函数。

    $rtoi$itor 用显示的方式完成实数和整数之间的转换(real to integer、integer to real) 。$rtoi和直接将实数赋值给整数的效果不同,如下面代码

    reg [7:0] dataa = 0, datab = 0;
    always @ (posedge clk) begin
        dataa <= 5.7;        // 结果为6
        datab <= $rtoi(5.7); // 结果为5
    end
    

    直接赋值采用近似的方式,$rtoi直接会截断小数部分。

    $realtobits$bitstoreal 用于完成实数和64-bit向量形式之间的转换,如下面的代码:

    real a = 568.96, b = 0;
    reg [63:0] dataa = 0;
    always @ (posedge clk) begin
        dataa = $realtobits(a);  // 结果为双精度浮点数
        b <= $bitstoreal(dataa); // 结果为568.96
    end
    

    实数转换后的64-bit向量采用的是IEEE 754规定的双精度浮点数表示方法。

    5.3 概率分布函数

    这类函数用于生成服从某种标准概率分布函数的整数。

    $random函数用于生成随机数,每次调用时返回一个新的32bit随机数(带符号整数)。该函数有一个可选的参数(reg、integer或time类型),表示随机种子。下面给出两个例子:

    // example1: 产生(-b+1)到(b-1)之间的随机数
    reg [23:0] rand;
    rand = $random % b;
    
    // example2: 产生0到b-1之间的随机数
    reg [23:0] rand;
    rand = {$random} % b;
    
    

    example2是利用的拼接运算符的性质,拼接运算符的结果是无符号数,因此整个表达式的结果变成了无符号数。

    产生服从某种分布的概率分布函数的伪随机数的其它系统函数如下表所示(所有参数都是整数值):

    系统函数PDF
    $dist_uniform(seed, sstart, end)均匀分布
    $dist_normal(seed, mean, standard_deviation)正态分布
    $dist_exponential(seed, mean)指数分布
    $dist_poisson(seed, mean)泊松分布
    $dist_chi_square(seed, degree_of_freedom)卡方分布
    $dist_t(seed, degree_of_freedom)T分布
    $dist_erlang(seed, k_stage, mean)埃尔朗分布

    设计者为这些函数提供一个初始的种子值seed,然后让系统函数自动更新这个种子,从而得到特定的分布函数。有两点注意事项:

    • start和end参数:start的值必须小于end的值,限定了$dist_uniform返回值的范围。
    • mean参数表示一系列函数返回值的均值;standard_deviation和degree_of_freedom表示方差和自由度,决定了随机变量概率密度函数的形状。

    特别注意:所有函数的种子参数seed(包括$random)必须以变量的形式传入,不能直接给一个常数(seed参数是inout型的,系统函数读取这个值后还会返回另一个值,因此必须用变量作为载体),否则系统函数是不能正常工作的。示例代码如下:

    integer seed = 5200;
    initial begin
        forever @ (posedge clk)
            cnt = $random(seed);
    end
    

    Verilog 2005标准的17.9.3小节,给出了实现上面所有函数算法的C语言代码,感兴趣可以查阅。

    5.4 命令行输入函数

    t e s t test testplusargs v a l u e value valueplusargs 两个系统函数和启动仿真时的参数有关。仿真工具中启动仿真时,可以用"+"指定一些额外的传入参数,这两个函数用于搜索参数中的字符串或值。

    这个功能和预编译中的"`ifdef"类似,只不过是面向仿真阶段,比如启动仿真时,传入不同的参数以执行不同的仿真代码。目前没有发现Vivado Simulator有相关的接口,不做详细介绍,等以后用到时再补充。

    5.5 数学函数

    这类函数用于完成一些常见的数学运算,输入参数和返回值可以是整数或实数。这些函数的效果和C语言中的标准数学库math.h相同,罗列于下表。

    Verilog函数等效的C语言函数功能
    $ln(x)log(x)自然对数
    $long10(x)log10(x)对数(以10为底)
    $exp(x)exp(x)指数
    $sqrt(x)sqrt(x)平方根
    $pow(x,y)pow(x, y)幂函数
    $floor(x)floor(x)向下取整
    $ceil(x)ceil(x)向上取整
    $sin(x)sin(x)正弦
    $cos(x)cos(x)余弦
    $tan(x)tan(x)正切
    $asin(x)asin(x)反正弦
    $acos(x)acos(x)反余弦
    $atan(x)atan(x)反正切
    $atan2(x,y)atan2(x,y)x/y的反正切
    $hypot(x,y)hypot(x,y)欧氏距离 sqrt(x2+y2)
    $sinh(x)sinh(x)双曲正弦
    $cosh(x)cosh(x)双曲余弦
    $tanh(x)tanh(x)双曲正切
    $asinh(x)asinh(x)反双曲正弦
    $acosh(x)acosh(x)反双曲余弦
    $atanh(x)atanh(x)反双曲正切
    展开全文
  • verilog中的任务函数

    千次阅读 2019-05-01 15:30:21
    目录 ...3.系统函数和系统任务 3.1显示任务 3.1.1显示任务(display and write) 3.1.2选通任务strobe 3.1.3 监控任务monitor 3.2文件输入输出任务 3.2.1文件的打开关闭 3.2.2输出到...
  • FreeRTOS任务延时函数

    千次阅读 2019-03-01 00:04:33
    系统提供了两个任务延时函数:相对延时函数vTaskDelay()绝对延时函数vTaskDelayUntil() 相对延时是指:vTaskDelay()开始执行到退出执行的时间固定 /* 相对延时函数 */ void vTaskDelay(const TickType_t ...
  • 关键字,操作符和函数区别

    千次阅读 2017-09-16 15:00:48
    1:关键字 所谓关键字就是已被:语言本身使用, 不能作其它用途使用的字。 2:操作符 操作符是在表达式中用于连接不同对象的运算符,不同的...函数是一组一起执行一个任务的语句 函数与操作符区别: 1:运算
  • FreeRTOS之任务挂起恢复函数

    千次阅读 2017-10-10 17:23:54
    1.任务挂起恢复相关的函数如下 vTaskSuspend():挂起一个任务 vTaskResume():恢复一个任务的运行 vTaskResumeFromISR():中断服务函数中恢复一个任务的运行2.函数的详细描述 (1)函数vTaskSuspend() 该函数...
  • 返回:贺老师课程教学链接【项目4-成员函数、友元函数和一般函数区别】(1)阅读下面的程序,体会注释中的说明。//例:使用成员函数、友元函数和一般函数区别 #include using namespace std; class Time { ...
  • setTimeoutPromise区别(宏任务和任务

    千次阅读 多人点赞 2018-10-10 00:14:40
    javascript的宏任务和任务任务有Event Table、Event Queue,微任务有Event Queue 1.宏任务:包括整体代码script,setTimeout,setInterval; 2.微任务:Promise,process.nextTick 注:Promise立即执行,...
  • Mysql 存储过程和函数区别

    万次阅读 2011-08-27 19:49:43
    存储过程是用户定义的一系列sql语句的集合,涉及特定表或其它对象的任务,用户可以调用存储过程,而函数通常是数据库已定义... 存储过程和函数存在以下几个区别:  1)一般来说,存储过程实现的功能要复杂一点,而函
  • 练习2-11 计算分段函数【2】

    万次阅读 2018-09-01 16:32:13
    练习2-11 计算分段函数[2](10 分) 本题目要求计算下列分段函数f(x)的值: 注:可在头文件中包含math.h,并调用sqrt函数求平方根,调用pow函数求幂。 输入格式: 输入在一行中给出实数x。 输出格式: 在一...
  • 系统调用和函数调用的区别

    千次阅读 2018-10-10 13:34:49
    系统调用与函数调用的区别 系统调用 1.使用INTIRET指令,内核应用程序使用的是不同的堆栈,因此存在堆栈的切换,从用户态切换到内核态,从而可以使用特权指令操控设备 2.依赖于内核,不保证移植性 3.在用户...
  • 任务——损失函数

    万次阅读 2018-08-02 22:41:21
    《Multi-Task Learning Using ...创新点:之前的损失函数是根据不同任务的权重参数计算得来,这些权重的设置是困难的,而且需要花费大量时间精力去进行验证,在实践中多任务学习望而却步。作者提出了一种考虑hom...
  • 函数类型 operator 运算符(形参表)  {   函数体; {  譬如++运算符的重载为: class lei{ friend lei operator++(const lei& ); } 调用的时候 lei entity = lei(); ...
  • MySQL存储过程和函数区别与优缺点

    千次阅读 2017-07-02 11:17:30
    为什么要使用存储过程和函数 数据库对象存储过程和函数,是用来实现一组关于表操作的SQL语句代码当做一个整体来执行。一个完整的操作会包含多条SQL语句,在执行过程中需要根据前面的SQL语句来执行结果有选择的执行...
  • Matlab中函数和脚本的区别

    千次阅读 2017-01-15 15:00:23
    函数:定义输入参数输出参数的对应关系,方便外部调用,有函数Function...end声明。脚本:一堆命令堆在一起,按照顺序执行,完成某一项任务的文件。没有Function函数声明。函数定义:Function 输出变量=函数名称...
  • FreeRTOS任务API函数的使用

    千次阅读 2017-08-27 18:01:41
    FreeRTOS 任务函数API
  • 机器学习中的目标函数、损失函数、代价函数有什么区别? 首先给出结论:损失函数和代价函数是同一个东西, 目标函数是一个与他们相关但更广的概念,对于目标函数来说在有约束条件下的最小化就是损失函数(loss ...
  • 尽管函数式宏定义普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配释放栈帧、传参、传返回值等一系列工作,因此那些简短并且被频繁调用的函数经常用函数式宏定义来代替实现...
  • Junit单元测试 main函数区别 (踩坑)

    千次阅读 2020-05-30 17:50:10
    最近在学习 定时任务时,踩坑… Junit 单元测试 不支持 多线程!!! 当Thread了新的线程后,Junit单元测试 在主线程运行结束后就关闭了,而不会等子线程运行结束。而main函数就不存在这个问题了... 测试对比如下:...
  • sigmoidsoftmax激活函数区别

    千次阅读 2017-07-13 10:58:59
     sigmoid函数(也叫逻辑斯谛函数):   引用wiki百科的定义:  A logistic function or logistic curve is a common “S” shape (sigmoid curve).  logistic曲线如下:    ...
  • 函数和自定义函数区别

    千次阅读 2017-11-15 17:02:23
    首先举一个比较两个数或者表达式大小的例子。  我们把它写成宏定义函数: #define MAX( a, b) ( (a) > (b) (a) : (b) ) 其次,把它用... } 很显然,我们不会选择用函数来完成这个任务,原因有两个: (1).首先,
  • 分类任务 回归任务区别在于 需要预测的值的类型: 回归任务,是对 连续值 进行预测(比如 多少); 分类任务,是对 离散值 进行预测(比如 是不是,属不属于,或者 属于哪一类)。 打个比方, 预测 明天的...
  • 1.损失函数(Loss function)是定义在单个训练样本上的,也就是就算一个样本的误差,比如我们想要分类,就是预测的类别实际类别的区别,是一个样本的哦,用L表示2.代价函数(Cost function)是定义在整个训练集上面的...
  • ucos 任务延时函数

    千次阅读 2017-01-09 15:41:17
    在ucos里,系统也提供了这样的延时函数,一个是大众版本OSTimeDly(),一个是精致版本的...这两个函数有着非常重要的作用,就是当你调用这两个函数的时候,ucos会进行一次任务调度,所以CPU能在各任务间进
  • FreeRTOS系列第12篇---FreeRTOS任务应用函数

    万次阅读 多人点赞 2016-01-11 17:15:59
    任务应用函数是一组辅助类函数,一般用于调试信息输出、获取任务句柄、获取任务状态、操作任务标签值等等。1.获取任务系统状态1.1函数描述 UBaseType_t uxTaskGetSystemState( TaskStatus_t * ...
  • uCOS-II任务之延时函数

    千次阅读 2016-12-08 10:31:18
    uCOS-II任务延时函数 编写过单片机程序的都知道,延时函数是经常被用到的。 在uCOS-II里,系统也提供了这样的延时函数。一个是大众版的OSTimeDly(),一个是精致版的OSTimeDlyHMSM()。 萝卜青菜,各有所爱,随你...
  • 目标函数,损失函数和代价函数 基本概念: 损失函数:计算的是一个样本的误差 代价函数:是整个训练集上所有样本误差的平均 目标函数:代价函数 + 正则化项 通常机器学习每一个算法中都会有一个目标函数,算法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 996,211
精华内容 398,484
关键字:

任务和函数的区别