-- Instantiate Output DDR registers WRDATA_DDR_OUT_INST : for i in DDR_DATA_WIDTH-1 downto 0 generate WRDATA_DDR_OUT : FDDRCPE port map( q => ddr_out(i), d0 => wrdata_2d(i), d1 => wrdata_3d_half(i), c0 => clk, c1 => clkx, ce => dqs_enable_2d(i/8), clr => reset, pre => gnd ); end generate WRDATA_DDR_OUT_INST;
not_dqs_enable_2d <= not dqs_enable_2d;
-- Insantiate three-state DDR registers WRDATA_DDR_TRI_INST : for i in DDR_DATA_WIDTH-1 downto 0 generate WRDATA_DDR_TRI : FDDRRSE port map( q => out_tri(i), d0 => dqs_reset_2d_dqtri(i/8), -- DQSが0になる最初のクロックで1なので、一番最初の半クロックだけディスエーブル d1 => gnd, c0 => clk, c1 => clkx, ce => vcc, r => reset, s => not_dqs_enable_2d(i/8) ); end generate WRDATA_DDR_TRI_INST;
-- inferr the 3-State buffer process(out_tri, ddr_out) begin for i in DDR_DATA_WIDTH-1 downto 0 loop if out_tri(i) = '1' then ddr_dq(i) <= 'Z'; elsif out_tri(i) = '0' then ddr_dq(i) <= ddr_out(i); end if; end loop; end process;
上のソースで"-- inferr the 3-State buffer"の部分をBUFTを使用するように以下のように修正したが他のエラーが出てしまった。
-- inferr the 3-State buffer OBUFT_GEN : for i in DDR_DATA_WIDTH-1 downto 0 generate OBUFT_INST : OBUFT port map( o => ddr_dq(i), i => ddr_out(i), t => out_tri(i) ); end generate OBUFT_GEN;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- pragma translate off library UNISIM; use UNISIM.VComponents.all; -- pragma translate on
entity lut_fifo is port ( clk: IN std_logic; areset : in std_logic; -- async reset sreset : in std_logic; -- sync reset din: IN std_logic_vector(7 downto 0); wr_en: IN std_logic; rd_en: IN std_logic; dout: OUT std_logic_vector(7 downto 0); full: OUT std_logic; empty: OUT std_logic); end lut_fifo;
architecture RTL of lut_fifo is component SRL16E port ( q : out std_logic; a0 : in std_logic; a1 : in std_logic; a2 : in std_logic; a3 : in std_logic; ce : in std_logic; clk : in std_logic; d : in std_logic ); END component; component BUFIO port( o : out std_ulogic; i : in std_ulogic ); end component; component BUFR generic( BUFR_DIVIDE : string := "BYPASS" ); port( o : out std_ulogic; ce : in std_ulogic; clr : in std_ulogic; i : in std_ulogic ); end component;
signal addr : std_logic_vector(3 downto 0); signal clk_bufio, clk_bufr : std_logic; signal logic0, logic1 : std_logic; begin logic0 <= '0'; logic1 <= '1';
bufio_inst : bufio port map( i => clk, o => clk_bufio );
bufr_inst : bufr port map( o => clk_bufr, ce => logic1, clr => logic0, i => clk_bufio );
DIST_FIFO_GEN : for i in 0 to 7 generate SRL16E_inst : SRL16E port map( q => dout(i), a0 => addr(0), a1 => addr(1), a2 => addr(2), a3 => addr(3), ce => wr_en, clk => clk_bufr, d => din(i) ); end generate DIST_FIFO_GEN;
empty <= '1' when addr=0 else '0'; full <= '1' when addr=15 else '0';
process(clk_bufr, areset) begin if areset='1' then addr <= (others => '0'); elsif clk_bufr'event and clk_bufr='1' then if sreset='1' then addr <= (others => '0'); elsif wr_en='1' and rd_en='0' then addr <= addr + 1; elsif wr_en='0' and rd_en='1' then addr <= addr - 1; end if; -- wr_en='1' and rd_en='1'の時はaddrはそのまま end if; end process;
NET "areset" LOC = "D16" ; #INST "bufio_inst" LOC = "BUFIO_X0Y11" ; INST "bufr_inst" LOC = "BUFR_X0Y11" ; NET "clk" LOC = "D18" ; NET "din<0>" LOC = "B17" ; NET "din<1>" LOC = "A17" ; NET "din<2>" LOC = "E17" ; NET "din<3>" LOC = "F17" ; NET "din<4>" LOC = "A18" ; NET "din<5>" LOC = "A19" ; NET "din<6>" LOC = "C18" ; NET "din<7>" LOC = "C19" ; NET "dout<0>" LOC = "D19" ; NET "dout<1>" LOC = "F18" ; NET "dout<2>" LOC = "E18" ; NET "dout<3>" LOC = "B19" ; NET "dout<4>" LOC = "A20" ; NET "dout<5>" LOC = "H18" ; NET "dout<6>" LOC = "J19" ; NET "dout<7>" LOC = "B20" ; NET "empty" LOC = "B21" ; NET "full" LOC = "D20" ; NET "rd_en" LOC = "C17" ; NET "sreset" LOC = "H17" ; NET "wr_en" LOC = "G17" ;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- pragma translate off library UNISIM; use UNISIM.VComponents.all; --pragma translate on
entity IDELAY_VARIABLE_TEST is Port ( clk : in std_logic; indata : in std_logic_vector(7 downto 0); idelay_ce : in std_logic; idelay_inc : in std_logic; q1 : out std_logic_vector(7 downto 0); q2 : out std_logic_vector(7 downto 0); rdy : out std_logic ); end IDELAY_VARIABLE_TEST;
architecture RTL of IDELAY_VARIABLE_TEST is component IDELAY generic( IOBDELAY_TYPE : string := "FIXED"; IOBDELAY_VALUE : integer := 0 ); port( O : out std_ulogic;
C : in std_ulogic; CE : in std_ulogic; I : in std_ulogic; INC : in std_ulogic; RST : in std_ulogic ); end component; component IDELAYCTRL port( RDY : out std_ulogic;
REFCLK : in std_ulogic; RST : in std_ulogic ); end component; component IDDR generic( DDR_CLK_EDGE : string := "OPPOSITE_EDGE"; INIT_Q1 : bit := '0'; INIT_Q2 : bit := '0'; SRTYPE : string := "SYNC" ); port( Q1 : out std_ulogic; Q2 : out std_ulogic; C : in std_ulogic; CE : in std_ulogic; D : in std_ulogic; R : in std_ulogic; S : in std_ulogic ); end component; COMPONENT dcm133 PORT( CLKIN_IN : IN std_logic; CLKIN_IBUFG_OUT : OUT std_logic; CLK0_OUT : OUT std_logic; LOCKED_OUT : OUT std_logic ); END COMPONENT;
signal logic0, logic1 : std_logic; signal iddr_reset : std_logic; signal locked_out, clk_out : std_logic; signal delay_out : std_logic_vector(7 downto 0); begin logic0 <= '0'; logic1 <= '1'; iddr_reset <= not locked_out;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; USE IEEE.STD_LOGIC_TEXTIO.ALL; USE STD.TEXTIO.ALL;
ENTITY IDELAY_VARIABLE_TEST_tb IS END IDELAY_VARIABLE_TEST_tb;
ARCHITECTURE testbench_arch OF IDELAY_VARIABLE_TEST_tb IS
COMPONENT IDELAY_VARIABLE_TEST PORT ( clk : In std_logic; indata : In std_logic_vector(7 downto 0); idelay_ce : in std_logic; idelay_inc : in std_logic; q1 : Out std_logic_vector(7 downto 0); q2 : Out std_logic_vector(7 downto 0) ); END COMPONENT;
SIGNAL clk : std_logic := '0'; SIGNAL indata : std_logic_vector(7 downto 0) := "00000000"; SIGNAL q1 : std_logic_vector(7 downto 0) := "00000000"; SIGNAL q2 : std_logic_vector(7 downto 0) := "00000000"; signal idelay_ce : std_logic := '0'; signal idelay_inc : std_logic := '0';
constant PERIOD : time := 10 ns; constant DUTY_CYCLE : real := 0.5; constant OFFSET : time := 0 ns;
BEGIN UUT : IDELAY_VARIABLE_TEST PORT MAP ( clk => clk, indata => indata, idelay_ce => idelay_ce, idelay_inc => idelay_inc, q1 => q1, q2 => q2 );
PROCESS -- clock process for clk BEGIN WAIT for OFFSET; CLOCK_LOOP : LOOP clk <= '0'; WAIT FOR (PERIOD - (PERIOD * DUTY_CYCLE)); clk <= '1'; WAIT FOR (PERIOD * DUTY_CYCLE); END LOOP CLOCK_LOOP; END PROCESS;
PROCESS begin wait for (PERIOD/4); DATA_LOOP : LOOP wait for (PERIOD/2); indata <= indata + 1; end loop; END PROCESS;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;
---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code.
-- pragma translate off library UNISIM; use UNISIM.VComponents.all; --pragma translate on
entity idelay_fixed_test is Port ( clk : in std_logic; indata : in std_logic_vector(7 downto 0); q1 : out std_logic_vector(7 downto 0); q2 : out std_logic_vector(7 downto 0); rdy : out std_logic ); end idelay_fixed_test;
architecture RTL of idelay_fixed_test is component IDELAY generic( IOBDELAY_TYPE : string := "FIXED"; IOBDELAY_VALUE : integer := 0 ); port( O : out std_ulogic;
C : in std_ulogic; CE : in std_ulogic; I : in std_ulogic; INC : in std_ulogic; RST : in std_ulogic ); end component; component IDELAYCTRL port( RDY : out std_ulogic;
REFCLK : in std_ulogic; RST : in std_ulogic ); end component; component IDDR generic( DDR_CLK_EDGE : string := "OPPOSITE_EDGE"; INIT_Q1 : bit := '0'; INIT_Q2 : bit := '0'; SRTYPE : string := "SYNC" ); port( Q1 : out std_ulogic; Q2 : out std_ulogic; C : in std_ulogic; CE : in std_ulogic; D : in std_ulogic; R : in std_ulogic; S : in std_ulogic ); end component; COMPONENT dcm133 PORT( CLKIN_IN : IN std_logic; CLKIN_IBUFG_OUT : OUT std_logic; CLK0_OUT : OUT std_logic; LOCKED_OUT : OUT std_logic ); END COMPONENT;
signal logic0, logic1 : std_logic; signal iddr_reset : std_logic; signal locked_out, clk_out : std_logic; signal delay_out : std_logic_vector(7 downto 0); begin logic0 <= '0'; logic1 <= '1'; iddr_reset <= not locked_out;
IDDR_GEN : for i in 7 downto 0 generate IDDR_inst : IDDR generic map( DDR_CLK_EDGE => "SAME_EDGE_PIPELINED" )port map( Q1 => q1(i), Q2 => q2(i), C => clk_out, CE => logic1, D => indata(i), R => iddr_reset, S => logic0 ); end generate IDDR_GEN;
NET "clk" TNM_NET = "clk"; TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50 %;
VHDLファイルを書き換えてSAME_EDGEモードにする。
IDDR_GEN : for i in 7 downto 0 generate IDDR_inst : IDDR generic map( DDR_CLK_EDGE => "SAME_EDGE" )port map( Q1 => q1(i), Q2 => q2(i), C => clk_out, CE => logic1, D => indata(i), R => iddr_reset, S => logic0 ); end generate IDDR_GEN;
インプリメントしてFPGA Editorで見てみると、ピンク矢印のレジスタが付加されている。
Timing AnalyzerでAnalyzeメニューからAgainst Auto Generated Design Constrains...で見てみると、セットアップ時間は同じだった。ピリオド制約は解析数が0で効いていなかった。IOB内のカスケードされたレジスタには制約は効かないようだ。データシートで規定されているのだろう。 次にDDRのデータを入れて論理シミュレーションで確かめてみた。q1とq2が同じタイミングで出力されているが、q1が1Cを出力している時はq2は以前の1Bを出力している。
entity V4_IDDR_test is Port ( clk : in STD_LOGIC; indata : in std_logic_vector(7 downto 0); q1 : out std_logic_vector(7 downto 0); q2 : out std_logic_vector(7 downto 0)); end V4_IDDR_test;
.....
IDDR_GEN : for i in 7 downto 0 generate IDDR_inst : IDDR generic map( DDR_CLK_EDGE => "OPPOSITE_EDGE" )port map( Q1 => q1(i), Q2 => q2(i), C => clk_out, CE => logic1, D => indata(i), R => iddr_reset, S => logic0 ); end generate IDDR_GEN;
NET "indata<1>" LOC = "C19"; NET "indata<2>" LOC = "B19"; NET "indata<3>" LOC = "F18"; NET "q1<0>" LOC = "B20"; NET "indata<4>" LOC = "A19"; NET "q1<1>" LOC = "C18"; NET "indata<5>" LOC = "B17"; NET "q1<2>" LOC = "A20"; NET "indata<6>" LOC = "E20"; NET "q1<3>" LOC = "E18"; NET "indata<7>" LOC = "K18"; NET "q2<0>" LOC = "J19"; NET "q1<4>" LOC = "A18"; NET "q2<1>" LOC = "D19"; NET "q1<5>" LOC = "F17"; NET "q2<2>" LOC = "H18"; NET "q1<6>" LOC = "F20"; NET "q2<3>" LOC = "D18"; NET "q1<7>" LOC = "L19"; NET "q2<4>" LOC = "E17"; NET "q2<5>" LOC = "A17"; NET "q2<6>" LOC = "G20"; NET "q2<7>" LOC = "F22"; NET "clk" LOC = "AA14"; NET "indata<0>" LOC = "B21"; #PINLOCK_END
entity DDRtest is port( clk : in std_logic; reset : in std_logic; lcd_d : inout std_logic_vector(7 downto 4); lcd_rs : out std_logic; lcd_rw : out std_logic; lcd_e : out std_logic; sf_ce0 : out std_logic; rot_a : in std_logic; rot_b : in std_logic; rot_center : in std_logic; btn_east : in std_logic; -- データ書き込み用 btn_west : in std_logic; -- データ読み出し用
sd_a : out std_logic_vector(12 downto 0); sd_dq : inout std_logic_vector(15 downto 0); sd_ba : out std_logic_vector(1 downto 0); sd_ras : out std_logic; sd_cas : out std_logic; sd_we : out std_logic; sd_udm : out std_logic; sd_ldm : out std_logic; sd_udqs : inout std_logic; sd_ldqs : inout std_logic; sd_cs : out std_logic; sd_cke : out std_logic; sd_ck_n : out std_logic; sd_ck_p : out std_logic ); end DDRtest;