FPGA学习——Modelsim仿真的小脚本run.do和force语句强制赋值

前言

有个大神给我说,FPGA视频看完之后,不要写简单的代码,就有什么大项目,做一个就够了。
但是,我还是想练一练。于是就写了一个简单的状态机,并且发现了一些有趣东西:run.do脚本force强制赋值语句

run.do脚本文件

这个脚本文件,通过modelsim在run.do脚本文件夹中新建一个工程,直接在运行窗口输入命令:do run.do,直接生成如下的波形图,简化了好多操作。
在这里插入图片描述
run.do文件
在这里插入图片描述

  • 上图中的8-18行可以直接删去,剩下的作为最最简单的模板文件。为了大家方便使用,可以复制粘贴下面的代码
quit -sim

vlib work
vlog	./../testbench/fsm_tb.v
vlog 	./../rtl/*.v

vsim -voptargs=+acc work.fsm_tb

virtual type {
{01 IDLE}
{02 WRITE}
{04 READ}
{08 CHECK}
{10 ERROR}
} virtual_new_signal

virtual function {(virtual_new_signal)fsm_tb/fsm_inst/state} new_state
add wave -colo red fsm_inst/new_state
add wave fsm_inst/*

run 100us

force强制改变波形数据

在仿真测试文件中,可以使用force语句强制改变波形数据,
在这里插入图片描述
这段代码的作用就是改变波形文件中的数据,从而测试某一功能,如下图所示:将red_cnt的值从0变为2,导致red_cnt和write_cnt的数不相等,进入ERROR状态。
在这里插入图片描述

附件(前面提到的设计文件)

在这里插入图片描述

fsm.v

module fsm(
	Clk,
	Rst_n,
	write_start,
	error_flag
);

	input Clk	;
   input Rst_n	;
   input write_start	;
   output error_flag;
	reg [4:0] state;
	
	assign error_flag = state[4];
	
	localparam 	IDLE 	= 5'b00001,
					WRITE	= 5'b00010,
					READ	= 5'b00100,
					CHECK = 5'b01000,
					ERROR = 5'b10000;
	
	reg [9:0] write_cnt;
	reg write_end;
	reg [9:0] read_cnt;
	reg read_end;
		
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		state <= IDLE;
	else case(state)
		IDLE:
			if(write_start == 1'b1)
				state <= WRITE;
		WRITE:
			if(write_end == 1'b1)
				state <= READ;
		READ:
			if(read_end == 1)
				state <= CHECK;
		CHECK:
			if((|write_cnt)==1'b0 && (|read_cnt)==1'b0)
				state <= IDLE;
			else
				state <= ERROR;
		ERROR:	
			state <= ERROR;
		default:state <= IDLE;
	endcase
	
	//写的计数器
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		write_cnt <= 10'b0;
	else if(state == WRITE)
		write_cnt <= write_cnt + 1'b1;
	else 
		write_cnt <= 10'b0; 
		
	//写的状态	
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		write_end <= 1'b0;
	else if(write_cnt == 10'd1022)
		write_end <= 1'b1;
	else 
		write_end <= 1'b0;
	
	//读的计数器
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		read_cnt <= 10'b0;
	else if(state == READ)
		read_cnt <= read_cnt + 1'b1;
	else 
		read_cnt <= 10'b0; 
		
	//读的状态	
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		read_end <= 1'b0;
	else if(read_cnt == 10'd1022)
		read_end <= 1'b1;
	else 
		read_end <= 1'b0;
endmodule

fsm_tb.v

`timescale 1ns/1ns
`define clock_period 20
module fsm_tb;

	reg Clk,Rst_n,write_start;
	wire error_flag;

	fsm fsm_inst(
		Clk,
		Rst_n,
		write_start,
		error_flag
	);

	initial Clk = 1'b1;
	always #(`clock_period/2) Clk = ~Clk;
	
	initial begin
		Rst_n = 1'b0;
		#100
		Rst_n = 1'b1;
	end
	
	initial begin
		write_start = 1'b0;
		#300
		write_start = 1'b1;
		#30 
		write_start = 1'b0;
	end
	
//force强制赋值语句
initial begin
# 41280
force fsm_inst.read_cnt = 10'd2;
end	
	//initial #100_000 $stop;

endmodule

经验之谈

  1. 学会用run.do和makefile等类似的脚本文件
  2. modelsim中仿真时,要将参数定义放在那面,否则会报错
  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰之行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值