quartus新建工程流程

一、新建工程

1、建立工程管理文件夹;

2、双击quartus,打开软件;

3、选择新建工程→选择工程文件夹→工程名→不 add files→选择器件→选择仿真工具;

新建工程
步骤1
步骤2:工程路径、文件名
步骤3:不添加文件,直接next
步骤4:选择器件
步骤5:选择仿真工具
新建工程完毕

4、至此新建工程完毕,可以进行设计输入;

二、quartus与notepad++的关联

1、tools→options;

步骤1

2、点击Preferred Text Editor,选择notepad++,并且关联到notepad++的安装路径;

步骤2

三、分析与综合 

        代码编写完毕后,需要对语法进行检查;

四、打开RTL视图

         方法1:双击左侧

方法1:双击RTL Viewer

        方法2:工具栏 Tools → Netlist Viewers →  RTL Viewer;

方法2:工具栏 Tools → Netlist Viewers →  RTL Viewer
RTL视图

 五、modelsim仿真

        代码编写完成后,就可以进行仿真操作,验证代码的逻辑性;

5.1 quartus与modelsim联合仿真

步骤1 :选择仿真软件;

步骤1-1
步骤1-2

其实步骤1在新建工程时,已经选择过了;

 步骤2:设置modelsim软件路径;

步骤2-1

步骤2-2

 步骤3:添加vt文件

代码编写好后,需要将 tb_xxx.v 文件添加到工程中。点击“File”切换到文件模式,在该模式下可以看到所有属于该工程下的文件。
 

添加tb文件

添加tb文件

 步骤4:仿真设置

仿真设置1
仿真设置2

 步骤5:NativeLink 的设置

步骤1

步骤2
步骤3

 步骤3中,

        ①

        ②是Testbench 顶层的名字;

        ③是设置打开 ModelSim时波形运行多久后停止,一般设置1us;

        ④选择 sim 文件夹下的 tb_led.v 文件;
 

 步骤6:打开 ModelSim 观察波形

5.2 testbench语法

通常,编写测试文件的过程如下:

• 产生模拟激励(波形);
• 将产生的激励加入到被测试模块中并观察其响应;
• 将输出响应与期望值相比较。

1、Testbench是一个测试文件,取名就在模块前加 tb_xxx;模块的实例化,是在Testbench里的代码,取名是u_xxx;

2、在sim文件夹下,编写 tb_xxx.v 文件;

3、tb_xxx.v文件写完后,可运行分析与综合,进行代码语法检查;

 5.2.1 testbench结构

通常,一个完整的测试文件其结构为

