【Quartus FPGA】EMIF DDR3 IP 仿真记录

EMIF (External Memory Interface) 是 Quartus 平台提供的 IP,用于实现高速存储器件接口与控制器。通过 Intel Quartus Prime 软件,可以很方便地实现 EMIF IP 电路。本文记录了使用 EMIF 实现 DDR3 控制器的仿真过程,软件平台为 Quartus Prime Pro 21.3,器件型号为 10CX220YF780E6G.

目录

1 EMIF IP 介绍

2 EMIF DDR3 IP 配置

3 EMIF DDR3 IP 仿真


1 EMIF IP 介绍

 

       Intel EMIF IP 是 Quartus 平台提供的 IP,用于实现高速存储器件接口与存储控制器电路。借助 EMIF 电路,FPGA 可以与外部存储器件进行数据交换。 

        EMIF IP 实现物理层接口与存储控制器,这两部分的功能说明如下:

  • 物理层接口(Physical Layer Interface),用于建立数据通路,以及管理 FPGA 和存储器件的传输时序;
  • 存储控制器(Memory Controller),实现内存命令与协议层规范。

        EMIF IP 的总体设计流程如下图:

        EMIF IP 设计过程中涉及许多参数与配置步骤,IP 配置完成之后,可以生成参考工程,用于功能仿真,以检查参数配置是否有误。

2 EMIF DDR3 IP 配置

        新建工程,器件型号选择 10CX220YF780E6G。

 

        在 IP Catalog 中输入 memory,然后双击选择 External Memory Interfaces Intel Cyclone 10 FPGA IP。

        Memory Protocol 选 DDR3,时钟频率和 PLL 参考时钟频率根据需要配置,这里时钟频率填 933M,PLL 参考时钟频率为 116.625MHz.

 (PS:右下角 Presets 中有预设的选项,双击可以直接应用)

        容量为 1Gb 的 DDR3,行地址为 13bit,DQ width 根据实际器件类型填写。

        中间时序参数可以先跳过,最后有个仿真选项,选择 Skip Calibration,跳过校准阶段。

        IP 配置完成之后,点击 Generate Example Design,生成参考工程。

3 EMIF DDR3 IP 仿真

        在前面生成的参考工程中,仿真相关文件在 sim/ed_sim/mentor 和 sim/ed_sim/sim 路径下。修改 sim/ed_sim/sim 路径下的 ed_sim.v 文件,替换掉 ed_sim_tg 模块例化代码,就可以仿真自己编写的控制逻辑。

        仿照 ed_sim_tg 模块接口,编写 ed_sim_tg_0 模块,代码如下:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity ed_sim_tg_0 is
   generic(
      AMM_WRITE_PATTERN   : std_logic_vector := X"0102030405060708090A0B0C0D0E0F10";
      AMM_WRITE_INC       : std_logic_vector := X"01010101010101010101010101010101"
   );
   port(
      emif_usr_reset_n    : in std_logic;
      emif_usr_clk        : in std_logic; -- 233MHz
      local_cal_success   : in std_logic;
      amm_ready_0         : in std_logic;
      amm_read_0          : out std_logic;
      amm_write_0         : out std_logic;
      amm_address_0       : out std_logic_vector(28 downto 0);
      amm_readdata_0      : in std_logic_vector(127 downto 0);
      amm_writedata_0     : out std_logic_vector(127 downto 0);
      amm_burstcount_0    : out std_logic_vector(6 downto 0);
      amm_byteenable_0    : out std_logic_vector(15 downto 0);
      amm_readdatavalid_0 : in std_logic
   );
end entity;
architecture behav of ed_sim_tg_0 is
-- internal signal declarations
type state is (
   st_emif_init,
   st_amm_idle,
   st_amm_write,
   st_amm_read
);
signal pstate                  : state := st_emif_init;
signal buf_amm_read_0          : std_logic;
signal buf_amm_write_0         : std_logic;
signal cnt_amm_write_0         : std_logic_vector(7 downto 0);
signal buf_amm_address_0       : std_logic_vector(28 downto 0);
signal buf_amm_writedata_0     : std_logic_vector(127 downto 0);
signal buf_amm_burstcount_0    : std_logic_vector(6 downto 0);
signal buf_amm_byteenable_0    : std_logic_vector(15 downto 0);
signal cnt_amm_readdatavalid_0 : std_logic_vector(7 downto 0);
------------------------------------------------------
begin
------------------------------------------------------
amm_write_0      <= buf_amm_write_0;
amm_read_0       <= buf_amm_read_0;
amm_address_0    <= buf_amm_address_0;
amm_writedata_0  <= buf_amm_writedata_0;
amm_burstcount_0 <= buf_amm_burstcount_0;
amm_byteenable_0 <= buf_amm_byteenable_0;

