FPGA 学习之路(四) modesim仿真方法

1)首先新建一个文件夹,把你需要仿真的设计文本和仿真文本全部放在同一个文件夹下面,注意,文件夹路径不能包含中文。

FPGA 学习之路(四) modesim仿真方法_第1张图片

2)打开modelsim软件,选择“File > new >project,新建一个工程,工程保存在上述所建的文件夹中,点击ok。

FPGA 学习之路(四) modesim仿真方法_第2张图片

3)点击add existing file,选择所要仿真的文件。

FPGA 学习之路(四) modesim仿真方法_第3张图片FPGA 学习之路(四) modesim仿真方法_第4张图片

4)点击编译进行文本编译找错。

FPGA 学习之路(四) modesim仿真方法_第5张图片

5)编译无错后,选择simulate>start simulate,进行仿真。

FPGA 学习之路(四) modesim仿真方法_第6张图片

6)选择work中文件名为xx-tb的文件(只需仿真顶层文件,其他文件不用选择)

FPGA 学习之路(四) modesim仿真方法_第7张图片

7)进入仿真界面。点击sim中顶层文件名,右击选择 Add Wave将所要观测的信号添加到Wave窗口,为便于查找观察信号点击Wave窗口左下角,如图;

FPGA 学习之路(四) modesim仿真方法_第8张图片

FPGA 学习之路(四) modesim仿真方法_第9张图片

8)在Transcript窗口输入  run 5000ns,仿真开始运行,运行5000ns。(5000ns为大致所需的仿真时间)若用run-all配置低的电脑容易卡死。

FPGA 学习之路(四) modesim仿真方法_第10张图片

9)为便于观测data中数据,点击data右击选择hex模式。

FPGA 学习之路(四) modesim仿真方法_第11张图片

10)仿真方法

用于精确寻找出发,有效的对代码进行分析。

Find prvious transition(寻找前一个传输)

Find next transition(寻找后一个传输)

    上下边沿寻找。

11)若需改动Testbench代码,在不退出Simulation的前提下,右击文件窗口中,project中需改动的文本文档选择Edit进行保存改动编译。如下图方式可方便改动和编译。(有时候会遇见.v文件打开时不用modesim自带的编辑软件打开,这是笔者采用的一种方法是选中文件,点击菜单栏project中的edit打开)也可用其他编程软件直接打开修改。

FPGA 学习之路(四) modesim仿真方法_第12张图片

12)编译后,点击modesim右上方,如下图,进行复位,然后重新点击simulate>start simulate,进行仿真进行重新仿真

FPGA 学习之路(四) modesim仿真方法_第13张图片

13)Testbench如下(内含语法):

 /***************************************************************************
一个testbench要包含时钟信号发生器,模块的例化,系统初始化,生成系统激励;
本例还要产生一个模拟总线时序。
	//mcu spi interface
	input			spi_cs,		//Chip select enable, default:L
	input			spi_sck	,	//Data transfer clock
	input			spi_mosi,	//Master output and slave input
	input			spi_miso,	//Master input and slave output	
	
***************************************************************************/

`timescale 1ns/1ns
module MCU2FPGA_SPI_TB;
//------------------------------------------
//clock generate module
reg	clk;               //所要仿真的接口信号都要设置成reg类型
reg	rst_n;
parameter PERIOD = 10;	//时钟周期我为10ns

initial	               //inital 执行一次
begin
	clk = 0;
	forever	#(PERIOD/2)	 //每半个时钟周期翻转一次
	clk = ~clk;
end


task task_reset;      //类似于子函数,调用方式为task_reset(接口信号)
begin
	rst_n = 0;
	repeat(2) @(negedge clk);     //重复两个时钟下降沿执行下一步
	rst_n = 1;
end
endtask                         //任务函数task要有endtask
wire	clk_ref = clk;
wire	sys_rst_n = rst_n;

//----------------------------------------------
//the target component instantiation
reg	spi_cs;                      //接口信号
reg	spi_sck;
reg	spi_mosi;
//-----------------------------------
wire		rxd_flag;
wire	[7:0]	rxd_data;
spi_receiver	u_spi_receiver         
(
	//global clock
	.clk			(clk_ref),			//100MHz clock
	.rst_n			(sys_rst_n),		//global reset
	
	//mcu spi interface
	.spi_cs			(spi_cs),		//Chip select enable, default:L
	.spi_sck		(spi_sck),		//Data transfer clock
	.spi_mosi		(spi_mosi),		//Master output and slave input
//	.spi_miso		(spi_miso),		//Master input and slave output

	//user interface
	.rxd_flag		(rxd_flag),
	.rxd_data		(rxd_data)
);

//---------------------------------------
wire	txd_flag;
spi_transfer u_spi_transfer
(
	//global clock
	.clk			(clk_ref),			//100MHz clock
	.rst_n			(sys_rst_n),		//global reset
	
	//mcu spi interface
	.spi_cs			(spi_cs),		//Chip select enable, default:L
	.spi_sck		(spi_sck),		//Data transfer clock
//	.spi_mosi		(spi_mosi),		//Master output and slave input
	.spi_miso		(spi_miso),		//Master input and slave output

	//user interface		
	.txd_en			(rxd_flag),
	.txd_data		(rxd_data),
	.txd_flag		(txd_flag)		
);


//---------------------------------------------
//mcu spi data transfer
task task_mcu_spi_txd;            //spi总线时序
input	[7:0] mcu_data;
begin
	spi_cs = 0; #100;
	spi_sck = 0;	spi_mosi = mcu_data[7];	 #100;	spi_sck = 1; #100;	//Bit[7]
	spi_sck = 0;	spi_mosi = mcu_data[6];	 #100;	spi_sck = 1; #100;	//Bit[6]
	spi_sck = 0;	spi_mosi = mcu_data[5];	 #100;	spi_sck = 1; #100;	//Bit[5]
	spi_sck = 0;	spi_mosi = mcu_data[4];	 #100;	spi_sck = 1; #100;	//Bit[4]
	spi_sck = 0;	spi_mosi = mcu_data[3];	 #100;	spi_sck = 1; #100;	//Bit[3]
	spi_sck = 0;	spi_mosi = mcu_data[2];	 #100;	spi_sck = 1; #100;	//Bit[2]
	spi_sck = 0;	spi_mosi = mcu_data[1];	 #100;	spi_sck = 1; #100;	//Bit[1]                                                                                                                         
	spi_sck = 0;	spi_mosi = mcu_data[0];	 #100;	spi_sck = 1; #100;	//Bit[0]
	spi_cs = 1; spi_sck = 0; #100;
end
endtask


//---------------------------------------------
//system initialization
task task_sysinit;           //spi总线时序chushihua
begin
	spi_cs = 1;
	spi_sck = 0;
	spi_mosi = 0;
end
endtask


//---------------------------------------
//testbench of the RTL
initial                    //生成系统激励
begin                      //多个inital文件可以并行执行
	task_sysinit;
	task_reset;
	
	#100;	
	task_mcu_spi_txd(8'h95);
	
	#100;	
	task_mcu_spi_txd(8'hbe);
	
	#100;	
	task_mcu_spi_txd(8'hab);	

	

end

endmodule




你可能感兴趣的:(FPGA)