`timescale 仿真单位/仿真精度

module Test_bench();//通常无输入无输出

信号或变量声明定义
逻辑设计中输入对应 reg 型
逻辑设计中输出对应 wire 型
使用 initial 或 always 语句产生激励
例化待测试模块
监控和比较输出响应

endmodule

 声明仿真的单位和精度

 

5.2.2 时钟激励设计

/*----------------------------------------------------------------
时钟激励产生方法一: 50%占空比时钟
----------------------------------------------------------------*/
parameter ClockPeriod=10;
initial
	begin
		clk_i=0;
		forever
		#(ClockPeriod/2) clk_i=~clk_i;
	
	end
/*----------------------------------------------------------------
时钟激励产生方法二: 50%占空比时钟
----------------------------------------------------------------*/
initial
	begin
		clk_i=0;
		always #(ClockPeriod/2) clk_i=~clk_i;
	end
/*----------------------------------------------------------------
时钟激励产生方法四:产生固定数量的时钟脉冲
----------------------------------------------------------------*/
initial
	begin
		clk_i=0;
		repeat(6)
		#(ClockPeriod/2) clk_i=~clk_i;
	end
/*----------------------------------------------------------------
时钟激励产生方法五:产生非占空比为 50%的时钟
----------------------------------------------------------------*/
initial
	begin
		clk_i=0;
		forever
				begin
					#((ClockPeriod/2)-2) clk_i=0;
					#((ClockPeriod/2)+2) clk_i=1;
				end
	end

5.2.3 复位信号设计

/*----------------------------------------------------------------
复位信号产生方法一:异步复位
----------------------------------------------------------------*/
initial
	begin
		rst_n_i=1;
		#100;
		rst_n_i=0;
		#100;
		rst_n_i=1;
	end
/*----------------------------------------------------------------
复位信号产生方法二:同步复位
----------------------------------------------------------------*/
initial
	begin
		rst_n_i=1;
		@(negedge clk_i)
		rst_n_i=0;
		#100; //固定时间复位
		repeat(10) @(negedge clk_i); //固定周期数复位
		@(negedge clk_i)
		rst_n_i=1;
	end
/*----------------------------------------------------------------
复位信号产生方法三:复位任务封装
----------------------------------------------------------------*/
task reset;
	input [31:0] reset_time; //复位时间可调,输入复位时间
	RST_ING=0; //复位方式可调,低电平或高电平
		begin
			rst_n=RST_ING; //复位中
			#reset_time; //复位时间
			rst_n_i=~RST_ING; //撤销复位,复位结束
		end
endtask

 5.2.4 双向信号设计

/*----------------------------------------------------------------
双向信号描述一: inout 在 testbench 中定义为 wire 型变量
----------------------------------------------------------------*/

//为双向端口设置中间变量 inout_reg 作为 inout 的输出寄存,其中 inout 变
//量定义为 wire 型,使用输出使能控制传输方向

//inout bir_port;
wire bir_port;
reg bir_port_reg;
reg bi_port_oe;
assign bi_port=bi_port_oe ? bir_port_reg : 1'bz;

/*----------------------------------------------------------------
双向信号描述二:强制 force
----------------------------------------------------------------*/

//当双向端口作为输出口时,不需要对其进行初始化,而只需开通三态门
//当双向端口作为输入时,只需要对其初始化并关闭三态门,初始化赋值需
//使用 wire 型数据,通过 force 命令来对双向端口进行输入赋值
//assign dinout=(!en) din :16'hz; 完成双向赋值

initial
	begin
		force dinout=20;
		#200
		force dinout=dinout-1;
	end

5.2.5特殊信号设计 


/*----------------------------------------------------------------
特殊激励信号产生描述一:输入信号任务封装
----------------------------------------------------------------*/

task i_data;
input [7:0] dut_data;
begin
	@(posedge data_en); send_data=0;
	@(posedge data_en); send_data=dut_data[0];
	@(posedge data_en); send_data=dut_data[1];
	@(posedge data_en); send_data=dut_data[2];
	@(posedge data_en); send_data=dut_data[3];
	@(posedge data_en); send_data=dut_data[4];
	@(posedge data_en); send_data=dut_data[5];
	@(posedge data_en); send_data=dut_data[6];
	@(posedge data_en); send_data=dut_data[7];
	@(posedge data_en); send_data=1;
	#100;
end
endtask

//调用方法: i_data(8'hXX);
/*----------------------------------------------------------------
特殊激励信号产生描述二:多输入信号任务封装
----------------------------------------------------------------*/

task more_input;
	input [7:0] a;
	input [7:0] b;
	input [31:0] times;
	output [8:0] c;
		begin
			repeat(times) //等待 times 个时钟上升沿
			@(posedge clk_i)
			c=a+b; //时钟上升沿 a, b 相加
		end
endtask

//调用方法: more_input(x,y,t,z); //按声明顺序
/*----------------------------------------------------------------
特殊激励信号产生描述三:输入信号产生,一次 SRAM 写信号产生
----------------------------------------------------------------*/

initial
	begin
		cs_n=1; //片选无效
		wr_n=1; //写使能无效
		rd_n=1; //读使能无效
		addr=8'hxx; //地址无效
		data=8'hzz; //数据无效
		#100;
		cs_n=0; //片选有效
		wr_n=0; //写使能有效
		addr=8'hF1; //写入地址
		data=8'h2C; //写入数据
		#100;
		cs_n=1;
		wr_n=1;
		#10;
		addr=8'hxx;
		data=8'hzz;
	end

/*----------------------------------------------------------------
Testbench 中@与 wait
----------------------------------------------------------------*/

//@使用沿触发
//wait 语句都是使用电平触发
initial
	begin
		start=1'b1;
		wait(en=1'b1);
		#10;
		start=1'b0;
	end

 5.2.6repeat ,wait函数

//==========================================
//==    repeat重复执行
//==========================================
initial begin
    start = 1;
    repeat(5) @(posedge clk)    //等待5个时钟上升沿
    start = 0;
end

initial begin
	repeat(10)begin
		...//执行10次
	end 
end

//===========================================
//==    wait为电平触发
//==========================================
initial begin
    start = 1;
    wait(en);                     //等待en==1
    start = 0;
end

 5.2.7 随机数的产生


$random         //产生随机数
$random % n     //产生范围 {-n,n} 的随机数
{$random} % n   //产生范围 { 0,n} 的随机数

 5.2.8 文本输入输出


reg [a:0] data_mem [0:b];  //定义位宽为(a+1)深度为(b+1)的存储器
$readmemb/$readmemh("<读入文件名>",<存储器名>);
$readmemb/$readmemh("<读入文件名>",<存储器名>,<起始地址>);
$readmemb/$readmemh("<读入文件名>",<存储器名>,<起始地址>,<结束地址>);

$readmemb
/*------------------------------------------------------------------------*\
  读取二进制数据,读取文件内容只能包含:空白位置,注释行,二进制数
  数据中不能包含位宽说明和格式说明,每个数字必须是二进制数字。
\*------------------------------------------------------------------------*/

$readmemh
/*------------------------------------------------------------------------*\
  读取十六进制数据,读取文件内容只能包含:空白位置,注释行,十六进制数
  数据中不能包含位宽说明和格式说明,每个数字必须是十六进制数字.
\*------------------------------------------------------------------------*/
//==========================================================================
//==    输出txt文件
//==========================================================================
integer fp_write;                                  //定义
	initial  begin
		begin
			fp_write = $fopen("output.txt");  //打开输出文件
			begin
				$fwrite(fp_write, "\n%h", output_data); //写入数据16进制
				#(`clk_period);
			end
		end
		$fclose(fp_write);   //关闭文件,不可少