process(emif_usr_reset_n,emif_usr_clk) 
begin
   if emif_usr_reset_n = '0' then
      pstate <= st_emif_init;
      buf_amm_write_0 <= '0';
      cnt_amm_write_0 <= (others => '0');
      buf_amm_read_0 <= '0';
      buf_amm_address_0 <= (others => '0');
      buf_amm_writedata_0 <= (others => '0');
      buf_amm_burstcount_0 <= (others => '0');
      buf_amm_byteenable_0 <= (others => '0');
      cnt_amm_readdatavalid_0 <= (others => '0');
   elsif rising_edge(emif_usr_clk) then
      case(pstate) is
         when st_emif_init => 
            if local_cal_success = '1' then
               pstate <= st_amm_idle;
            else
               pstate <= st_emif_init;
            end if;

         when st_amm_idle => 
            pstate <= st_amm_write;
            buf_amm_writedata_0 <= AMM_WRITE_PATTERN;
            buf_amm_address_0 <= buf_amm_address_0 + 1;

         when st_amm_write => 
            if cnt_amm_write_0 = 63 then
               cnt_amm_write_0 <= (others => '0');
               buf_amm_write_0 <= '0';
               buf_amm_byteenable_0 <= (others => '0');
               pstate <= st_amm_read;
               buf_amm_read_0 <= '1';
            else
               if buf_amm_write_0 = '1' and amm_ready_0 = '1' then
                  cnt_amm_write_0 <= cnt_amm_write_0 + 1;
                  buf_amm_writedata_0 <= buf_amm_writedata_0 + AMM_WRITE_INC;
               end if;
               buf_amm_write_0 <= '1';
               buf_amm_burstcount_0 <= conv_std_logic_vector(64,7);
               buf_amm_byteenable_0 <= (others => '1');
               pstate <= st_amm_write;
            end if;

         when st_amm_read => 
            if buf_amm_read_0 = '1' and amm_ready_0 = '1' then
               buf_amm_read_0 <= '0';
            end if;

            if cnt_amm_readdatavalid_0 = 64 then
               cnt_amm_readdatavalid_0 <= (others => '0');
               pstate <= st_amm_idle;
            else
               if amm_readdatavalid_0 = '1' then
                  cnt_amm_readdatavalid_0 <= cnt_amm_readdatavalid_0 + 1;
               end if;
               pstate <= st_amm_read;
            end if;

         when others => NULL;

      end case;
   end if;
end process;
end architecture;

        打开 Modelsim 读取 msim_setup.tcl 文件,编译 EMIF IP 文件与用户设计文件,并启动仿真。 

