URL
https://opencores.org/ocsvn/the_wizardry_project/the_wizardry_project/trunk
Subversion Repositories the_wizardry_project
Compare Revisions
- This comparison shows the changes necessary to convert path
/the_wizardry_project/trunk/Wizardry/VHDL/Wizardry Top Level/Memory Design/MIG_top_00/MIG_data_path_0
- from Rev 23 to Rev 24
- ↔ Reverse comparison
Rev 23 → Rev 24
/MIG_data_path_0.vhd
0,0 → 1,138
------------------------------------------------------------------------------- |
-- Copyright (c) 2005-2007 Xilinx, Inc. |
-- This design is confidential and proprietary of Xilinx, All Rights Reserved. |
------------------------------------------------------------------------------- |
-- ____ ____ |
-- / /\/ / |
-- /___/ \ / Vendor : Xilinx |
-- \ \ \/ Version : $Name: i+IP+131489 $ |
-- \ \ Application : MIG |
-- / / Filename : MIG_data_path_0.vhd |
-- /___/ /\ Date Last Modified : $Date: 2007/09/21 15:23:24 $ |
-- \ \ / \ Date Created : Mon May 2 2005 |
-- \___\/\___\ |
-- |
-- Device : Virtex-4 |
-- Design Name : DDR SDRAM |
-- Description: Instantiates the tap logic and the data write modules. Gives |
-- the rise and the fall data and the calibration information for |
-- IDELAY elements. |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use work.MIG_parameters_0.all; |
library UNISIM; |
use UNISIM.vcomponents.all; |
|
entity MIG_data_path_0 is |
port( |
clk : in std_logic; |
clk90 : in std_logic; |
reset0 : in std_logic; |
reset90 : in std_logic; |
idelay_ctrl_rdy : in std_logic; |
dummy_write_pattern : in std_logic; |
ctrl_dummyread_start : in std_logic; |
wdf_data : in std_logic_vector((DATA_WIDTH*2 - 1) downto 0); |
mask_data : in std_logic_vector((DATA_MASK_WIDTH*2 - 1) downto 0); |
ctrl_wren : in std_logic; |
ctrl_dqs_rst : in std_logic; |
ctrl_dqs_en : in std_logic; |
dqs_delayed : in std_logic_vector((DATA_STROBE_WIDTH - 1) downto 0); |
data_idelay_inc : out std_logic_vector((READENABLE - 1) downto 0); |
data_idelay_ce : out std_logic_vector((READENABLE - 1) downto 0); |
data_idelay_rst : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_inc : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_ce : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_rst : out std_logic_vector((READENABLE - 1) downto 0); |
sel_done : out std_logic; |
dqs_rst : out std_logic; |
dqs_en : out std_logic; |
wr_en : out std_logic; |
wr_data_rise : out std_logic_vector((DATA_WIDTH - 1) downto 0); |
wr_data_fall : out std_logic_vector((DATA_WIDTH - 1) downto 0); |
mask_data_rise : out std_logic_vector((DATA_MASK_WIDTH - 1) downto 0); |
mask_data_fall : out std_logic_vector((DATA_MASK_WIDTH - 1) downto 0) |
); |
end MIG_data_path_0; |
|
architecture arch of MIG_data_path_0 is |
|
component MIG_data_write_0 |
port( |
clk : in std_logic; |
clk90 : in std_logic; |
reset90 : in std_logic; |
wdf_data : in std_logic_vector((DATA_WIDTH*2 - 1) downto 0); |
mask_data : in std_logic_vector((DATA_MASK_WIDTH*2 - 1) downto 0); |
dummy_write_pattern : in std_logic; |
ctrl_wren : in std_logic; |
ctrl_dqs_rst : in std_logic; |
ctrl_dqs_en : in std_logic; |
dqs_rst : out std_logic; |
dqs_en : out std_logic; |
wr_en : out std_logic; |
wr_data_rise : out std_logic_vector((DATA_WIDTH - 1) downto 0); |
wr_data_fall : out std_logic_vector((DATA_WIDTH - 1) downto 0); |
mask_data_rise : out std_logic_vector((DATA_MASK_WIDTH - 1) downto 0); |
mask_data_fall : out std_logic_vector((DATA_MASK_WIDTH - 1) downto 0) |
); |
end component; |
|
component MIG_tap_logic_0 |
port( |
clk : in std_logic; |
reset0 : in std_logic; |
idelay_ctrl_rdy : in std_logic; |
ctrl_dummyread_start : in std_logic; |
dqs_delayed : in std_logic_vector((DATA_STROBE_WIDTH - 1) downto 0); |
data_idelay_inc : out std_logic_vector((READENABLE - 1) downto 0); |
data_idelay_ce : out std_logic_vector((READENABLE - 1) downto 0); |
data_idelay_rst : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_inc : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_ce : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_rst : out std_logic_vector((READENABLE - 1) downto 0); |
sel_done : out std_logic |
); |
end component; |
|
begin |
|
data_write_10: MIG_data_write_0 |
port map ( |
clk => clk, |
clk90 => clk90, |
reset90 => reset90, |
wdf_data => wdf_data, |
mask_data => mask_data, |
dummy_write_pattern => dummy_write_pattern, |
ctrl_wren => ctrl_wren, |
ctrl_dqs_rst => ctrl_dqs_rst, |
ctrl_dqs_en => ctrl_dqs_en, |
dqs_rst => dqs_rst, |
dqs_en => dqs_en, |
wr_en => wr_en, |
wr_data_rise => wr_data_rise, |
wr_data_fall => wr_data_fall, |
mask_data_rise => mask_data_rise, |
mask_data_fall => mask_data_fall |
); |
|
tap_logic_00: MIG_tap_logic_0 |
port map ( |
clk => clk, |
reset0 => reset0, |
idelay_ctrl_rdy => idelay_ctrl_rdy, |
ctrl_dummyread_start => ctrl_dummyread_start, |
dqs_delayed => dqs_delayed, |
data_idelay_inc => data_idelay_inc, |
data_idelay_ce => data_idelay_ce, |
data_idelay_rst => data_idelay_rst, |
dqs_idelay_inc => dqs_idelay_inc, |
dqs_idelay_ce => dqs_idelay_ce, |
dqs_idelay_rst => dqs_idelay_rst, |
sel_done => sel_done |
); |
|
end arch; |
/MIG_tap_logic/MIG_data_tap_inc.vhd
0,0 → 1,141
------------------------------------------------------------------------------- |
-- Copyright (c) 2005-2007 Xilinx, Inc. |
-- This design is confidential and proprietary of Xilinx, All Rights Reserved. |
------------------------------------------------------------------------------- |
-- ____ ____ |
-- / /\/ / |
-- /___/ \ / Vendor : Xilinx |
-- \ \ \/ Version : $Name: i+IP+131489 $ |
-- \ \ Application : MIG |
-- / / Filename : MIG_data_tap_inc.vhd |
-- /___/ /\ Date Last Modified : $Date: 2007/09/21 15:23:24 $ |
-- \ \ / \ Date Created : Mon May 2 2005 |
-- \___\/\___\ |
-- |
-- Device : Virtex-4 |
-- Design Name : DDR SDRAM |
-- Description: The tap logic for calibration of the memory data with respect |
-- to FPGA clock is provided here. According to the edge detection |
-- or not the taps in the IDELAY element of the Virtex4 devices |
-- are either increased or decreased. |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
library UNISIM; |
use UNISIM.vcomponents.all; |
|
entity MIG_data_tap_inc is |
port( |
clk : in std_logic; |
reset : in std_logic; |
data_dlyinc : out std_logic; |
data_dlyce : out std_logic; |
data_dlyrst : out std_logic; |
data_tap_sel_done : out std_logic; |
dqs_sel_done : in std_logic; |
valid_data_tap_count : in std_logic; |
data_tap_count : in std_logic_vector(5 downto 0) |
); |
end MIG_data_tap_inc; |
|
architecture arch of MIG_data_tap_inc is |
|
signal data_dlyinc_clk0 : std_logic; |
signal data_dlyce_clk0 : std_logic; |
signal data_dlyrst_clk0 : std_logic; |
signal data_tap_inc_counter : std_logic_vector(5 downto 0) := "000000"; |
signal data_tap_sel_clk : std_logic; |
signal data_tap_sel_r1 : std_logic; |
signal dqs_sel_done_r : std_logic; |
signal valid_data_tap_count_r : std_logic; |
signal rst_r : std_logic; |
|
begin |
|
data_tap_sel_done <= data_tap_sel_r1; |
data_dlyinc <= data_dlyinc_clk0; |
data_dlyce <= data_dlyce_clk0; |
data_dlyrst <= data_dlyrst_clk0; |
|
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
rst_r <= reset; |
end if; |
end process; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if(rst_r = '1') then |
data_tap_sel_clk <= '0'; |
elsif(data_tap_inc_counter = "000001") then |
data_tap_sel_clk <= '1'; |
end if; |
end if; |
end process; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if(rst_r = '1') then |
data_tap_sel_r1 <= '0'; |
else |
data_tap_sel_r1 <= data_tap_sel_clk; |
end if; |
end if; |
end process; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if(rst_r = '1') then |
dqs_sel_done_r <= '0'; |
elsif(dqs_sel_done = '1') then |
dqs_sel_done_r <= '1'; |
end if; |
end if; |
end process; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if(rst_r = '1') then |
valid_data_tap_count_r <= '0'; |
else |
valid_data_tap_count_r <= valid_data_tap_count; |
end if; |
end if; |
end process; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if(rst_r = '1' or dqs_sel_done_r = '0') then |
data_dlyinc_clk0 <= '0'; |
data_dlyce_clk0 <= '0'; |
data_dlyrst_clk0 <= '1'; |
data_tap_inc_counter <= "000000"; |
elsif(valid_data_tap_count_r = '1') then |
data_dlyinc_clk0 <= '0'; |
data_dlyce_clk0 <= '0'; |
data_dlyrst_clk0 <= '0'; |
data_tap_inc_counter <= data_tap_count; |
elsif(data_tap_inc_counter /= "000000") then -- Data IDELAY incremented |
data_dlyinc_clk0 <= '1'; |
data_dlyce_clk0 <= '1'; |
data_dlyrst_clk0 <= '0'; |
data_tap_inc_counter <= data_tap_inc_counter - '1'; |
else -- Data IDELAY no change mode |
data_dlyinc_clk0 <= '0'; |
data_dlyce_clk0 <= '0'; |
data_dlyrst_clk0 <= '0'; |
data_tap_inc_counter <= "000000"; |
end if; |
end if; |
end process; |
|
end arch; |
/MIG_tap_logic/MIG_tap_ctrl_0.vhd
0,0 → 1,473
------------------------------------------------------------------------------- |
-- Copyright (c) 2005-2007 Xilinx, Inc. |
-- This design is confidential and proprietary of Xilinx, All Rights Reserved. |
------------------------------------------------------------------------------- |
-- ____ ____ |
-- / /\/ / |
-- /___/ \ / Vendor : Xilinx |
-- \ \ \/ Version : $Name: i+IP+131489 $ |
-- \ \ Application : MIG |
-- / / Filename : MIG_tap_ctrl.vhd |
-- /___/ /\ Date Last Modified : $Date: 2007/09/21 15:23:24 $ |
-- \ \ / \ Date Created : Mon May 2 2005 |
-- \___\/\___\ |
-- |
-- Device : Virtex-4 |
-- Design Name : DDR SDRAM |
-- Description: The tap control logic which claculates the relation between the |
-- FPGA clock and the dqs from memory. It delays the dqs so as to |
-- detect the edges of the dqs and then calculates the mid point |
-- so that the data can be registered properly. |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
library UNISIM; |
use UNISIM.vcomponents.all; |
|
entity MIG_tap_ctrl is |
port( |
clk : in std_logic; |
reset : in std_logic; |
rdy_status : in std_logic; |
dqs : in std_logic; |
ctrl_dummyread_start : in std_logic; |
dlyinc : out std_logic; |
dlyce : out std_logic; |
dlyrst : out std_logic; |
sel_done : out std_logic; |
valid_data_tap_count : out std_logic; |
data_tap_count : out std_logic_vector(5 downto 0) |
); |
end MIG_tap_ctrl; |
|
architecture arch of MIG_tap_ctrl is |
|
signal prev_dqs_level : std_logic; |
signal dly_inc : std_logic; |
signal dly_ce : std_logic; |
signal dly_rst : std_logic; |
signal transition : std_logic_vector(1 downto 0); |
signal first_edge : std_logic; |
signal second_edge : std_logic; |
signal second_edge_r1 : std_logic; |
signal second_edge_r2 : std_logic; |
signal second_edge_r3 : std_logic; |
signal transition_rst : std_logic; |
signal sel_complete : std_logic; |
signal tap_counter : std_logic_vector(5 downto 0); |
signal first_edge_tap_count : std_logic_vector(5 downto 0); |
signal second_edge_tap_count : std_logic_vector(5 downto 0); |
signal pulse_width_tap_count : std_logic_vector(5 downto 0); |
signal data_bit_tap_count : std_logic_vector(5 downto 0); |
signal state : std_logic_vector(2 downto 0); |
signal idelay_rst_idle : std_logic; |
signal idelay_rst_idle_r1 : std_logic; |
signal idelay_rst_idle_r2 : std_logic; |
signal idelay_rst_idle_r3 : std_logic; |
signal idelay_rst_idle_r4 : std_logic; |
signal idelay_rst_idle_r5 : std_logic; |
signal idelay_rst_idle_r6 : std_logic; |
signal idelay_inc_idle : std_logic; |
signal idelay_inc_idle_r1 : std_logic; |
signal idelay_inc_idle_r2 : std_logic; |
signal idelay_inc_idle_r3 : std_logic; |
signal idelay_inc_idle_r4 : std_logic; |
signal idelay_inc_idle_r5 : std_logic; |
signal idelay_inc_idle_r6 : std_logic; |
signal detect_edge_idle : std_logic; |
signal detect_edge_idle_r1 : std_logic; |
signal detect_edge_idle_r2 : std_logic; |
signal detect_edge_idle_r3 : std_logic; |
signal detect_edge_idle_r4 : std_logic; |
signal detect_edge_idle_r5 : std_logic; |
signal detect_edge_idle_r6 : std_logic; |
signal flag : std_logic_vector(3 downto 0); |
signal dly_after_first_cnt : std_logic_vector(3 downto 0); |
signal pulse_center_tap_count : std_logic_vector(5 downto 0); |
signal valid_data_count : std_logic; |
signal data_count_valid : std_logic; |
signal dly_after_first : std_logic_vector(3 downto 0); |
signal curr_dqs_level : std_logic; |
signal delay_sel_done : std_logic; |
signal reset_int : std_logic; |
signal rst_r : std_logic; |
|
constant IDELAY_RST : std_logic_vector(2 downto 0) := "000"; |
constant IDLE : std_logic_vector(2 downto 0) := "001"; |
constant IDELAY_INC : std_logic_vector(2 downto 0) := "010"; |
constant DETECT_EDGE : std_logic_vector(2 downto 0) := "011"; |
|
attribute syn_preserve : boolean; |
attribute syn_preserve of pulse_width_tap_count : signal is true ; |
|
begin |
|
process(clk) |
begin |
if clk'event and clk = '1' then |
rst_r <= reset; |
end if; |
end process; |
|
dlyinc <= dly_inc; |
dlyce <= dly_ce; |
dlyrst <= dly_rst; |
sel_done <= sel_complete; |
valid_data_tap_count <= valid_data_count; |
data_tap_count <= data_bit_tap_count; |
|
data_count_valid <= '1' when (second_edge_r3 = '1') or (tap_counter = "111111") else '0'; |
reset_int <= not(rdy_status) or rst_r; |
|
delay_sel_done <= '1' when ((second_edge = '1') or (tap_counter = "111111")) else |
'0' when (ctrl_dummyread_start = '0') else |
sel_complete; |
|
dly_after_first <= "1001" when ((transition = "01") and (first_edge = '0')) else |
(dly_after_first_cnt - '1') when ((dly_after_first_cnt /= "0000") |
and (dly_inc = '1')) else |
dly_after_first_cnt; |
|
curr_dqs_level <= dqs; |
|
-- Shift registers for controls |
process(clk) |
begin |
if clk'event and clk = '1' then |
if reset_int = '1' then |
second_edge_r1 <= '0'; |
second_edge_r2 <= '0'; |
second_edge_r3 <= '0'; |
idelay_rst_idle_r1 <= '0'; |
idelay_rst_idle_r2 <= '0'; |
idelay_rst_idle_r3 <= '0'; |
idelay_rst_idle_r4 <= '0'; |
idelay_rst_idle_r5 <= '0'; |
idelay_rst_idle_r6 <= '0'; |
idelay_inc_idle_r1 <= '0'; |
idelay_inc_idle_r2 <= '0'; |
idelay_inc_idle_r3 <= '0'; |
idelay_inc_idle_r4 <= '0'; |
idelay_inc_idle_r5 <= '0'; |
idelay_inc_idle_r6 <= '0'; |
detect_edge_idle_r1 <= '0'; |
detect_edge_idle_r2 <= '0'; |
detect_edge_idle_r3 <= '0'; |
detect_edge_idle_r4 <= '0'; |
detect_edge_idle_r5 <= '0'; |
detect_edge_idle_r6 <= '0'; |
valid_data_count <= '0'; |
else |
second_edge_r1 <= second_edge; |
second_edge_r2 <= second_edge_r1; |
second_edge_r3 <= second_edge_r2; |
idelay_rst_idle_r1 <= idelay_rst_idle; |
idelay_rst_idle_r2 <= idelay_rst_idle_r1; |
idelay_rst_idle_r3 <= idelay_rst_idle_r2; |
idelay_rst_idle_r4 <= idelay_rst_idle_r3; |
idelay_rst_idle_r5 <= idelay_rst_idle_r4; |
idelay_rst_idle_r6 <= idelay_rst_idle_r5; |
idelay_inc_idle_r1 <= idelay_inc_idle; |
idelay_inc_idle_r2 <= idelay_inc_idle_r1; |
idelay_inc_idle_r3 <= idelay_inc_idle_r2; |
idelay_inc_idle_r4 <= idelay_inc_idle_r3; |
idelay_inc_idle_r5 <= idelay_inc_idle_r4; |
idelay_inc_idle_r6 <= idelay_inc_idle_r5; |
detect_edge_idle_r1 <= detect_edge_idle; |
detect_edge_idle_r2 <= detect_edge_idle_r1; |
detect_edge_idle_r3 <= detect_edge_idle_r2; |
detect_edge_idle_r4 <= detect_edge_idle_r3; |
detect_edge_idle_r5 <= detect_edge_idle_r4; |
detect_edge_idle_r6 <= detect_edge_idle_r5; |
valid_data_count <= data_count_valid; |
end if; |
end if; |
end process; |
|
-- Tap Delay Selection Complete for Data bus associated with a dqs |
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
sel_complete <= '0'; |
else |
sel_complete <= delay_sel_done; |
end if; |
end if; |
end process; |
|
|
-- Start detection of second transition only after 10 taps from first transition |
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
dly_after_first_cnt <= "0000"; |
else |
dly_after_first_cnt <= dly_after_first; |
end if; |
end if; |
end process; |
|
|
-- Tap Counter |
process(clk) |
begin |
if(clk'event and clk = '1') then |
if ((reset_int = '1') or (tap_counter = "111111")) then |
tap_counter <= "000000"; |
elsif (dly_inc = '1') then |
tap_counter <= tap_counter + '1'; |
end if; |
end if; |
end process; |
|
-- Tap value for Data IDELAY circuit |
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
first_edge_tap_count <= "000000"; |
elsif ((transition = "01") and (first_edge = '0')) then |
first_edge_tap_count <= tap_counter; |
end if; |
end if; |
end process; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
second_edge_tap_count <= "000000"; |
elsif ((transition = "10") and (second_edge = '0')) then |
second_edge_tap_count <= tap_counter; |
end if; |
end if; |
end process; |
|
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
pulse_width_tap_count <= "000000"; |
elsif (second_edge_r1 = '1') then |
pulse_width_tap_count <= (second_edge_tap_count - first_edge_tap_count); |
end if; |
end if; |
end process; |
|
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
pulse_center_tap_count <= "000000"; |
elsif (second_edge_r2 = '1') then |
pulse_center_tap_count <= '0' & pulse_width_tap_count(5 downto 1); |
-- Shift right to divide by 2 and find pulse center |
end if; |
end if; |
end process; |
|
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
data_bit_tap_count <= "000000"; |
elsif (second_edge_r3 = '1') then -- 2 edges detected |
data_bit_tap_count <= first_edge_tap_count + pulse_center_tap_count; |
elsif ((transition = "01") and ((tap_counter = "111111"))) then |
if (first_edge_tap_count(5) = '0') then |
data_bit_tap_count <= first_edge_tap_count + "010000"; |
else |
data_bit_tap_count <= first_edge_tap_count - "010000"; |
end if; |
elsif ((transition = "00") and ((tap_counter = "111111"))) then |
data_bit_tap_count <= "100000"; |
end if; |
end if; |
end process; |
|
|
-- Logic required to determine whether the registered dqs is on the edge of |
-- meeting setup time in the FPGA clock domain. |
-- If dqs is on the edge, then the vector 'flag' will not be "1111" or "0000" and |
-- edge detection will not be executed. |
-- If dqs is not on the edge, then the vector 'flag' will be "1111" or "0000" and |
-- edge detection will be executed. |
|
process(clk) |
begin |
if clk'event and clk = '1' then |
if (reset_int = '1') then |
flag <= (others => '0'); |
elsif (detect_edge_idle_r3 = '1' or idelay_inc_idle_r3 = '1' or |
idelay_rst_idle_r3 = '1') then |
if (curr_dqs_level /= prev_dqs_level) then |
flag(0) <= '0'; |
else |
flag(0) <= '1'; |
end if; |
elsif (detect_edge_idle_r4 = '1' or idelay_inc_idle_r4 = '1' or |
idelay_rst_idle_r4 = '1') then |
if (curr_dqs_level /= prev_dqs_level) then |
flag(1) <= '0'; |
else |
flag(1) <= '1'; |
end if; |
elsif (detect_edge_idle_r5 = '1' or idelay_inc_idle_r5 = '1' or |
idelay_rst_idle_r5 = '1') then |
if (curr_dqs_level /= prev_dqs_level) then |
flag(2) <= '0'; |
else |
flag(2) <= '1'; |
end if; |
elsif (detect_edge_idle_r6 = '1' or idelay_inc_idle_r6 = '1' or |
idelay_rst_idle_r6 = '1') then |
if (curr_dqs_level /= prev_dqs_level) then |
flag(3) <= '0'; |
else |
flag(3) <= '1'; |
end if; |
|
end if; |
end if; |
end process; |
|
|
-- First and second edge assignment logic |
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
transition(1 downto 0) <= "00"; |
elsif ((dly_after_first_cnt = "0000") and (state = DETECT_EDGE) and |
((flag = X"0") or (flag = X"F"))) then |
if ((curr_dqs_level /= prev_dqs_level) and (transition_rst = '0') and |
(tap_counter > "000000")) then |
transition <= transition + '1'; |
end if; |
elsif (transition_rst = '1') then |
transition <= "00"; |
else |
transition <= transition; |
end if; |
end if; |
end process; |
|
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then |
transition_rst <= '0'; |
first_edge <= '0'; |
second_edge <= '0'; |
else |
case transition is |
when "01" => |
first_edge <= '1'; |
|
when "10" => |
if (transition_rst = '1') then |
second_edge <= '0'; |
transition_rst <= '0'; |
else |
second_edge <= '1'; |
transition_rst <= '1'; |
end if; |
when others => |
first_edge <= '0'; |
second_edge <= '0'; |
end case; |
end if; |
end if; |
end process; |
|
-- State Machine for edge detection and midpoint determination |
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (reset_int = '1') then -- dqs IDELAY in reset |
dly_rst <= '1'; |
dly_ce <= '0'; |
dly_inc <= '0'; |
idelay_rst_idle <= '0'; |
detect_edge_idle <= '0'; |
idelay_inc_idle <= '0'; |
prev_dqs_level <= curr_dqs_level; |
state(2 downto 0) <= IDELAY_RST; |
elsif ((ctrl_dummyread_start = '1') and (sel_complete = '0')) then |
case state is |
when "000" => -- IDELAY_RST |
dly_rst <= '1'; |
dly_ce <= '0'; |
dly_inc <= '0'; |
idelay_rst_idle <= '1'; |
state(2 downto 0) <= IDLE; |
when "001" => -- IDLE |
dly_rst <= '0'; |
dly_ce <= '0'; |
dly_inc <= '0'; |
idelay_rst_idle <= '0'; |
detect_edge_idle <= '0'; |
idelay_inc_idle <= '0'; |
if (idelay_rst_idle_r5 = '1') then |
state(2 downto 0) <= IDELAY_INC; |
elsif ((idelay_inc_idle_r6 = '1') or ((detect_edge_idle_r6 = '1') |
and (second_edge_r2 = '0') and (tap_counter /= "111111"))) then |
state(2 downto 0) <= DETECT_EDGE; |
else |
state(2 downto 0) <= IDLE; |
end if; |
when "010" => -- IDELAY_INC |
dly_rst <= '0'; |
dly_ce <= '1'; |
dly_inc <= '1'; |
idelay_inc_idle <= '1'; |
state(2 downto 0) <= IDLE; |
if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then |
prev_dqs_level <= curr_dqs_level; |
else |
prev_dqs_level <= prev_dqs_level; |
end if; |
|
when "011" => -- DETECT_EDGE |
dly_rst <= '0'; |
dly_ce <= '1'; |
dly_inc <= '1'; |
detect_edge_idle <= '1'; |
state(2 downto 0) <= IDLE; |
if((flag(3 downto 0) = X"0") or (flag(3 downto 0) = X"F")) then |
prev_dqs_level <= curr_dqs_level; |
else |
prev_dqs_level <= prev_dqs_level; |
end if; |
when others => |
dly_rst <= '0'; |
dly_ce <= '0'; |
dly_inc <= '0'; |
idelay_rst_idle <= '0'; |
detect_edge_idle <= '0'; |
idelay_inc_idle <= '0'; |
prev_dqs_level <= curr_dqs_level; |
state(2 downto 0) <= IDLE; |
end case; |
else |
dly_rst <= '0'; |
dly_ce <= '0'; |
dly_inc <= '0'; |
idelay_rst_idle <= '0'; |
detect_edge_idle <= '0'; |
idelay_inc_idle <= '0'; |
prev_dqs_level <= curr_dqs_level; |
state <= IDELAY_RST; |
end if; |
end if; |
end process; |
|
end arch; |
/MIG_tap_logic/MIG_tap_logic_0.vhd
0,0 → 1,152
------------------------------------------------------------------------------- |
-- Copyright (c) 2005-2007 Xilinx, Inc. |
-- This design is confidential and proprietary of Xilinx, All Rights Reserved. |
------------------------------------------------------------------------------- |
-- ____ ____ |
-- / /\/ / |
-- /___/ \ / Vendor : Xilinx |
-- \ \ \/ Version : $Name: i+IP+131489 $ |
-- \ \ Application : MIG |
-- / / Filename : MIG_tap_logic_0.vhd |
-- /___/ /\ Date Last Modified : $Date: 2007/09/21 15:23:24 $ |
-- \ \ / \ Date Created : Mon May 2 2005 |
-- \___\/\___\ |
-- |
-- Device : Virtex-4 |
-- Design Name : DDR SDRAM |
-- Description: Instantiates the tap_cntrl and the data_tap_inc modules. |
-- Used for calibration of the memory data with the FPGA clock. |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use work.MIG_parameters_0.all; |
library UNISIM; |
use UNISIM.vcomponents.all; |
|
entity MIG_tap_logic_0 is |
port( |
clk : in std_logic; |
reset0 : in std_logic; |
idelay_ctrl_rdy : in std_logic; |
ctrl_dummyread_start : in std_logic; |
dqs_delayed : in std_logic_vector((DATA_STROBE_WIDTH - 1) downto 0); |
sel_done : out std_logic; |
data_idelay_inc : out std_logic_vector((READENABLE - 1) downto 0); |
data_idelay_ce : out std_logic_vector((READENABLE - 1) downto 0); |
data_idelay_rst : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_inc : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_ce : out std_logic_vector((READENABLE - 1) downto 0); |
dqs_idelay_rst : out std_logic_vector((READENABLE - 1) downto 0) |
); |
end MIG_tap_logic_0; |
|
architecture arch of MIG_tap_logic_0 is |
|
component MIG_tap_ctrl |
port( |
clk : in std_logic; |
reset : in std_logic; |
rdy_status : in std_logic; |
dqs : in std_logic; |
ctrl_dummyread_start : in std_logic; |
dlyinc : out std_logic; |
dlyce : out std_logic; |
dlyrst : out std_logic; |
sel_done : out std_logic; |
valid_data_tap_count : out std_logic; |
data_tap_count : out std_logic_vector(5 downto 0) |
); |
end component; |
|
component MIG_data_tap_inc |
port( |
clk : in std_logic; |
reset : in std_logic; |
data_dlyinc : out std_logic; |
data_dlyce : out std_logic; |
data_dlyrst : out std_logic; |
data_tap_sel_done : out std_logic; |
dqs_sel_done : in std_logic; |
valid_data_tap_count : in std_logic; |
data_tap_count : in std_logic_vector(5 downto 0) |
); |
end component; |
|
signal data_tap_select : std_logic_vector((READENABLE - 1) downto 0); |
signal dqs_tap_sel_done : std_logic_vector((READENABLE - 1) downto 0); |
signal valid_tap_count : std_logic_vector((READENABLE - 1) downto 0); |
signal data_tap_inc_done : std_logic; |
signal tap_sel_done : std_logic; |
signal rst_r : std_logic; |
|
signal data_tap_count0 : std_logic_vector(5 downto 0); |
|
|
begin |
|
-- For controller to stop dummy reads |
sel_done <= tap_sel_done; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
rst_r <= reset0; |
end if; |
end process; |
|
process(clk) |
begin |
if(clk'event and clk = '1') then |
if (rst_r = '1') then |
data_tap_inc_done <= '0'; |
tap_sel_done <= '0'; |
else |
data_tap_inc_done <= data_tap_select(0) ; |
tap_sel_done <= data_tap_inc_done; |
|
end if; |
end if; |
end process; |
|
--********************************************************************** |
-- tap_ctrl instances for ddr_dqs strobes |
--********************************************************************** |
|
|
tap_ctrl_0: MIG_tap_ctrl |
port map ( |
clk => clk, |
reset => reset0, |
rdy_status => idelay_ctrl_rdy, |
dqs => dqs_delayed(3), |
ctrl_dummyread_start => ctrl_dummyread_start, |
dlyinc => dqs_idelay_inc(0), |
dlyce => dqs_idelay_ce(0), |
dlyrst => dqs_idelay_rst(0), |
sel_done => dqs_tap_sel_done(0), |
valid_data_tap_count => valid_tap_count(0), |
data_tap_count => data_tap_count0(5 downto 0) |
); |
|
|
--********************************************************************** |
-- instances of data_tap_inc for each dqs and associated tap_ctrl |
--********************************************************************** |
|
|
data_tap_inc_0: MIG_data_tap_inc |
port map ( |
clk => clk, |
reset => reset0, |
data_dlyinc => data_idelay_inc(0), |
data_dlyce => data_idelay_ce(0), |
data_dlyrst => data_idelay_rst(0), |
data_tap_sel_done => data_tap_select(0), |
dqs_sel_done => dqs_tap_sel_done(0), |
valid_data_tap_count => valid_tap_count(0), |
data_tap_count => data_tap_count0(5 downto 0) |
); |
|
|
end arch; |
/MIG_data_write_0.vhd
0,0 → 1,168
------------------------------------------------------------------------------- |
-- Copyright (c) 2005-2007 Xilinx, Inc. |
-- This design is confidential and proprietary of Xilinx, All Rights Reserved. |
------------------------------------------------------------------------------- |
-- ____ ____ |
-- / /\/ / |
-- /___/ \ / Vendor : Xilinx |
-- \ \ \/ Version : $Name: i+IP+131489 $ |
-- \ \ Application : MIG |
-- / / Filename : MIG_data_write_0.vhd |
-- /___/ /\ Date Last Modified : $Date: 2007/09/21 15:23:24 $ |
-- \ \ / \ Date Created : Mon May 2 2005 |
-- \___\/\___\ |
-- |
-- Device : Virtex-4 |
-- Design Name : DDR SDRAM |
-- Description: Splits the user data into the rise data and the fall data. |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use work.MIG_parameters_0.all; |
library UNISIM; |
use UNISIM.vcomponents.all; |
|
entity MIG_data_write_0 is |
port( |
clk : in std_logic; |
clk90 : in std_logic; |
reset90 : in std_logic; |
wdf_data : in std_logic_vector((DATA_WIDTH*2 - 1) downto 0); |
mask_data : in std_logic_vector((DATA_MASK_WIDTH*2 - 1) downto 0); |
dummy_write_pattern : in std_logic; |
ctrl_wren : in std_logic; |
ctrl_dqs_rst : in std_logic; |
ctrl_dqs_en : in std_logic; |
dqs_rst : out std_logic; |
dqs_en : out std_logic; |
wr_en : out std_logic; |
wr_data_rise : out std_logic_vector((DATA_WIDTH - 1) downto 0); |
wr_data_fall : out std_logic_vector((DATA_WIDTH - 1) downto 0); |
mask_data_rise : out std_logic_vector((DATA_MASK_WIDTH - 1) downto 0); |
mask_data_fall : out std_logic_vector((DATA_MASK_WIDTH - 1) downto 0) |
); |
end MIG_data_write_0; |
|
architecture arch of MIG_data_write_0 is |
|
signal wr_en_clk270_r1 : std_logic; |
signal wr_en_clk90_r3 : std_logic; |
signal dqs_rst_r1 : std_logic; |
signal dqs_en_r1 : std_logic; |
signal dqs_en_r2 : std_logic; |
signal dummy_flag : std_logic; |
signal dummy_rise_pattern : std_logic_vector((DATA_WIDTH - 1) downto 0); |
signal dummy_fall_pattern : std_logic_vector((DATA_WIDTH - 1) downto 0); |
signal dummy_write_pattern_270 : std_logic; |
signal dummy_write_pattern_90 : std_logic; |
signal dummy_flag1 : std_logic; |
|
signal patA : std_logic_vector(143 downto 0); |
signal pat5 : std_logic_vector(143 downto 0); |
signal pat9 : std_logic_vector(143 downto 0); |
signal pat6 : std_logic_vector(143 downto 0); |
signal rst90_r : std_logic; |
begin |
|
dqs_rst <= dqs_rst_r1; |
dqs_en <= dqs_en_r2; |
wr_en <= wr_en_clk90_r3; |
|
patA <= X"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; |
pat5 <= X"555555555555555555555555555555555555"; |
pat9 <= X"999999999999999999999999999999999999"; |
pat6 <= X"666666666666666666666666666666666666"; |
|
process(clk90) |
begin |
if(clk90'event and clk90 = '1') then |
rst90_r <= reset90; |
end if; |
end process; |
|
process(clk90) |
begin |
if(clk90'event and clk90 = '0') then |
wr_en_clk270_r1 <= ctrl_wren; |
dqs_rst_r1 <= ctrl_dqs_rst; |
dqs_en_r1 <= not ctrl_dqs_en; |
end if; |
end process; |
|
|
process(clk) |
begin |
if(clk'event and clk = '0') then |
dqs_en_r2 <= dqs_en_r1; |
end if; |
end process; |
|
process(clk90) |
begin |
if(clk90'event and clk90 = '1') then |
wr_en_clk90_r3 <= wr_en_clk270_r1; |
end if; |
end process; |
|
process(clk90) |
begin |
if(clk90'event and clk90 = '0') then |
dummy_write_pattern_270 <= dummy_write_pattern; |
end if; |
end process; |
|
process(clk90) |
begin |
if(clk90'event and clk90 = '1') then |
dummy_write_pattern_90 <= dummy_write_pattern_270; |
end if; |
end process; |
|
process(clk90) |
begin |
if(clk90'event and clk90 = '1') then |
if(rst90_r = '1') then |
dummy_flag <= '0'; |
elsif(dummy_write_pattern_90 = '1') then |
if(dummy_flag = '1') then |
dummy_rise_pattern <= patA((DATA_WIDTH - 1) downto 0); |
else |
dummy_rise_pattern <= pat9((DATA_WIDTH - 1) downto 0); |
end if; |
dummy_flag <= not dummy_flag; |
end if; |
end if; |
end process; |
|
process(clk90) |
begin |
if(clk90'event and clk90 = '1') then |
if(rst90_r = '1') then |
dummy_flag1 <= '0'; |
elsif(dummy_write_pattern_90 = '1') then |
if(dummy_flag1 = '1') then |
dummy_fall_pattern <= pat5((DATA_WIDTH - 1) downto 0); |
else |
dummy_fall_pattern <= pat6((DATA_WIDTH - 1) downto 0); |
end if; |
dummy_flag1 <= not dummy_flag1; |
end if; |
end if; |
end process; |
|
|
wr_data_rise <= dummy_rise_pattern when (dummy_write_pattern_90 = '1') |
else wdf_data((DATA_WIDTH*2 - 1) downto data_width); |
wr_data_fall <= dummy_fall_pattern when (dummy_write_pattern_90 = '1') |
else wdf_data((DATA_WIDTH - 1) downto 0); |
|
mask_data_rise <= (others => '0') when (dummy_write_pattern_90 = '1' or |
wr_en_clk90_r3 = '0') else |
mask_data((DATA_MASK_WIDTH*2 - 1) downto data_mask_width); |
mask_data_fall <= (others => '0') when (dummy_write_pattern_90 = '1' or |
wr_en_clk90_r3 = '0') else |
mask_data((DATA_MASK_WIDTH - 1) downto 0); |
|
|
end arch; |