基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证

本文内容:基于 Cyclone IV在 Quartus 中配置 IP 核中的 PLL 、 RAM 与 FIFO 的详细步骤

目录
  • 一、配置 PLL
    • 1.1 参数配置
    • 1.2 仿真测试
  • 二、配置 RAM
    • 2.1 参数配置
    • 2.2 仿真测试
  • 三、配置 FIFO
    • 3.1 参数配置
    • 3.2 仿真测试

一、配置 PLL
  • 在我看来哈,PLL 的作用就是将输入时钟通过倍频分频相位偏移设置占空比等操作,将输入的时钟信号转变为另外一种形式的时钟信号,这个主要看自己的需求
1.1 参数配置
  • 首先需要新建一个工程,在工程里面配置 PLL
  • 在【IP Catalog】界面的搜索框中输入【PLL】,双击【ALTPLL】即可
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 如果没有【IP Catalog】界面,在【View】中可以设置
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 点击【…】选择 IP 核的保存路径
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 最好新建一个 ip 文件夹,输入文件名后保存(图中有文件,是之前加的)
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 再点击【OK】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • Cyclone IV 选择 8 通道、50 MHz(细心的兄弟会发现左边的 PLL_demo 有 c0 - c3 多个输出,但是自己的界面只有个 c0 ,没关系,这是后面才配置出来的,我这个是配置好的)
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 勾选上【Create ‘locked’ output】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 默认即可
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 默认即可
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 默认即可
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 主要的配置界面如下:
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片

    Clock multiplication factor——时钟倍频参数
    Clock division factor——时钟分频参数
    Clock phase shift——时钟相位偏移参数
    Clock duty cycle(%)——时钟占空比
  • 这里我们让每一个输出设置一种参数类型来看看实际的效果
  • 首先让 c0 设置倍频参数为 2,可以看到它的时钟频率变为了 100 MHz,再点击【Next>】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • c1 让它分频参数设为 2 ,可以看到它的频率变为了 25 MHz,再点【Next>】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • c2 相位偏移设为 90,单位是 deg,表示角度,也就是偏移了 π/2 个时钟周期,除了角度还有时间单位 ns、ps
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • c3 时间占空比设为 20,之后可以具体看看是什么样子
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • c4 我就没有勾选上了,因为就那么四个参数,没必要再搞一个 c4 输出了
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 继续点击【Next>】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 勾选上【PLL_demo_inst.v】,这个可以生成相应的模块调用格式
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
1.2 仿真测试
  • 写一个仿真文件,直接调用这个模块就可以,如果不怎么会仿真的话,可以参考博客:
    Quartus 与 ModelSim 联合仿真详细步骤
    基于 FPGA 按键控制呼吸灯原理、仿真及验证全过程
  • 贴一下仿真代码
`timescale 1ns/1nsmodule tb_pll; // Parameter definition parameterCYC_CLK= 20; // Drive signal regtb_clk; regtb_rst_n; // Observation signal wirec0; wirec1; wirec2; wirec3; wirelocked; // Module calls PLL_demo PLL_demo_inst ( /*input */.inclk0(tb_clk), /*input */.areset(~tb_rst_n), /*output*/.c0(c0), /*output*/.c1(c1), /*output*/.c2(c2), /*output*/.c3(c3), /*output*/.locked(locked) ); // System initialization initial tb_clk = 1'b1; always #10 tb_clk = ~tb_clk; initial begin tb_rst_n = 1'b0; #20; tb_rst_n = 1'b1; #(500 * CYC_CLK); $stop; end endmodule

  • 在【Simulation】选择 Test Benches 中,选择哪一个仿真文件,就会仿真哪个,同时还要设置相应的顶层模块熬
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 仿真结果如下:
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 可以看到
    c0 倍频,频率高了,时钟周期短了
    c1 分频,频率低了,时钟周期长了
    c2 相位偏移,右移了 π/2 个时钟周期
    c3 设置占空比 20,高电平区间占一个时钟周期 20%
  • 这就是 PLL 的作用,将输出的 clock 时钟信号转变为其它类型的时钟信号
二、配置 RAM 2.1 参数配置
  • 同样在【IP Catalog】搜索 RAM,选择 1-PORT 单端口的,2-PORT 表示双端口,学会了单端口那么双端口也依葫芦画瓢就会了
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 同样的操作步骤
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 这里表示一个数据字节为 8 bits,共 256 个字节,Auto 自动配置即可,勾选 Single clock 表示单个时钟信号控制输入输出就行
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 勾选上 q 也就是数据输出,同时勾选上复位信号 aclr 和读使能信号 rden
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 这里设置 Don’t Care 即可
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 在这里使用一个 hex 文件初始化 RAM,看下面怎么创建 hex 文件
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 切回 Quartus 主界面,点击【File】→【New…】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 点击【Hexadecimal (Intel-Format) File】创建基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 新建的文件,里面是没有数据,选中所有的字节,右键点击【Custom Fill Cells…】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • Starting address:开始地址
    Ending address:结束地址
    Starting value:初始值
    Increment:递增操作
    by:步长
  • 最后点击 OK
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 保存到 prj 下面,一定要是 prj 下面!!!
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 回到刚刚的窗口,添加 hex 文件到 RAM 中
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 再点击【Next>】
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 最后勾选上【inst】即可
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
2.2 仿真测试
  • 仿真代码如下:
`timescale 1ns/1nsmodule tb_ram; // Parameter definition parameterCYC_CLK= 20; // Drive signal regtb_clk; regtb_rst_n; reg[ 7:0]address; reg[ 7:0]data; regrden; regwren; // Observation signal wire[ 7:0]q_out; // Module calls RAM_demo RAM_demo_inst ( .clock(tb_clk), .aclr(~tb_rst_n), .address(address), .data(data), .rden(rden), .wren(wren), .q(q_out) ); // System initialization initial tb_clk = 1'b1; always #10 tb_clk = ~tb_clk; initial begin address = 8'd25; data = https://www.it610.com/article/8'd51; rden = 1'b0; wren = 1'b0; tb_rst_n = 1'b0; #20; tb_rst_n = 1'b1; // 读操作 rden = 1'b1; repeat (256) begin address = address + 8'd1; #(CYC_CLK); end rden = 1'b0; #(500 * CYC_CLK); // 写操作 wren = 1'b1; repeat (256) begin data = https://www.it610.com/article/data + 8'd2; address = address + 8'd1; #(CYC_CLK); end wren = 1'b0; #(500 * CYC_CLK); // 读操作 rden = 1'b1; repeat (256) begin address = address + 8'd1; #(CYC_CLK); end rden = 1'b0; #(500 * CYC_CLK); $stop; end endmodule

  • 记得设置仿真文件
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 仿真结果:
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 第一段读操作是读的 hex 文件设置的内容,写操作写入新的数据,第二个读操作,读取的是写入的新数据
三、配置 FIFO 3.1 参数配置
  • FIFO 其实就是一个队列,先进先出的原则
  • 同样的,输入 FIFO/fifo 双击
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 选择存储路径
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 看自己的选择勾选与设置
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 默认设置即可
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 按照下图自己需要进行配置
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 默认就行
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 没勾选
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 一直到这一步,勾选个 inst 即可,生成个模块调用语句而已
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
3.2 仿真测试
  • 这里使用一个 Verilog 顶层模块调用 FIFO,并不断地写数据,同时不断地读数据
  • 再写一个仿真测试文件来看看仿真波形