等待 emif_c10_0_status_local_cal_success 拉高,就可以进行 DDR3 数据读写操作了。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
vhdl设计FPGA读写DS18B20温度传感器quartus工程源码+文档说明 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity ds18B20 is port( clk : in std_logic;---50MHz rst_n: in std_logic; --复位信号输入 one_wire : inout std_logic; --DS18B20数据线 ---------------- dataout : out std_logic_vector(7 downto 0); --数码管数据输出 en : out std_logic_vector(3 downto 0)); --数码管位选信号 end ds18B20; architecture Behavioral of ds18B20 is signal dataout_buf:std_logic_vector(3 downto 0); signal count:std_logic_vector(17 downto 0); --分频计数器 signal cnt_scan:std_logic_vector(17 downto 0); --数码管的扫描显示计数器 signal clk_1us:std_logic;-- 1MHz 时钟 signal cnt_1us:integer range 0 to 750002;-- 1us延时计数子 signal cnt_1us_clear:std_logic;-- 请1us延时计数子 TYPE STATE_TYPE is (S00,S0,S1,S2,S3,S4,S5,S6,S7, WRITE0,WRITE1,WRITE00,WRITE01,READ0,READ1,READ2,READ3); --状态机 signal state: STATE_TYPE; --初始状态设置为复位状态 signal one_wire_buf:std_logic;-- One-Wire总线 缓存寄存器 signal temperature_buf:std_logic_vector(15 downto 0);-- 采集到的温度值缓存器(未处理) signal DS18B20_DATA_buf:std_logic_vector(15 downto 0);-- 采集到的温度值缓存器(未处理) signal DS18B20_DATA_buf_temp:std_logic_vector(15 downto 0);-- 采集到的温度值缓存器(未处理) signal step:integer range 0 to 50;--子状态寄存器 0~50 signal bit_valid:integer range 0 to 15;--有效位 signal one_wire_in:std_logic; signal t_buf:std_logic_vector(15 downto 0); signal t_buf_temp:std_logic_vector(15 downto 0); signal cnt:integer range 0 to 50;-- 计数子 -- //++++++++++++++++++++++++++++++++++++++ -- // 分频器50MHz->1MHz 开始 -- //++++++++++++++++++++++++++++++++++++++ begin -- process (clk,rst_n) -- begin -- if rising_edge(clk) then -- if(rst_n='0') then -- cnt <= 0; -- else -- if(cnt = 49)then -- cnt <= 0; -- else -- cnt <= cnt + 1; -- end if; -- end if; -- end if; -- end Process;
基于cyclone FPGA VHDL语言设计交通信号灯quartus9.0工程源码+文档说明, 设计任务 1. 模拟十字路口交通信号灯的工作过程,利用交通信号灯上的两组红,黄,绿LED发光二极管作为交通信号灯,设计一个交通信号灯控制器。 2. 模拟两条公路,一条交通主干道,一条交通支干道,在主干道和支干道的交叉路口上设置红,绿,蓝灯进行交通管理。 3. 应用VHDL硬件描述语言编写程序; 4. 利用软件仿真出结果; 2总体设计 十字路口交通灯控制系统设计 任务和要求:该数字系统完成对十字路口交通信号灯的控制,十字路口由一条东西方向的主干道(简称A道)和南北方向的支干道(简称B道)构成。 十字路口交通灯控制规则为: (1) 初始状态为4 个方向的红灯全亮,时间1s。 (2) 东西方向绿灯亮,南北方向红灯亮。东西方向通车,时间30s。 (3) 东西方向黄灯亮,南北方向红灯亮,时间5s。 (4) 东西方向红灯亮,南北方向绿灯亮。南北方向通车,时间20s。 (5) 东西方向红灯亮,南,北方向黄灯亮,时间5s。 (6) 返回(2),继续运行。 (7) 如果发生紧急事件,例如救护车,警车通过,则按下单脉冲按钮,使得东,南,西,北四个方向红灯亮。紧急事件结束后,松开单脉冲按钮,将恢复到被打断的状态继续运行。 3 详细设计及实现 此题即为一个典型的时序状态机,共有六个大的状态,现设定: S0: 四个方向的红灯全亮 S1: 东、西方向绿灯亮,南、北方向红灯亮 S2:东、西方向黄灯闪烁,南、北方向红灯亮 S3:东、西方向红灯亮,南、北方向绿灯亮 S4:东、西方向红灯亮,南、北方向黄灯闪烁 S5:东、西、南、北四个方向的红灯亮 则状态图如下: LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY state_machine IS PORT( clk,reset_n,hold,clk_1hz,select_model: IN STD_LOGIC;--clk为50M时钟信号,hold为紧急信号,reset为复位信号 second_count_ge_out: OUT std_logic_vector(3 downto 0);--秒的个位 second_count_shi_out:OUT std_logic_vector(3 downto 0);--秒的十位 red1_out,green1_out,yellow1_out:OUT STD_LOGIC; --控制东西方向的交通灯 red2_out,green2_out,yellow2_out:OUT STD_LOGIC);--控制南北方向的交通灯 END;

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

洋洋Young

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

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

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

打赏作者

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

抵扣说明:

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

余额充值