製品情報>Artix-7評価ボード>Artix-7技術コラム>DDR3の使い方

DDR3の使い方

Artix-7でDDR3メモリを使うには、ISEに内蔵されたCoreGeneratorを使ってIPコアを生成します(MIGという)。ISEのバージョンは14.5または14.7を使用してください。

Spartan-6のときのDDR3 IPコア

Spartan-6のDDR3メモリコアは、下の図のように、MCBというハードウェアブロックで行っていました。MCBは複数のユーザポートを持っていて、それぞれのユーザポートは独立して動きました。MCBのユーザ側ポートはFIFOベースの単純なものだったので、センサから取り込んだデータをUSBに転送したりCPU(MicroBlaze等)で扱う設計が比較的楽にできました。

 

Artix-7のDDR3 IPコア

しかし、Artix-7のDDR3メモリコア(MIG)はユーザ側ポート1ポートしかありません。DDR3メモリをUSBから操作するようなアプリを作ったら、それだけで終わってしまいます。センサをつなぐところがもうないのです。

だから、複数のポートに拡張しなければなりませんが、ソフトコアにはクロックドメインが1つか用意されていないので簡単ではありません。

そこで、Artix-7のソフトコアをAXIバス形式で生成し、AXIインターコネクトを使って拡張するのが一番簡単です。

 

つまり、USBのコアも、センサ(お客様回路)も、すべてAXIバスに準拠して作り、XILINXのCoreGeneratorを使ってAXI ICとソフトコアを生成してつなげる、という形になります。

プロジェクトの設定はVerilog

CoreGeneratorを使ったAXI版のDDR3コアはVerilogで生成されます。したがって、ISEプロジェクトをVerilogにしておく必要があります。

VHDLで使うにはラッパを通す

当社はVHDL派なので、CoreGenの作ったVerilog版AXI-DDR3コアをVHDLでラップして使っています。直接インスタンシエートするのではなく、いったん、ラッパを通してから使います。

 

 component axi_ddr3_wrap is
 port (
  ddr3_dq         : inout STD_LOGIC_VECTOR(7 downto 0);
  ddr3_dqs_n      : inout STD_LOGIC_VECTOR(0 downto 0);
  ddr3_dqs_p      : inout STD_LOGIC_VECTOR(0 downto 0);
 -- Outputs
  ddr3_addr       : out   STD_LOGIC_VECTOR(14 downto 0);
  ddr3_ba         : out   STD_LOGIC_VECTOR(2 downto 0);
  ddr3_ras_n      : out   STD_LOGIC;
  ddr3_cas_n      : out   STD_LOGIC;
  ddr3_we_n       : out   STD_LOGIC;
  ddr3_cs_n       : out   STD_LOGIC_VECTOR(0 downto 0);
  ddr3_reset_n    : out   STD_LOGIC;
  ddr3_ck_p       : out   STD_LOGIC_VECTOR(0 downto 0);
  ddr3_ck_n       : out   STD_LOGIC_VECTOR(0 downto 0);
  ddr3_cke        : out   STD_LOGIC_VECTOR(0 downto 0);
  ddr3_dm         : out   STD_LOGIC_VECTOR(0 downto 0);
  ddr3_odt        : out   STD_LOGIC_VECTOR(0 downto 0);
 -- Inputs
 -- Single-ended system clock
  sys_clk_i       : in   STD_LOGIC;
  clk_ref_i       : in   STD_LOGIC;
  ui_clk          : out  STD_LOGIC;
  ui_clk_sync_rst : out  STD_LOGIC;
  mmcm_locked     : out  STD_LOGIC;
  aresetn         : in   STD_LOGIC;
  app_sr_req      : in   STD_LOGIC;
  app_sr_active   : out  STD_LOGIC;
  app_ref_req     : in   STD_LOGIC;
  app_ref_ack     : out  STD_LOGIC;
  app_zq_req      : in   STD_LOGIC;
  app_zq_ack      : out  STD_LOGIC;
 -- Slave Interface Write Address Ports
  s_axi_awid      : in  STD_LOGIC_VECTOR(3 downto 0);
  s_axi_awaddr    : in  STD_LOGIC_VECTOR(31 downto 0);
  s_axi_awlen     : in  STD_LOGIC_VECTOR(7 downto 0);
  s_axi_awsize    : in  STD_LOGIC_VECTOR(2 downto 0);
  s_axi_awburst   : in  STD_LOGIC_VECTOR(1 downto 0);
  s_axi_awlock    : in  STD_LOGIC_VECTOR(0 downto 0);
  s_axi_awcache   : in  STD_LOGIC_VECTOR(3 downto 0);
  s_axi_awprot    : in  STD_LOGIC_VECTOR(2 downto 0);
  s_axi_awqos     : in  STD_LOGIC_VECTOR(3 downto 0);
  s_axi_awvalid   : in  STD_LOGIC;
  s_axi_awready   : out STD_LOGIC;
 -- Slave Interface Write Data Ports
  s_axi_wdata     : in  STD_LOGIC_VECTOR(63 downto 0);
  s_axi_wstrb     : in  STD_LOGIC_VECTOR(7 downto 0);
  s_axi_wlast     : in  STD_LOGIC;
  s_axi_wvalid    : in  STD_LOGIC;
  s_axi_wready    : out STD_LOGIC;
 -- Slave Interface Write Response Ports
  s_axi_bready    : in  STD_LOGIC;
  s_axi_bid       : out STD_LOGIC_VECTOR(3 downto 0);
  s_axi_bresp     : out STD_LOGIC_VECTOR(1 downto 0);
  s_axi_bvalid    : out STD_LOGIC;
 -- Slave Interface Read Address Ports
  s_axi_arid      : in  STD_LOGIC_VECTOR(3 downto 0);
  s_axi_araddr    : in  STD_LOGIC_VECTOR(31 downto 0);
  s_axi_arlen     : in  STD_LOGIC_VECTOR(7 downto 0);
  s_axi_arsize    : in  STD_LOGIC_VECTOR(2 downto 0);
  s_axi_arburst   : in  STD_LOGIC_VECTOR(1 downto 0);
  s_axi_arlock    : in  STD_LOGIC_VECTOR(0 downto 0);
  s_axi_arcache   : in  STD_LOGIC_VECTOR(3 downto 0);
  s_axi_arprot    : in  STD_LOGIC_VECTOR(2 downto 0);
  s_axi_arqos     : in  STD_LOGIC_VECTOR(3 downto 0);
  s_axi_arvalid   : in  STD_LOGIC;
  s_axi_arready   : out STD_LOGIC;
 -- Slave Interface Read Data Ports
  s_axi_rready        : in   STD_LOGIC;
  s_axi_rid           : out  STD_LOGIC_VECTOR(3 downto 0);
  s_axi_rdata         : out  STD_LOGIC_VECTOR(63 downto 0);
  s_axi_rresp         : out  STD_LOGIC_VECTOR(1 downto 0);
  s_axi_rlast         : out  STD_LOGIC;
  s_axi_rvalid        : out  STD_LOGIC;
  init_calib_complete : out  STD_LOGIC;
 -- System reset - Default polarity of sys_rst pin is Active Low.
 -- System reset polarity will change based on the option
 -- selected in GUI.
  sys_rst             : in  std_logic
 );
 end component;

 

まとめると、DDR3メモリを使うための基本は、

  • CoreGenを使ってDDR3メモリコアを生成する
  • AXIバスとして作る
  • ラッパを通す

使うには、CoreGenの知識と、AXIバスの知識が必要になります。

 


© 2017 TokushuDenshiKairo Inc. All rights reserved