如何使用quartus创建项目并与Modelsim联合仿真

我所使用的版本是Quartus II 13.1及Modelsim SE-64 10.4

一、创建新工程

1.点击New Project Wizard创建

2.第一行是工程文件存放位置,第二行是工程的名称,第三行默认和第二行一样为顶层模块

3.点击next,next,然后在simulation处选择仿真方式及编写程序使用的语言

4.然后点击 next,最后finish便完成了一个工程的创建

二、代码编写

1.左上角选择新建file,选择需要的语言文件

2.输入你写的代码,然后ctrl+s保存文件,注意保存时的文件名需要与你的模块名一致,且至少需要有一个模块名为上述提及的顶层模块,我这里的是“Instruction”

3.编写完成之后,点击下述图片的三角进行编译

 4.编译正常后我们便可以开始下一步编写测试平台

三、与Modelsim进行联合仿真

1.点击Processing->Start->Start test bench template writer,生成测试平台文件

2.找到.vt文件,进行测试代码的编写

3.接下来设置仿真,点击Tools->Options->EDA Tools Options,选择Modelsim安装目录下的Win64或Win32,若显示找不到modelsim的可以试试多加一个‘\’在末尾

4.然后将你刚刚的.vt文件设置一下,点击Assignments->Settings->Simulation

 点击Test Benches->New

第一行是.vt文件的名字,第二行打开你的.vt文件,看看里面的模块名是什么,一定要保持一致,然后在file name下找到你的.vt文件,点击Add,便会出现在下面的框框里,接下来一直点击OK即可 

对仿照时间有需要的话,可以自行选择End simulation at: 

5. 进行仿真,会跳转到modelsim

6.选择wave文件便可看到波形

四、测试代码

这里仅仅是我随便写的一次作业代码,仅供大家参考运行

module Registers_32(Clk, wr, Ra, Rb, Rw, busW, busA, busB);

parameter n = 32;       // 每个寄存器宽度
parameter num = 32;     // 寄存器数量
input Clk, wr;          // 时钟信号和写使能信号
input [4:0] Ra, Rb, Rw; // 读/写地址
input [n-1:0] busW;     // 写入数据总线
output reg [n-1:0] busA, busB; // 读出数据总线
reg [n-1:0] register[num-1:0]; // 寄存器组
integer i;

// 初始化寄存器组
initial begin
    for (i = 0; i < num; i = i + 1)
        register[i] <= i;
end

// 读操作 (组合逻辑操作)
always @(*) begin
    busA = register[Ra]; // 从地址 Ra 对应的寄存器中读数据
    busB = register[Rb]; // 从地址 Rb 对应的寄存器中读数据
end

// 写操作 (时序逻辑操作)
always @(negedge Clk) begin
    if (wr) begin
        register[Rw] <= busW; // 在时钟下降沿,将数据写入地址 Rw 对应的寄存器
    end
end

endmodule
module DataMemory(DataIn, Clk, WrEn, Adr, DataOut);

parameter n = 32;             // 数据宽度
input WrEn, Clk;              // 写使能和时钟信号
input [n-1:0] DataIn;         // 写入数据
input [31:0] Adr;             // 地址
output reg [n-1:0] DataOut;   // 读出数据
reg [n-1:0] MemReg[255:0];    // 256 个 32 位存储单元
integer i;

// 初始化存储器
initial begin
    for (i = 0; i < 256; i = i + 1)
        MemReg[i] = i;
end

// 写操作 (时序逻辑操作)
always @(negedge Clk) begin
    if (WrEn) begin
        MemReg[Adr] <= DataIn; // 在时钟下降沿,将数据写入指定地址
    end
end

// 读操作 (组合逻辑操作)
always @(*) begin
    DataOut = MemReg[Adr]; // 从指定地址读数据
end

endmodule

 顶层模块

module Instruction(Clk, RegWrEn, MemWrEn, Ra, Rb, Rw, MemAdr, RegDataIn, MemDataIn, RegDataOutA, RegDataOutB, MemDataOut);

parameter n = 32;

