verilog入门学习---项目导向D6---2020/3/23

任务和函数

一、任务

task <任务名>
端口和类型声明
局部变量声明
	begin
		语句;
	end
endtask

例子:

task read_memory;
	input [15:0] address;		//输入端口说明
	output [31:0] data;			//输出端口说明,即返回值
	reg [3:0] counter;			//变量类型说明
	reg [7:0] temp [1:4];		//变量类型说明
	begin 						
		for(counter=1;counter<=4;counter=counter+1)
		temp[counter] = mem[address + counter-1];
		data = {temp[1],temp[2],temp[3],temp[4]};
	end
endtask

例子:交通灯
代码实现:

module traffic_lights_tb(red,yellow,green);
output red,yellow,green;
reg [1:0]order;
reg red,yellow,green;
reg clk;
parameter tic_time_R=1,tic_time_Y=2,tic_time_G=3;
//产生时钟脉冲
initial clk=0;
always
begin
    #10 clk=1;
    #10 clk=0;
end

//任务:开启交通灯
task light;
    output red;
    output yellow;
    output green;
    input [1:0]order;
    begin
        red=0;
        yellow=0;
        green=0;
        case(order)
            2'b01:red=1;
            2'b10:green=1;
            2'b11:yellow=1;
            default:
            begin
                red=0;
                yellow=0;
                green=0;
            end
        endcase
    end
endtask

//任务调用,交通灯初始化
initial
begin
    order=2'b00;
    light(red,yellow,green,order);

end

//任务调用,交通灯控制时序
always 
begin
    order=2'b01;
    light(red,yellow,green,order);//开红灯
    repeat(tic_time_R) @(posedge clk);//重复tic_time次上升沿所经过的时间
    order=2'b10;
    light(red,yellow,green,order);//开绿灯  
    repeat(tic_time_G) @(posedge clk);//重复tic_time次上升沿所经过的时间
    order=2'b11;
    light(red,yellow,green,order);//开黄灯  
    repeat(tic_time_Y) @(posedge clk);//重复tic_time次上升沿所经过的时间
end
endmodule

仿真结果:
在这里插入图片描述

二、函数

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

例子:阶乘函数

module tryfact_tb;
function [31:0]factorial;//函数相当于一个返回数
    input[3:0]operand;
    reg[3:0]index;
    begin
        factorial=1;
        for (index=1;index<=operand;index=index+1)
        factorial=index*factorial;
    end
endfunction
reg [31:0]result;
reg [3:0]n;
initial 
begin
    result=1;
    for (n=1;n<9;n=n+1)
    begin
        result=factorial(n);
        $display("n=%d result=%d",n,result);
    end
end
endmodule

三、任务和函数的区别
在这里插入图片描述
四、测试向量(一般用initial定义)
(1)测试向量例子:质数打印
功能描述:产生位宽为4的质数序列{1 3 5 7 11 13}, 重复两次,样值间隔4个仿真时间单位

'timescale 1ns/1ps
module sequence_tb;
	reg [3:0]out;
initial begin
	repeat (2)
	begin
		#4 out=1;
		#4 out=3;
		#4 out=5;
		#4 out=7;
		#4 out=11;
		#4 out=13;
	end
end
endmodule

仿真波形:
在这里插入图片描述

(2)时钟测试向量例子:

module clk(clk);
	output clk;
	parameter clk_period=20;
	reg clk;
	initial clk=0;
	always #(clk_period/2) clk=~clk;
endmodule

(3)自定义占空比时钟信号:

module Duty_Cycle(clk);
output clk;
reg clk;
parameter high_time=5, low_time=20;
always
	begin
		clk=1;
		#high_time;
		clk=0;
		#low_time;
	end
endmodule

(4)具有相位偏移的时钟信号
(组成:标准时钟加延迟,用途:一般用在将采样时钟信号移到眼图中央)

module shift_Duty_Cycle(clk_a,clk_b);
output clk_a,clk_b;
reg clk_a;
wire clk_b;
parameter high_time=5, low_time=20,shift_time=5;
always
	begin
		clk_a=1;
		#high_time;
		clk_a=0;
		#low_time;
	end
assign #shift_time clk_b=clk_a;
endmodule

(5)产生固定数目的时钟信号

module fix_num_clk(clk);
output clk;
reg clk;
parameter clk_num=5,clk_period=10;
initial begin
	clk=0;
	repeat(clk_num)
		#clk_period/2 clk=~clk;
end
endcase

(6)总线信号测试向量

四、基本门级元件和模块的延时建模
上升延时:信号由0、x、z状态变化到1状态收到的门延时时间
下降延时:信号由1、x、z状态变化到0状态收到的门延时时间
截止延时:信号由0、1、x状态变化到z状态收到的门延时时间
到不定态的延时:信号由0、1、z状态变化到x状态收到的门延时时间

notif1 #(10,20,30) U1(out,in,clk);	//上升延时:10,下降延时:20,截止延时:30
									//不定态延时:三者中的最小,10
发布了19 篇原创文章 · 获赞 0 · 访问量 294

猜你喜欢

转载自blog.csdn.net/m0_46493315/article/details/105041650