fifo_top.v
module fifo_top ( inputclk, inputrst_n,output[15:0]q, outputrdempty, output[ 7:0]rdusedw, outputwrfull, output[ 8:0]wrusedw ); // Parameter definition// Signal definition reg[ 7:0]data; regrdreq; regwrreq; // Module calls FIFO_512_8 FIFO_512_8_inst ( /*input*/.aclr(~rst_n),// 复位信号,高电平有效 /*input[ 7:0]*/.data(data),// 写数据,8bits /*input*/.rdclk(clk),// 读时钟信号 /*input*/.rdreq(rdreq),// 读使能信号,高电平读 /*input*/.wrclk(clk),// 写时钟信号 /*input*/.wrreq(wrreq),// 写使能信号,高电平写 /*output[15:0]*/.q(q),// 读数据,16bits /*output*/.rdempty(rdempty ),// 读空使能,表示读的时候队列中是否为空,1表示空,0表示非空 /*output[ 7:0]*/.rdusedw(rdusedw ),// 读余量,表示读的时候队列中有多少个16bits的数据 /*output*/.wrfull(wrfull),// 写满使能,表示写的时候队列中是否写满了,1表示满,0表示非满 /*output[ 8:0]*/.wrusedw(wrusedw ) // 写余量,表示写的时候队列中有多少个8bits的数据 ); // Logic description // 读使能 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin rdreq <= 'd0; end else if (rdempty) begin rdreq <= 'd0; end else begin rdreq <= 'd1; end end// 写使能 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin wrreq <= 'd0; end else if (wrfull) begin wrreq <= 'd0; end else begin wrreq <= 'd1; end end// 写数据 always @(posedge clk or negedge rst_n) begin if (!rst_n) begin data <= 'd20; end else if (wrreq) begin if (data >= 255) begin data <= 0; end else begin data <= data + 'd2; end end else begin data <= 'd20; end endendmodule

  • 仿真文件
【基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证】tb_fifo.v
`timescale 1ns/1nsmodule tb_fifo; // Parameter definition parameterCYC_CLK= 20; // Drive signal regtb_clk; regtb_rst_n; // Observation signal wire[15:0]tb_q; wiretb_rdempty; wire[ 7:0]tb_rdusedw; wiretb_wrfull; wire[ 8:0]tb_wrusedw; // Module calls fifo_top U_fifo_top( /*input*/.clk(tb_clk), /*input*/.rst_n(tb_rst_n), /*output[15:0]*/.q(tb_q), /*output*/.rdempty(tb_rdempty ), /*output[ 7:0]*/.rdusedw(tb_rdusedw ), /*output*/.wrfull(tb_wrfull), /*output[ 8:0]*/.wrusedw(tb_wrusedw ) ); // System initialization initial tb_clk = 1'b1; always #10 tb_clk = ~tb_clk; initial begin tb_rst_n = 1'b0; #20; tb_rst_n = 1'b1; #(200 * CYC_CLK); $stop; end endmodule

  • 仿真结果
    基于 Cyclone IV 在 Quartus 中配置 IP 核中的 PLL、RAM 与 FIFO 的详细步骤及仿真验证
    文章图片
  • 可以看到队列先进先出的原则
  • 但是读余量前面一段时间为 0 ,但是明明有数据,结果却为了,过了几个时钟周期后才变成 1
  • 应该是由于写数据到 M9K 中这个过程需要时间,过了几个时钟周期后,读余量才检测到有数据,才读取数据

    推荐阅读