- added Altera/De0-NAno implementation

git-svn-id: http://moon:8086/svn/vhdl/trunk@1255 cc03376c-175c-47c8-b038-4cd826a8556b
This commit is contained in:
2015-05-29 13:09:20 +00:00
parent 4afbac8e59
commit 2da60e2b54
5 changed files with 483 additions and 1 deletions
@@ -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
)
@@ -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;
@@ -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 <http://www.gnu.org/licenses/>.
--
-- 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;
------------------------------------------------------------------------------------------
@@ -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
@@ -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