diff --git a/lib/SDRAM/ddr_sdr_v1_5/src/ctrl_sdr_wb32.vhd b/lib/SDRAM/ddr_sdr_v1_5/src/ctrl_sdr_wb32.vhd index 66c4b47..31d0a3e 100644 --- a/lib/SDRAM/ddr_sdr_v1_5/src/ctrl_sdr_wb32.vhd +++ b/lib/SDRAM/ddr_sdr_v1_5/src/ctrl_sdr_wb32.vhd @@ -33,6 +33,7 @@ entity ctrl_sdr_wb32 is Generic ( F_SYSCLK : real := 100.0; + F_SDRCLK_IN : real := 100.0; F_SDRCLK : real := 100.0; FIFO_DEPTH : integer := 4; TPD_BOARD_SIM : time := 0 ns @@ -117,6 +118,7 @@ begin inst_sdram_phy : entity work.sdram_phy Generic map ( + F_SDRCLK_IN => F_SDRCLK_IN, F_SDRCLK => F_SDRCLK, TPD_BOARD_SIM => TPD_BOARD_SIM ) diff --git a/lib/SDRAM/ddr_sdr_v1_5/src/sdr_clk_cycloneive.vhd b/lib/SDRAM/ddr_sdr_v1_5/src/sdr_clk_cycloneive.vhd new file mode 100644 index 0000000..97efb56 --- /dev/null +++ b/lib/SDRAM/ddr_sdr_v1_5/src/sdr_clk_cycloneive.vhd @@ -0,0 +1,230 @@ +-- megafunction wizard: %ALTPLL% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altpll + +-- ============================================================ +-- File Name: sdram_pll.vhd +-- Megafunction Name(s): +-- altpll +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 15.0.0 Build 145 04/22/2015 SJ Web Edition +-- ************************************************************ + + +--Copyright (C) 1991-2015 Altera Corporation. All rights reserved. +--Your use of Altera Corporation's design tools, logic functions +--and other software and tools, and its AMPP partner logic +--functions, and any output files from any of the foregoing +--(including device programming or simulation files), and any +--associated documentation or information are expressly subject +--to the terms and conditions of the Altera Program License +--Subscription Agreement, the Altera Quartus II License Agreement, +--the Altera MegaCore Function License Agreement, or other +--applicable license agreement, including, without limitation, +--that your use is for the sole purpose of programming logic +--devices manufactured by Altera and sold by Altera or its +--authorized distributors. Please refer to the applicable +--agreement for further details. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +USE WORK.utils_pkg.ALL; + +entity sdram_clk is + generic + ( + F_SDRCLK_IN : real := 100.0; + F_SDRCLK_OUT : real := 100.0; + clk0_out_phaseshift_ps : integer := 0; + clk1_out_phaseshift_ps : integer := 0 + ); + port + ( + -- Clocks and Reset + rst : in std_logic; -- external async reset, low active + clk_in : in std_logic; -- system clock (e.g. 100MHz), from board + clk_fb_in : in std_logic; -- feedback clock + clk0_0_out : out std_logic; -- System clock #0, dcm#0 output 0° + clk1_0_out : out std_logic; -- System clock #1 (e.g. clock for DDR-SDRAM data capture), dcm#1 output 0° + locked_out : out std_logic -- DCM locked status + ); +end; + +ARCHITECTURE SYN OF sdram_clk IS + + SIGNAL sub_wire0 : STD_LOGIC ; + SIGNAL sub_wire1 : STD_LOGIC_VECTOR (1 DOWNTO 0); + SIGNAL sub_wire2_bv : BIT_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire2 : STD_LOGIC_VECTOR (0 DOWNTO 0); + SIGNAL sub_wire3 : STD_LOGIC_VECTOR (4 DOWNTO 0); + SIGNAL sub_wire4 : STD_LOGIC ; + SIGNAL sub_wire5 : STD_LOGIC ; + SIGNAL sub_wire6 : STD_LOGIC ; + + + + COMPONENT altpll + GENERIC ( + bandwidth_type : STRING; + clk0_divide_by : NATURAL; + clk0_duty_cycle : NATURAL; + clk0_multiply_by : NATURAL; + clk0_phase_shift : STRING; + clk1_divide_by : NATURAL; + clk1_duty_cycle : NATURAL; + clk1_multiply_by : NATURAL; + clk1_phase_shift : STRING; + compensate_clock : STRING; + inclk0_input_frequency : NATURAL; + intended_device_family : STRING; + lpm_hint : STRING; + lpm_type : STRING; + operation_mode : STRING; + pll_type : STRING; + port_activeclock : STRING; + port_areset : STRING; + port_clkbad0 : STRING; + port_clkbad1 : STRING; + port_clkloss : STRING; + port_clkswitch : STRING; + port_configupdate : STRING; + port_fbin : STRING; + port_inclk0 : STRING; + port_inclk1 : STRING; + port_locked : STRING; + port_pfdena : STRING; + port_phasecounterselect : STRING; + port_phasedone : STRING; + port_phasestep : STRING; + port_phaseupdown : STRING; + port_pllena : STRING; + port_scanaclr : STRING; + port_scanclk : STRING; + port_scanclkena : STRING; + port_scandata : STRING; + port_scandataout : STRING; + port_scandone : STRING; + port_scanread : STRING; + port_scanwrite : STRING; + port_clk0 : STRING; + port_clk1 : STRING; + port_clk2 : STRING; + port_clk3 : STRING; + port_clk4 : STRING; + port_clk5 : STRING; + port_clkena0 : STRING; + port_clkena1 : STRING; + port_clkena2 : STRING; + port_clkena3 : STRING; + port_clkena4 : STRING; + port_clkena5 : STRING; + port_extclk0 : STRING; + port_extclk1 : STRING; + port_extclk2 : STRING; + port_extclk3 : STRING; + self_reset_on_loss_lock : STRING; + width_clock : NATURAL + ); + PORT ( + areset : IN STD_LOGIC ; + inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0); + clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0); + locked : OUT STD_LOGIC + ); + END COMPONENT; + +BEGIN + sub_wire2_bv(0 DOWNTO 0) <= "0"; + sub_wire2 <= To_stdlogicvector(sub_wire2_bv); + sub_wire0 <= clk_in; + sub_wire1 <= sub_wire2(0 DOWNTO 0) & sub_wire0; + sub_wire5 <= sub_wire3(1); + sub_wire4 <= sub_wire3(0); + clk0_0_out <= sub_wire4; + clk1_0_out <= sub_wire5; + locked_out <= sub_wire6; + + altpll_component : altpll + GENERIC MAP ( + bandwidth_type => "AUTO", + clk0_divide_by => UTILS_FREQ_D(F_SDRCLK_IN, F_SDRCLK_OUT), + clk0_duty_cycle => 50, + clk0_multiply_by => UTILS_FREQ_M(F_SDRCLK_IN, F_SDRCLK_OUT), + clk0_phase_shift => integer'image(clk0_out_phaseshift_ps), + clk1_divide_by => UTILS_FREQ_D(F_SDRCLK_IN, F_SDRCLK_OUT), + clk1_duty_cycle => 50, + clk1_multiply_by => UTILS_FREQ_M(F_SDRCLK_IN, F_SDRCLK_OUT), + clk1_phase_shift => integer'image(clk1_out_phaseshift_ps), + compensate_clock => "CLK0", + inclk0_input_frequency => integer(1000.0*UTILS_PERIOD_NS(F_SDRCLK_IN)), -- ps + intended_device_family => "Cyclone IV E", + lpm_hint => "CBX_MODULE_PREFIX=sdram_pll", + lpm_type => "altpll", + operation_mode => "NORMAL", + pll_type => "AUTO", + port_activeclock => "PORT_UNUSED", + port_areset => "PORT_USED", + port_clkbad0 => "PORT_UNUSED", + port_clkbad1 => "PORT_UNUSED", + port_clkloss => "PORT_UNUSED", + port_clkswitch => "PORT_UNUSED", + port_configupdate => "PORT_UNUSED", + port_fbin => "PORT_UNUSED", + port_inclk0 => "PORT_USED", + port_inclk1 => "PORT_UNUSED", + port_locked => "PORT_USED", + port_pfdena => "PORT_UNUSED", + port_phasecounterselect => "PORT_UNUSED", + port_phasedone => "PORT_UNUSED", + port_phasestep => "PORT_UNUSED", + port_phaseupdown => "PORT_UNUSED", + port_pllena => "PORT_UNUSED", + port_scanaclr => "PORT_UNUSED", + port_scanclk => "PORT_UNUSED", + port_scanclkena => "PORT_UNUSED", + port_scandata => "PORT_UNUSED", + port_scandataout => "PORT_UNUSED", + port_scandone => "PORT_UNUSED", + port_scanread => "PORT_UNUSED", + port_scanwrite => "PORT_UNUSED", + port_clk0 => "PORT_USED", + port_clk1 => "PORT_USED", + port_clk2 => "PORT_UNUSED", + port_clk3 => "PORT_UNUSED", + port_clk4 => "PORT_UNUSED", + port_clk5 => "PORT_UNUSED", + port_clkena0 => "PORT_UNUSED", + port_clkena1 => "PORT_UNUSED", + port_clkena2 => "PORT_UNUSED", + port_clkena3 => "PORT_UNUSED", + port_clkena4 => "PORT_UNUSED", + port_clkena5 => "PORT_UNUSED", + port_extclk0 => "PORT_UNUSED", + port_extclk1 => "PORT_UNUSED", + port_extclk2 => "PORT_UNUSED", + port_extclk3 => "PORT_UNUSED", + self_reset_on_loss_lock => "OFF", + width_clock => 5 + ) + PORT MAP ( + areset => rst, + inclk => sub_wire1, + clk => sub_wire3, + locked => sub_wire6 + ); + + + +END SYN; diff --git a/lib/SDRAM/ddr_sdr_v1_5/src/sdr_phy_de0nano.vhd b/lib/SDRAM/ddr_sdr_v1_5/src/sdr_phy_de0nano.vhd new file mode 100644 index 0000000..1da4209 --- /dev/null +++ b/lib/SDRAM/ddr_sdr_v1_5/src/sdr_phy_de0nano.vhd @@ -0,0 +1,248 @@ +------------------------------------------------------------------------- +-- Project: SDRAM controller +-- This file: DDR physical layer (Virtex-4 specific) +-- +-- Copyright (C) 2007 J. Ahrensfeld +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- For questions and ideas, please contact the author at jens@jayfield.org +-- +-------------------------------------------------------------------------- + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.numeric_std.ALL; + +use work.sdram_const.all; +use work.sdram_config.all; +use work.sdram_types.all; + +entity sdram_phy is + Generic + ( + F_SDRCLK_IN : real := 100.0; + F_SDRCLK : real := 100.0; + TPD_BOARD_SIM : time := 0 ns + ); + Port + ( + rst : in STD_LOGIC; + clk : in STD_LOGIC; + clk_fb : in STD_LOGIC; + clk0_out : out STD_LOGIC; + rst0_out : out STD_LOGIC; + phy_in : in phy_in_t; + phy_out : out phy_out_t; + phy_ctrl : in phy_ctrl_t; + part_clk : out STD_LOGIC; + part_dqm : out unsigned(PART_DM_WIDTH-1 downto 0); + part_data : inout unsigned(PART_DATA_WIDTH-1 downto 0); + part_ba : out unsigned(PART_BANK_WIDTH-1 downto 0); + part_addr : out unsigned(PART_ADDR_WIDTH-1 downto 0); + part_cs_n : out STD_LOGIC; + part_we_n : out STD_LOGIC; + part_cas_n : out STD_LOGIC; + part_ras_n : out STD_LOGIC; + part_cke : out STD_LOGIC + ); +end sdram_phy; + +architecture tech of sdram_phy is + + signal drive : std_logic; + signal data_reg_r : unsigned(BUS_DATA_WIDTH-1 downto 0); + signal part_ctrl_reg : part_ctrl_t; + signal we_reg : std_logic; + + signal clk0 : std_logic; + signal clk0_temp : std_logic; + signal rst0 : std_logic; + signal clk0_rd : std_logic; + + signal locked : std_logic; + signal error : std_logic; + + type u_tag_array_t is array (natural range 0 to 4) of user_tag_t; + signal u_tag_pipe : u_tag_array_t; + + attribute KEEP : string; + attribute KEEP of clk0 : signal is "TRUE"; + attribute KEEP of clk0_rd : signal is "TRUE"; + +begin + + clk0_out <= clk0_temp; + clk0 <= clk0_temp after 10 ps; -- fix delta delay + rst0_out <= rst0; +-- clk0_rd <= clk_fb; -- no feedback pin on DE0-Nano, use shifted clk1_0_out from clock gen + +------------------------------------------------------------------------------------------------------------------------------------------------ +inst_sdram_clk : entity work.sdram_clk + GENERIC MAP + ( + F_SDRCLK_IN => F_SDRCLK_IN, + F_SDRCLK_OUT => F_SDRCLK, + clk0_out_phaseshift_ps => 0, + clk1_out_phaseshift_ps => 3000 + ) + PORT MAP + ( + -- Clocks and Reset + rst => rst, -- external async reset, low active + clk_in => clk, -- system clock (e.g. 100MHz), from board + clk_fb_in => clk_fb, -- feedback clock + clk0_0_out => clk0_temp, -- System clock #0, dcm#0 output 0° + clk1_0_out => clk0_rd, -- System clock #1 (e.g. clock for DDR-SDRAM data capture), dcm#1 output 0° + locked_out => locked -- DCM locked status + ); + +rst0_gen: + process(rst, clk0) + begin + if rst = '1' then + rst0 <= '1'; + elsif rising_edge(clk0) then + rst0 <= not locked; + end if; + end process; + +------------------------------------------------------------------------------------------------------------------------------------------------ +utag_pipe: + process(clk0) + begin + if rising_edge(clk0) then + for i in u_tag_pipe'length-1 downto 1 loop + u_tag_pipe(i) <= u_tag_pipe(i-1); + end loop; + if phy_ctrl.utag_we = '1' then + u_tag_pipe(0) <= phy_ctrl.u_tag; + end if; + end if; + end process; + +WE_REGISTER: + process(clk0) + begin + if rising_edge(clk0) then + if rst0 = '1' then + we_reg <= '0'; + else + we_reg <= phy_ctrl.we; + end if; + end if; + end process; + +DATA_DRIVE_GEN: + process(clk0) + begin + if falling_edge(clk0) then + drive <= phy_ctrl.drive_en; + end if; + end process; + +------------------------------------------------------------------------------------------------------------------------------------------------ +-- SDRAM Clock +part_clk <= clk0 after TPD_BOARD_SIM; + +------------------------------------------------------------------------------------------------------------------------------------------------ +-- Data OUT FFs + process (clk0) is + begin + if falling_edge(clk0) then + part_data <= (others => 'Z') after TPD_BOARD_SIM; + if (phy_ctrl.drive_en = '1') then + part_data <= phy_in.wr_data after TPD_BOARD_SIM; + end if; + end if; + end process; + +------------------------------------------------------------------------------------------------------------------------------------------------ +-- Data-mask OUT DDR-FFs + process (clk0) is + begin + if falling_edge(clk0) then + part_dqm <= phy_in.wr_dm after TPD_BOARD_SIM; + end if; + end process; + +------------------------------------------------------------------------------------------------------------------------------------------------ + process (clk0) is + begin + if rising_edge(clk0) then + if rst0 = '1' then + part_ctrl_reg.cmd <= COMMAND(SD_DESELECT); + part_ctrl_reg.ba <= (others=>'0'); + part_ctrl_reg.addr <= (others=>'0'); + part_ctrl_reg.cke <= '0'; + else + part_ctrl_reg <= phy_ctrl.part; + end if; + end if; + end process; + + process (clk0) is + begin + if falling_edge(clk0) then + part_ras_n <= part_ctrl_reg.cmd.ras_n after TPD_BOARD_SIM; + part_cas_n <= part_ctrl_reg.cmd.cas_n after TPD_BOARD_SIM; + part_we_n <= part_ctrl_reg.cmd.we_n after TPD_BOARD_SIM; + part_cs_n <= part_ctrl_reg.cmd.cs_n after TPD_BOARD_SIM; + part_ba <= part_ctrl_reg.ba after TPD_BOARD_SIM; + part_addr <= part_ctrl_reg.addr after TPD_BOARD_SIM; + part_cke <= part_ctrl_reg.cke after TPD_BOARD_SIM; + end if; + end process; + +----------------------------------------------------------------- +-- READ DATA Processing +----------------------------------------------------------------- +data_sample_stage: + process (clk0_rd) + begin + if rising_edge(clk0_rd) then + data_reg_r <= part_data; + end if; + end process; + +misc_flags_and_data_out: + process (clk0) + variable p : unsigned(3 downto 0); + begin + if rising_edge(clk0) then + if rst0 = '1' then + p := (others => '0'); + phy_out.rd_data_we <= '0'; + phy_out.wr_data_re <= '0'; + else + phy_out.rd_data <= data_reg_r; + if p(3) = '1' then + phy_out.tag_rd <= u_tag_pipe(4); + end if; + if phy_ctrl.we = '1' then + phy_out.tag_wr <= u_tag_pipe(0); + end if; + phy_out.wr_data_re <= phy_ctrl.drive_en; + phy_out.rd_data_we <= p(2); + if phy_ctrl.re = '1' then + p := p(p'left-1 downto 0) & '1'; + else + p := p(p'left-1 downto 0) & '0'; + end if; + end if; + end if; + end process; + +------------------------------------------------------------------------------------------ +end tech; diff --git a/lib/SDRAM/ddr_sdr_v1_5/src/sdr_phy_virtex4.vhd b/lib/SDRAM/ddr_sdr_v1_5/src/sdr_phy_virtex4.vhd index a8f5b9e..ca36fba 100644 --- a/lib/SDRAM/ddr_sdr_v1_5/src/sdr_phy_virtex4.vhd +++ b/lib/SDRAM/ddr_sdr_v1_5/src/sdr_phy_virtex4.vhd @@ -35,7 +35,8 @@ use UNISIM.vcomponents.all; entity sdram_phy is Generic ( - F_SDRCLK : real := 100.0; + F_SDRCLK_IN : real := 100.0; + F_SDRCLK : real := 100.0; TPD_BOARD_SIM : time := 0 ns ); Port diff --git a/lib/SDRAM/ddr_sdr_v1_5/src/tb_ctrl_sdr_wb32.vhd b/lib/SDRAM/ddr_sdr_v1_5/src/tb_ctrl_sdr_wb32.vhd index b5b9810..27c0da0 100644 --- a/lib/SDRAM/ddr_sdr_v1_5/src/tb_ctrl_sdr_wb32.vhd +++ b/lib/SDRAM/ddr_sdr_v1_5/src/tb_ctrl_sdr_wb32.vhd @@ -111,6 +111,7 @@ begin GENERIC MAP ( F_SYSCLK => 100.000, + F_SDRCLK_IN => 100.000, F_SDRCLK => 100.000, FIFO_DEPTH => 4, TPD_BOARD_SIM => TPD_BOARD_SIM