end


 5.2.9 文本输入输出


reg [a:0] data_mem [0:b];  //定义位宽为(a+1)深度为(b+1)的存储器
$readmemb/$readmemh("<读入文件名>",<存储器名>);
$readmemb/$readmemh("<读入文件名>",<存储器名>,<起始地址>);
$readmemb/$readmemh("<读入文件名>",<存储器名>,<起始地址>,<结束地址>);

$readmemb
/*------------------------------------------------------------------------*\
  读取二进制数据,读取文件内容只能包含:空白位置,注释行,二进制数
  数据中不能包含位宽说明和格式说明,每个数字必须是二进制数字。
\*------------------------------------------------------------------------*/

$readmemh
/*------------------------------------------------------------------------*\
  读取十六进制数据,读取文件内容只能包含:空白位置,注释行,十六进制数
  数据中不能包含位宽说明和格式说明,每个数字必须是十六进制数字.
\*------------------------------------------------------------------------*/
//==========================================================================
//==    输出txt文件
//==========================================================================
integer fp_write;                                  //定义
	initial  begin
		begin
			fp_write = $fopen("output.txt");  //打开输出文件
			begin
				$fwrite(fp_write, "\n%h", output_data); //写入数据16进制
				#(`clk_period);
			end
		end
		$fclose(fp_write);   //关闭文件,不可少
end


 5.2.10 打印信息

$monitor      //仿真打印输出,打印出仿真过程中的变量,使其终端显示
/*------------------------------------------------------------------------*\
  $monitor($time,,,"clk=%d reset=%d out=%d",clk,reset,out);
\*------------------------------------------------------------------------*/

$display      //终端打印字符串,显示仿真结果等
/*------------------------------------------------------------------------*\
  $display(” Simulation start ! ");
  $display(” At time %t,input is %b%b%b,output is %b",$time,a,b,en,z);
\*------------------------------------------------------------------------*/

$time         //返回 64 位整型时间

$stime        //返回 32 位整型时间

$realtime     //实行实时模拟时间

5.2.11 testbench总体代码结构

`timescale 1ns/1ps  	//时间精度
`define clk_perilod 20	//时钟周期可变

module test_file_tb;

//==================<端口>==================================================
reg                         clk                 ; //时钟,50Mhz
reg                         rst_n               ; //复位,低电平有效
reg  [XX:0]                 in                  ; //
wire [XX:0]                 out                 ; //

//--------------------------------------------------------------------------
//--    模块例化
//--------------------------------------------------------------------------
my_design u_my_design
(
    .clk                    (clk                ),
    .rst_n                  (rst_n              ),
    .in                     (in                 ),
    .out                    (out                )
);

//----------------------------------------------------------------------
//--    时钟信号和复位信号
//----------------------------------------------------------------------
initial begin
    clk = 0;
    forever
        #(`Clock/2) clk = ~clk;
end

initial begin
    rst_n = 0; #(`Clock*20+1);
    rst_n = 1;
end

//----------------------------------------------------------------------
//--    设计输入信号
//----------------------------------------------------------------------
initial begin
    in = 0;
    #(`Clock*20+2); //初始化完成

    $stop;
end

endmodule在这里插入代码片

六、管脚分配

6.1 管脚分配

 引脚分配完成后, 直接关闭引脚分配窗口, 软件会在工程所在位置生成一个.qsf 文件用来存放引脚信息。 当然我们也可以生成一个 TCL 文件,这样下次在使用的时候就可以直接运行 TCL 文件自动分配引脚。

 6.2 清除管脚分配

1

2

 再次打开Pin Planner,我们可以看到引脚绑定信息已经被清除了。

6.3 生成TCL文件