input Clk, RegWrEn, MemWrEn;            // 时钟信号和写使能信号
input [4:0] Ra, Rb, Rw;                 // 寄存器地址
input [31:0] MemAdr;                    // 存储器地址
input [n-1:0] RegDataIn, MemDataIn;     // 写入寄存器和存储器的数据
output [n-1:0] RegDataOutA, RegDataOutB; // 寄存器读出数据
output [n-1:0] MemDataOut;              // 存储器读出数据

// 实例化寄存器组模块
Registers_32 registers(
    .Clk(Clk),
    .wr(RegWrEn),
    .Ra(Ra),
    .Rb(Rb),
    .Rw(Rw),
    .busW(RegDataIn),
    .busA(RegDataOutA),
    .busB(RegDataOutB)
);

// 实例化存储器模块
DataMemory memory(
    .DataIn(MemDataIn),
    .Clk(Clk),
    .WrEn(MemWrEn),
    .Adr(MemAdr),
    .DataOut(MemDataOut)
);

endmodule

.vt文件 

`timescale 1 ps / 1 ps
module Instruction_vlg_tst();
// constants                                           
// general purpose registers
reg [31:0] cycle; // 记录测试循环
// test vector input registers
reg Clk;
reg [31:0] MemAdr;
reg [31:0] MemDataIn;
reg MemWrEn;
reg [4:0] Ra;
reg [4:0] Rb;
reg [31:0] RegDataIn;
reg RegWrEn;
reg [4:0] Rw;
// wires                                               
wire [31:0]  MemDataOut;
wire [31:0]  RegDataOutA;
wire [31:0]  RegDataOutB;

// DUT (Device Under Test)
Instruction i1 (
// port map - connection between master ports and signals/registers   
    .Clk(Clk),
    .MemAdr(MemAdr),
    .MemDataIn(MemDataIn),
    .MemDataOut(MemDataOut),
    .MemWrEn(MemWrEn),
    .Ra(Ra),
    .Rb(Rb),
    .RegDataIn(RegDataIn),
    .RegDataOutA(RegDataOutA),
    .RegDataOutB(RegDataOutB),
    .RegWrEn(RegWrEn),
    .Rw(Rw)
);

// 时钟信号生成
initial begin
    Clk = 0;
    forever #50 Clk = ~Clk; // 时钟周期
end

// 测试逻辑
initial begin
    $display("Running testbench...");
    cycle = 0;

    // 初始化信号
    MemAdr = 0; MemDataIn = 0; MemWrEn = 0;
    Ra = 0; Rb = 0; Rw = 0;
    RegDataIn = 0; RegWrEn = 0;

    // 等待复位时间
    #200;

    // 测试1:寄存器组写操作和读操作
    $display("Test 1: Registers_32 Write and Read");
    Rw = 5'd2;            // 写寄存器2
    RegDataIn = 32'hA5A5; // 写入数据 0xA5A5
    RegWrEn = 1;          // 启用写操作
    #100;                  // 等待一个时钟周期
    RegWrEn = 0;          // 停止写操作

    Ra = 5'd2;            // 读取寄存器2
    #100;                  // 等待组合逻辑延迟
    if (RegDataOutA == 32'hA5A5) begin
        $display("PASS: Register Read/Write");
    end else begin
        $display("FAIL: Register Read/Write");
    end

    // 测试2:数据存储器写操作和读操作
    $display("Test 2: DataMemory Write and Read");
    MemAdr = 32'd100;      // 地址 100
    MemDataIn = 32'h5A5A;  // 写入数据 0x5A5A
    MemWrEn = 1;           // 启用写操作
    #100;                   // 等待一个时钟周期
    MemWrEn = 0;           // 停止写操作

    MemAdr = 32'd100;      // 地址 100
    #100;                   // 等待组合逻辑延迟
    if (MemDataOut == 32'h5A5A) begin
        $display("PASS: DataMemory Read/Write");
    end else begin
        $display("FAIL: DataMemory Read/Write");
    end

    // 测试完成
    $display("All tests completed.");
    $finish;
end

endmodule

(作者是初学者,文章若是有不对的地方欢迎大家指出,一起学习) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值