逻辑仿真和时序仿真

1. 组合逻辑的测试模块

  • 最简单的测试模块编写方式: 步进式信号。所谓步进式信号,即按时间顺序列出所有可能的输入信号组合,用于观察输出的情况是否满足要求。这种写法的好处是不需要太多的思考,非常适合输入端口较少的逻辑组合电路,。例如参考如下的设计模块,这是一个带有使能端的 3-8 译码器,在,en 为高电平时停止工作,输出全唯 1, 在 en 为 0 时正常工作,若无输入也输出全唯 1。ex 信号是为了区分输入全为 1 时的电路的工作状态而特意保留的扩展输出位。

3-8译码器

  • 设计模块
module decoder3x8(din, en, dout, ex);
input [2:0] din;
input en;
output [7:0] dout;
output ex;
reg [7:0] dout;
reg ex;

always @(din or en)
if(en)
	begin
		dout=8'b1111_1111;
		ex=1'b1;
	end
else
	begin
		case(din)
		3'b000: begin
				 dout=8'b1111_1110;
				 ex=1'b0;
				end
		3'b001: begin
				 dout=8'b1111_1101;
				 ex=1'b0;
				end
		3'b010: begin
				 dout=8'b1111_1011;
				 ex=1'b0;
				end
		3'b011: begin
				 dout=8'b1111_0111;
				 ex=1'b0;
				end
		3'b100: begin
				 dout=8'b1110_1111;
				 ex=1'b0;
				end
		3'b101: begin
				 dout=8'b1101_1111;
				 ex=1'b0;
				end
		3'b110: begin
				 dout=8'b1011_1111;
				 ex=1'b0;
				end
		3'b111: begin
				 dout=8'b0111_1111;
				 ex=1'b0;
				end
		default:begin
				 dout=8'b1111_1111;
				 ex=1'b0;
				end
		endcase
	end
	
endmodule

该设计模块一共有四位的信号输入(一个 3 位输入加一个 1 位输入), 非常适合用步进试的信号方式。

  • 由此编写的测试模块
module tbdecoder;
reg [2:0] din;
reg en;
wire [7:0] dout;
wire ex;

initial
begin
	#10 en=0;din=3'b000;
	#10 en=0;din=3'b001;
	#10 en=0;din=3'b010;
	#10 en=0;din=3'b011;
	#10 en=0;din=3'b100;
	#10 en=0;din=3'b101;
	#10 en=0;din=3'b110;
	#10 en=0;din=3'b111;
	#10 en=0;din=3'b1x1;
	#10 en=0;din=3'b000;
	#10 en=0;din=3'b001;
	#10 en=0;din=3'b010;
	#10 en=0;din=3'b011;
	#10 en=0;din=3'b100;
	#10 en=0;din=3'b101;
	#10 en=0;din=3'b110;
	#10 en=0;din=3'b111;
	#10 $stop;
end

decoder3x8 idecoder(din, en, dout, ex);

endmodule
	

波形图

  • 功能仿真波形图

使用这种信号生成方式完成一些小的测试模块是很方便的,它与随机信号的最大不同在于信号的可控性,本例中信号的产生都是设计者已知的,不会出现未知情况,而随机信号则均为未知,每次都需要临时分析。但是当设计的输入信号位数较多时,采用这种方法来指定测试信号就显得比较麻烦,用随机数就简单许多。

2. 时序逻辑的测试模块

如果待测试的设计文件是一个时序电路,由于需要时钟信号和复位信号,以及一些模块间交互信号,测试模块的编写就变得复杂一些,这是可以使用@来进行信号定位,同时使用一些任务来帮助设计者判断结果。

4位的并串转换模块

  • 设计模块
module p2s(data_in, clock, reset, load, data_out, done);
input [3:0] data_in;
input clock, reset, load;
output data_out;
output done;
reg done;

reg [3:0] temp;
reg [3:0] cnt;

always@(posedge clock or posedge reset)
begin
	if(reset)
	begin
		temp<=0;
		cnt<=0;
		done<=1;
	end
	else if(load)
	begin
		temp<=data_in;
		cnt<=0;
		done<=0;
	end
	else if(cnt==3)
	begin
		temp<={temp[2:0],1'b0};
		cnt<=0;
		done<=1;
	end
	else
	begin
		temp <= {temp[2:0],1'b0};
		cnt<=cnt+1;
		done<=0;
	end
end

assign data_out=(done==1)?1'bz:temp[3];

endmodule

该设计模块的基本功能就是在 load 为 1 时接收一个 4 位的数据,在接下来的 4 个周期里依次输出这4位信息,输出结束后 done 信号变为 1, 表示一次转换完毕, 可以继续接收下一个数据。 如果 done 信号位 0 则表示转换还在进行,不能输入数据。

  • 为此设计模块编写测试模块
module tbp2s;
reg [3:0] data_in;
reg clock,reset,load;
wire data_out;
wire done;

initial
begin
	reset=1;
	#15 reset=0;
end

initial clock=1;
always #5 clock=~clock;

always @(done)
begin
	if(done==1)
	begin
		data_in=$random%16;
		load=1;
	end
	else
	begin
		load=0;
	end
end

always @(posedge clock)
if(load==1)
	begin:dis
		integer i;
		i=3;
		repeat(4)
		begin	
			@(posedge clock)
			if(data_out==data_in[i])
				$display("Output Right!");
			else
				$display("Bad Output!data_out= %b ,but data_in[%d]= %b",data_out,i,data_in[i]);
			i=i-1;
		end
	end
	
p2s ip2s(data_in,clock,reset,load,data_out,done);

endmodule

波形图

运行仿真后可得到波形图,从图中可以看到,data_out 产生的 4 位数出就是 data_in 中的数据。同事还会有文字提示信息如下

在这里插入图片描述

前三个错误信息的原因是 i 的定位问题, 由于 reset 产生复位信号之后对 i 产生了影响,在该工作周期结束后即可恢复正常。

3.仿真视频

地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值