verilog学习笔记(3)_task/case小例子及其tb

module ex_case

`timescale lns/1ns

module ex_case(
		input wire rst_n,
		input wire sclk,
		output reg [7:0] o_dv,
		output reg [7:0] o_data,
		//数据输入
		input wire [9:0] i_data,
		input wire [7:0] i_addr
);
//
reg [2:0] cnt_7;
	
//不同功能的寄存器分开always来写,这样代码的可维护性强,可读性强
always@(posedge sclk or negedge rst_n)
	if(rst_n == 1'b0)
		cnt_7 <= 3'd0;
	else
		cnt_7 <= cnt_7 + 1'b1;
/*	
//时序逻辑
always@(posedge sclk or negedge rst_n)
	if(rst_n == 1'b0)
	begin
		o_data <= 8'd0;
	end
	else
	begin
		case(cnt_7)
			3'd0:
			begin
				o_data <= 3'd7;//给寄存器 非阻塞赋值 当cnt_7等于3'd0执行此条语句
				o_dv <= 1'b1;
			end
			3'd1:
			begin
				o_data <= 3'd0;
				o_dv <= 1'b0;
			end
			3'd2:
			begin
				0_data <= 3'd5;
				o_dv <= 1'b1;
			end
			default:
			begin
				o_data <= 3'd0;
				o_dv <= 1'b0;
			end
		endcase
	end
*/

//组合逻辑
//消除锁存器
//1.消除敏感列表,case条件,在赋值语句的右边变量
//2.所有条件分支写全
always@(cnt_7)

		case(cnt_7)
			3'd0:
			begin
				o_data <= 3'd7;//给寄存器 非阻塞赋值 当cnt_7等于3'd0执行此条语句
				o_dv <= 1'b1;
			end
			
			
			3'd1:
			begin
				o_data <= 3'd0;
				o_dv <= 1'b0;
			end
			3'd2:
			begin
				o_data <= 3'd5;
				o_dv <= 1'b1;
			end
			
			
			default:
			begin
				o_data <= 3'd0;
				o_dv <= 1'b0;
			end
		endcase

endmodule

module tb_ex_case

`timescale lns/1ns

module tb_ex_case;
reg sclk,rst_n;
wire [7:0] data;
wire dv;
reg [7:0] i_addr;
reg [9:0] i_data;

initial begin
	sclk = 0;
	rst_n = 0;
	#200
	rst_n = 1;
end

initial 
begin
    i_data = 0;
    i_addr = 0;
	#500
	send_data(255);
end

always #10 sclk <= ~sclk;//周期20ns的时钟

ex_case ex_case_inst(
		.rst_n	(rst_n),
		.sclk	(sclk),
		.o_dv	(dv),
		.o_data	(data),
		.i_data	(i_data),
		.i_addr	(i_addr)
);


task send_data(len);//任务的声明
	integer len,i;//变量声明区
	begin//必须加begin和end
		for(i = 0;i <= len;i = i + 1)//循环语句
		begin
			@(posedge sclk);//上升沿时进行赋值 按照节拍的动作来
			i_addr <= i[7:0];//这里阻塞赋值 非阻塞赋值都可以
			i_data <= i[7:0];
		end
			i_addr <= 0;
			i_data <= 0;
		
	end
endtask

endmodule

原文地址:https://www.cnblogs.com/maskerk/p/7372494.html