生成TCL文件

点击状态栏的 File,然后点击 Export。

 然后弹出下面的界面, 这里我们将生成的 TCL 文件放置到 doc 文件夹下,选择保存类型*.tcl。然后点击“ Export”。

 此时 TCL 文件就已经生成。

6.4 添加TCL文件

6.4.1 18.0之后版本

步骤1

步骤2

步骤3

6.4.2 18.0之前版本

方法一:使用TCL绑定管脚

        a.回到工程界面,单击View->Utility Windows->Tcl Console,然后复制导出的tcl文件中的所有内容,然后粘贴到Tcl Console窗口,完成引脚绑定。

方法二:使用 .cvs文件绑定管脚

        a. 在pin planer界面,导出tcl文件的同时,也导出 .cvs文件;

        b. 在工程界面,点击Assignments->Import Assignments,然后点击右侧的三个点,找到我们第一次导出的.csv文件,选中后选择打开,然后点击OK;

七、编译工程

分配完引脚之后, 需要对整个工程进行一次全编译,

八、下载工程

编译完成后,就可以下载程序,

首先将 USB Blaster 下载器一端连接电脑, 另一端与JTAG 接口相连接;

然后连接电源线,并打开电源开关。

打开程序下载操作

程序下载界面

 点击【 Hardware Setup...】按钮,选择“ USB-Blaster”,

选中 USB-Blaster

选择.sof 文件

程序下载界面
程序下载完成界面

九、固化

 如果我们想要程序断电不丢失的话,就必须将程序保存在片外 Flash 中, Flash 的引脚是和 FPGA 固定的引脚相连接, FPGA 会在上电后自动读取 Flash 中存储的程序,这个过程不需要我们编写驱动代码和人为干预,只需要通过 JTAG 下载jic 文件即可。

需要注意的是, jic 文件不是软件自动生成的, 而是需要我们手动的将 sof 文件转换成 jic 文件。

 9.1 jic文件生成

Quartus 软件界面

sof 文件转换 jic 文件窗口

①文件类型,jic;

②flash型号;

③输出文件名;

④⑤选择fpga型号;

添加 sof 操作页面

最终完成设置

9.2 固化

回到下载界面,删除sof文件;

删除 sof 文件

 加载jic文件;

添加 jic 文件

 在 Program/Configure 选项打勾,开始下载;

程序下载界面

 9.3 擦除

如果需要擦除 Flash 中的程序的话, 可以通过勾选【 Erase】下面的方框来擦除程序。

需要注意的是,如果已经勾选了【 Program/Configure】方框,是无法勾选【 Erase】方框的,所以先取消勾选

【 Program/Configure】,然后再勾选【 Erase】,如下图所示。

取消勾选【 Program/Configure】
以下是使用Quartus 18.0软件编写四选一数据选择器的步骤: 1. 打开Quartus 18.0软件,创建一个新工程。 2. 在新工程中创建一个新的VHDL文件。 3. 在VHDL文件中编写四选一数据选择器的代码,例如: ```vhdl entity mux4to1 is port (a : in std_logic_vector(3 downto 0); s : in std_logic_vector(1 downto 0); y : out std_logic); end mux4to1; architecture Behavioral of mux4to1 is begin y <= a(to_integer(unsigned(s))); end Behavioral; ``` 4. 保存VHDL文件并编译工程。 5. 在编译成功后,打开ModelSim仿真器。 6. 在ModelSim仿真器中创建一个新的仿真工程。 7. 将编译后的文件添加到仿真工程中。 8. 在仿真工程中添加一个测试文件,例如: ```vhdl library ieee; use ieee.std_logic_1164.all; entity mux4to1_tb is end mux4to1_tb; architecture Behavioral of mux4to1_tb is component mux4to1 is port (a : in std_logic_vector(3 downto 0); s : in std_logic_vector(1 downto 0); y : out std_logic); end component; signal a : std_logic_vector(3 downto 0) := "0000"; signal s : std_logic_vector(1 downto 0) := "00"; signal y : std_logic; begin uut : mux4to1 port map (a => a, s => s, y => y); process begin s <= "00"; a <= "0001"; wait for 10 ns; assert (y = '0') report "Error: y /= 0" severity error; s <= "01"; a <= "0010"; wait for 10 ns; assert (y = '0') report "Error: y /= 0" severity error; s <= "10"; a <= "0100"; wait for 10 ns; assert (y = '0') report "Error: y /= 0" severity error; s <= "11"; a <= "1000"; wait for 10 ns; assert (y = '1') report "Error: y /= 1" severity error; wait; end process; end Behavioral; ``` 9. 运行仿真工程,查看仿真结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值