Initial commit
This commit is contained in:
commit
a1efcf62c4
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*.wlf
|
||||||
|
wlf*
|
||||||
|
*.vstf
|
||||||
|
transcript
|
||||||
|
|
25
.library_mapping.xml
Normal file
25
.library_mapping.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<com.sigasi.hdt.shared.librarymapping.model:LibraryMappings xmlns:com.sigasi.hdt.shared.librarymapping.model="com.sigasi.hdt.vhdl.scoping.librarymapping" Version="2">
|
||||||
|
<Mappings Location="bench" Library="bench"/>
|
||||||
|
<Mappings Location="devicemodels" Library="bench"/>
|
||||||
|
<Mappings Location="ip/altera/ddr3.vhd" Library="ddr3"/>
|
||||||
|
<Mappings Location="cores" Library="design"/>
|
||||||
|
<Mappings Location="cores/flashrom-wb" Library="design"/>
|
||||||
|
<Mappings Location="design" Library="design"/>
|
||||||
|
<Mappings Location="Common Libraries/IEEE" Library="ieee"/>
|
||||||
|
<Mappings Location="ip/altera/ram0.vhd" Library="ip"/>
|
||||||
|
<Mappings Location="ip/altera/spiFifo.vhd" Library="ip"/>
|
||||||
|
<Mappings Location="ip/intercon/rtl/crossbar_v3.vhd" Library="ip"/>
|
||||||
|
<Mappings Location="ip/intercon/rtl/wishbone_package.vhd" Library="ip"/>
|
||||||
|
<Mappings Location="ip/mor1kx-mor1kx_v4/rtl/vhdl/mor1kx_pkg.vhd" Library="ip"/>
|
||||||
|
<Mappings Location="ip/mor1kx-mor1kx_v4/rtl/vhdl/mor1kx_vhdl.vhd" Library="ip"/>
|
||||||
|
<Mappings Location="Common Libraries" Library="not mapped"/>
|
||||||
|
<Mappings Location="cores/OLDflashrom-wb" Library="not mapped"/>
|
||||||
|
<Mappings Location="ip" Library="not mapped"/>
|
||||||
|
<Mappings Location="ip/intercon/rtl" Library="not mapped"/>
|
||||||
|
<Mappings Location="ip/intercon/rtl/crossbar.vhd" Library="not mapped"/>
|
||||||
|
<Mappings Location="ip/intercon/rtl/crossbar_package.vhd" Library="not mapped"/>
|
||||||
|
<Mappings Location="quartus" Library="not mapped"/>
|
||||||
|
<Mappings Location="Common Libraries/STD" Library="std"/>
|
||||||
|
<Mappings Location="" Library="work"/>
|
||||||
|
</com.sigasi.hdt.shared.librarymapping.model:LibraryMappings>
|
45
.project
Normal file
45
.project
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>mor1kx-bemicrocv</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>com.sigasi.hdt.vhdl.ui.vhdlNature</nature>
|
||||||
|
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||||
|
</natures>
|
||||||
|
<linkedResources>
|
||||||
|
<link>
|
||||||
|
<name>Common Libraries</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>virtual:/virtual</locationURI>
|
||||||
|
</link>
|
||||||
|
<link>
|
||||||
|
<name>Common Libraries/DRAG_REUSABLE_LIBRARIES_HERE.txt</name>
|
||||||
|
<type>1</type>
|
||||||
|
<locationURI>sigasiresource:/vhdl/readme2.txt</locationURI>
|
||||||
|
</link>
|
||||||
|
<link>
|
||||||
|
<name>Common Libraries/IEEE</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>sigasiresource:/vhdl/93/IEEE</locationURI>
|
||||||
|
</link>
|
||||||
|
<link>
|
||||||
|
<name>Common Libraries/STD</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>sigasiresource:/vhdl/93/STD</locationURI>
|
||||||
|
</link>
|
||||||
|
<link>
|
||||||
|
<name>Common Libraries/IEEE/Synopsys</name>
|
||||||
|
<type>2</type>
|
||||||
|
<locationURI>sigasiresource:/vhdl/93/IEEE%20Synopsys</locationURI>
|
||||||
|
</link>
|
||||||
|
</linkedResources>
|
||||||
|
</projectDescription>
|
5
.settings/org.eclipse.core.resources.prefs
Normal file
5
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
encoding//Common\ Libraries/IEEE=utf-8
|
||||||
|
encoding//Common\ Libraries/IEEE/Synopsys=utf-8
|
||||||
|
encoding//Common\ Libraries/STD=utf-8
|
||||||
|
encoding/Common\ Libraries=utf-8
|
92
bench/OLDbench_flashrom_spi.vhd.old
Normal file
92
bench/OLDbench_flashrom_spi.vhd.old
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity bench_flashrom_spi is
|
||||||
|
end entity bench_flashrom_spi;
|
||||||
|
|
||||||
|
library design;
|
||||||
|
use design.all;
|
||||||
|
|
||||||
|
architecture RTL of bench_flashrom_spi is
|
||||||
|
signal clk : std_logic;
|
||||||
|
signal spi_clk : std_logic;
|
||||||
|
signal rst : std_logic;
|
||||||
|
signal spi_si : std_logic;
|
||||||
|
signal spi_so : std_logic;
|
||||||
|
signal spi_sck : std_logic;
|
||||||
|
signal spi_reset_n : std_logic;
|
||||||
|
signal spi_cs_n : std_logic;
|
||||||
|
signal spi_wp_n : std_logic;
|
||||||
|
signal toSpiDataIn : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
signal toSpiWrite : STD_LOGIC;
|
||||||
|
signal toSpiFull : STD_LOGIC;
|
||||||
|
signal fromSpiDataOut : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
signal fromSpiRead : STD_LOGIC;
|
||||||
|
signal fromSpiEmpty : STD_LOGIC;
|
||||||
|
|
||||||
|
procedure waitclk is
|
||||||
|
begin
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
end procedure waitclk;
|
||||||
|
|
||||||
|
procedure strobe(signal s : out std_logic) is
|
||||||
|
begin
|
||||||
|
s <= '1';
|
||||||
|
waitclk;
|
||||||
|
s <= '0';
|
||||||
|
waitclk;
|
||||||
|
end procedure strobe;
|
||||||
|
|
||||||
|
begin
|
||||||
|
flashrom_spi_inst : entity design.flashrom_spi
|
||||||
|
port map(
|
||||||
|
spi_clk => spi_clk,
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
spi_si => spi_si,
|
||||||
|
spi_so => spi_so,
|
||||||
|
spi_sck => spi_sck,
|
||||||
|
spi_reset_n => spi_reset_n,
|
||||||
|
spi_cs_n => spi_cs_n,
|
||||||
|
spi_wp_n => spi_wp_n,
|
||||||
|
toSpiDataIn => toSpiDataIn,
|
||||||
|
toSpiWrite => toSpiWrite,
|
||||||
|
toSpiFull => toSpiFull,
|
||||||
|
fromSpiDataOut => fromSpiDataOut,
|
||||||
|
fromSpiRead => fromSpiRead,
|
||||||
|
fromSpiEmpty => fromSpiEmpty
|
||||||
|
);
|
||||||
|
|
||||||
|
clock_driver : process
|
||||||
|
constant period : time := 10 ns;
|
||||||
|
begin
|
||||||
|
clk <= '0';
|
||||||
|
wait for period / 2;
|
||||||
|
clk <= '1';
|
||||||
|
wait for period / 2;
|
||||||
|
end process clock_driver;
|
||||||
|
spi_clk <= clk;
|
||||||
|
|
||||||
|
test : process is
|
||||||
|
begin
|
||||||
|
spi_so <= '0';
|
||||||
|
rst <= '1';
|
||||||
|
toSpiDataIn <= (others => '0');
|
||||||
|
toSpiWrite <= '0';
|
||||||
|
fromSpiRead <= '0';
|
||||||
|
|
||||||
|
wait for 40 ns;
|
||||||
|
|
||||||
|
rst <= '0';
|
||||||
|
wait for 20 ns;
|
||||||
|
toSpiDataIn <= x"55";
|
||||||
|
strobe(toSpiWrite);
|
||||||
|
waitclk;
|
||||||
|
toSpiDataIn <= x"AA";
|
||||||
|
strobe(toSpiWrite);
|
||||||
|
|
||||||
|
wait;
|
||||||
|
end process test;
|
||||||
|
|
||||||
|
end architecture RTL;
|
199
bench/bench_flashrom_controller.vhd
Normal file
199
bench/bench_flashrom_controller.vhd
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use std.textio.all;
|
||||||
|
|
||||||
|
library design;
|
||||||
|
use design.all;
|
||||||
|
use design.flashrom_pkg.all;
|
||||||
|
|
||||||
|
entity bench_flashrom_controller is
|
||||||
|
end entity bench_flashrom_controller;
|
||||||
|
|
||||||
|
architecture rtl of bench_flashrom_controller is
|
||||||
|
signal clk : std_logic;
|
||||||
|
signal rst : std_logic;
|
||||||
|
|
||||||
|
procedure waitclk is
|
||||||
|
begin
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
end procedure waitclk;
|
||||||
|
procedure waitnclk(n : integer) is
|
||||||
|
begin
|
||||||
|
for i in 1 to n loop
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
end loop;
|
||||||
|
end procedure waitnclk;
|
||||||
|
procedure strobe(signal s : out std_logic) is
|
||||||
|
begin
|
||||||
|
s <= '1';
|
||||||
|
waitclk;
|
||||||
|
s <= '0';
|
||||||
|
waitclk;
|
||||||
|
end procedure strobe;
|
||||||
|
signal clr : std_logic;
|
||||||
|
signal ready : std_logic;
|
||||||
|
signal page : std_logic_vector(FLASHROM_ADDR_WIDTH - 1 downto 0);
|
||||||
|
signal sync_stb : std_logic;
|
||||||
|
signal load_stb : std_logic;
|
||||||
|
signal status_update_stb : std_logic;
|
||||||
|
signal status : std_logic_vector(31 downto 0);
|
||||||
|
signal info : std_logic_vector(31 downto 0);
|
||||||
|
signal data_in : std_logic_vector(7 downto 0);
|
||||||
|
signal data_in_valid : std_logic;
|
||||||
|
signal data_out : std_logic_vector(7 downto 0);
|
||||||
|
signal data_out_valid : std_logic;
|
||||||
|
signal spi_si : std_logic;
|
||||||
|
signal spi_so : std_logic;
|
||||||
|
signal spi_sck : std_logic;
|
||||||
|
signal spi_reset_n : std_logic;
|
||||||
|
signal spi_cs_n : std_logic;
|
||||||
|
signal spi_wp_n : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
flashrom_controller_inst : entity design.flashrom_controller
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
clr => clr,
|
||||||
|
ready => ready,
|
||||||
|
page => page,
|
||||||
|
sync_stb => sync_stb,
|
||||||
|
load_stb => load_stb,
|
||||||
|
status_update_stb => status_update_stb,
|
||||||
|
status => status,
|
||||||
|
info => info,
|
||||||
|
data_in => data_in,
|
||||||
|
data_in_valid => data_in_valid,
|
||||||
|
data_out => data_out,
|
||||||
|
data_out_valid => data_out_valid,
|
||||||
|
spi_si => spi_si,
|
||||||
|
spi_so => spi_so,
|
||||||
|
spi_sck => spi_sck,
|
||||||
|
spi_reset_n => spi_reset_n,
|
||||||
|
spi_cs_n => spi_cs_n,
|
||||||
|
spi_wp_n => spi_wp_n
|
||||||
|
);
|
||||||
|
|
||||||
|
-- clock driver
|
||||||
|
clock_driver : process
|
||||||
|
constant PERIOD : time := 10 ns;
|
||||||
|
begin
|
||||||
|
clk <= '0';
|
||||||
|
wait for PERIOD / 2;
|
||||||
|
clk <= '1';
|
||||||
|
wait for PERIOD / 2;
|
||||||
|
end process clock_driver;
|
||||||
|
|
||||||
|
--testbench
|
||||||
|
bench : process is
|
||||||
|
begin
|
||||||
|
rst <= '1';
|
||||||
|
clr <= '0';
|
||||||
|
wait for 10 ns * 2;
|
||||||
|
wait until (rising_edge(clk));
|
||||||
|
rst <= '0';
|
||||||
|
wait for 10 ns * 2;
|
||||||
|
wait until (rising_edge(clk));
|
||||||
|
|
||||||
|
-- bench code here
|
||||||
|
|
||||||
|
|
||||||
|
wait;
|
||||||
|
end process bench;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- debugging only!
|
||||||
|
spi_so_p : process is
|
||||||
|
procedure spitx(constant value : std_logic) is
|
||||||
|
begin
|
||||||
|
spi_so <= value;
|
||||||
|
wait until rising_edge(spi_sck);
|
||||||
|
end procedure spitx;
|
||||||
|
begin
|
||||||
|
spi_so <= '0';
|
||||||
|
wait until rising_edge(spi_sck);
|
||||||
|
wait until rising_edge(spi_sck);
|
||||||
|
|
||||||
|
|
||||||
|
-- 0x0 (dummy)
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
-- INFO FOO: 0x1F
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('1');
|
||||||
|
spitx('1');
|
||||||
|
spitx('1');
|
||||||
|
spitx('1');
|
||||||
|
--
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('1');
|
||||||
|
spitx('1');
|
||||||
|
--
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
--
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- 0x88
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
-- 0x44
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
-- 0x22
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
|
||||||
|
wait;
|
||||||
|
end process spi_so_p;
|
||||||
|
end architecture rtl;
|
205
bench/bench_flashrom_spi.vhd
Normal file
205
bench/bench_flashrom_spi.vhd
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use std.textio.all;
|
||||||
|
|
||||||
|
library design;
|
||||||
|
use design.all;
|
||||||
|
|
||||||
|
entity bench_flashrom_spi is
|
||||||
|
end entity bench_flashrom_spi;
|
||||||
|
|
||||||
|
architecture rtl of bench_flashrom_spi is
|
||||||
|
signal clk : std_logic;
|
||||||
|
signal rst : std_logic;
|
||||||
|
|
||||||
|
procedure waitclk is
|
||||||
|
begin
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
end procedure waitclk;
|
||||||
|
procedure waitnclk(n : integer) is
|
||||||
|
begin
|
||||||
|
for i in 1 to n loop
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
end loop;
|
||||||
|
end procedure waitnclk;
|
||||||
|
procedure strobe(signal s : out std_logic) is
|
||||||
|
begin
|
||||||
|
s <= '1';
|
||||||
|
waitclk;
|
||||||
|
s <= '0';
|
||||||
|
waitclk;
|
||||||
|
end procedure strobe;
|
||||||
|
|
||||||
|
constant max_word_length : integer := 16;
|
||||||
|
constant max_dummy_bits : integer := 16;
|
||||||
|
|
||||||
|
signal clr : std_logic;
|
||||||
|
signal spi_si : std_logic;
|
||||||
|
signal spi_so : std_logic := '0';
|
||||||
|
signal spi_sck : std_logic;
|
||||||
|
signal spi_cs_n : std_logic;
|
||||||
|
signal data_in_valid : std_logic;
|
||||||
|
signal data_in : std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
signal data_next : std_logic;
|
||||||
|
signal data_out : std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
signal data_out_valid : std_logic;
|
||||||
|
signal data_in_length : integer range 0 to max_word_length;
|
||||||
|
signal data_out_length : integer range 0 to max_word_length;
|
||||||
|
signal data_out_dummy_bits : integer range 0 to max_dummy_bits;
|
||||||
|
signal transmission_active : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
flashrom_spi_inst : entity design.flashrom_spi
|
||||||
|
generic map(
|
||||||
|
clk_divider => 4,
|
||||||
|
max_word_length => max_word_length,
|
||||||
|
max_dummy_bits => max_dummy_bits)
|
||||||
|
port map(
|
||||||
|
data_out_dummy_bits => data_out_dummy_bits,
|
||||||
|
data_out_length => data_out_length,
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
clr => clr,
|
||||||
|
spi_si => spi_si,
|
||||||
|
spi_so => spi_so,
|
||||||
|
spi_sck => spi_sck,
|
||||||
|
spi_cs_n => spi_cs_n,
|
||||||
|
data_in_valid => data_in_valid,
|
||||||
|
data_in => data_in,
|
||||||
|
data_next => data_next,
|
||||||
|
data_out => data_out,
|
||||||
|
data_out_valid => data_out_valid,
|
||||||
|
data_in_length => data_in_length,
|
||||||
|
transmission_active => transmission_active
|
||||||
|
);
|
||||||
|
|
||||||
|
-- clock driver
|
||||||
|
clock_driver : process
|
||||||
|
constant PERIOD : time := 10 ns;
|
||||||
|
begin
|
||||||
|
clk <= '0';
|
||||||
|
wait for PERIOD / 2;
|
||||||
|
clk <= '1';
|
||||||
|
wait for PERIOD / 2;
|
||||||
|
end process clock_driver;
|
||||||
|
|
||||||
|
--testbench
|
||||||
|
bench : process is
|
||||||
|
begin
|
||||||
|
rst <= '1';
|
||||||
|
data_in <= x"0000";
|
||||||
|
data_in_valid <= '0';
|
||||||
|
wait for 10 ns * 2;
|
||||||
|
wait until (rising_edge(clk));
|
||||||
|
rst <= '0';
|
||||||
|
wait for 10 ns * 2;
|
||||||
|
wait until (rising_edge(clk));
|
||||||
|
|
||||||
|
-- bench code here
|
||||||
|
data_out_dummy_bits <= 0;
|
||||||
|
|
||||||
|
data_in_length <= 8;
|
||||||
|
data_out_length <= 8;
|
||||||
|
data_in <= x"FF00";
|
||||||
|
data_in_valid <= '1';
|
||||||
|
wait until data_next = '1';
|
||||||
|
|
||||||
|
data_in_length <= 16;
|
||||||
|
data_out_length <= 16;
|
||||||
|
data_in <= x"0055";
|
||||||
|
data_in_valid <= '1';
|
||||||
|
wait until data_next = '1';
|
||||||
|
|
||||||
|
data_in_valid <= '0';
|
||||||
|
wait until transmission_active = '0';
|
||||||
|
waitnclk(10); -- new SPI transaction
|
||||||
|
|
||||||
|
data_out_dummy_bits <= 16;
|
||||||
|
data_in_length <= 16;
|
||||||
|
data_out_length <= 16;
|
||||||
|
data_in <= x"0055";
|
||||||
|
data_in_valid <= '1';
|
||||||
|
wait until data_next = '1';
|
||||||
|
wait until data_next = '1'; -- 32 bits total
|
||||||
|
|
||||||
|
data_in_valid <= '0';
|
||||||
|
|
||||||
|
wait;
|
||||||
|
end process bench;
|
||||||
|
|
||||||
|
spi_so_p : process is
|
||||||
|
procedure spitx(constant value : std_logic) is
|
||||||
|
begin
|
||||||
|
spi_so <= value;
|
||||||
|
wait until rising_edge(spi_sck);
|
||||||
|
end procedure spitx;
|
||||||
|
begin
|
||||||
|
spi_so <= '0';
|
||||||
|
wait until rising_edge(spi_sck);
|
||||||
|
wait until rising_edge(spi_sck);
|
||||||
|
|
||||||
|
-- 8 bit word
|
||||||
|
spitx('1');
|
||||||
|
for i in 1 to 7 loop
|
||||||
|
spitx('0');
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
-- 8 bit word
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
for i in 1 to 6 loop
|
||||||
|
spitx('0');
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
-- 8 bit word
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
for i in 1 to 5 loop
|
||||||
|
spitx('0');
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
wait until rising_edge(spi_sck);
|
||||||
|
|
||||||
|
-- 0x80 (dummy)
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
-- 0x88
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
-- 0x44
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
-- 0x22
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('0');
|
||||||
|
spitx('1');
|
||||||
|
spitx('0');
|
||||||
|
|
||||||
|
wait;
|
||||||
|
end process spi_so_p;
|
||||||
|
|
||||||
|
end architecture rtl;
|
119
bench/bench_sram_wb.vhd
Normal file
119
bench/bench_sram_wb.vhd
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library design;
|
||||||
|
use design.all;
|
||||||
|
|
||||||
|
library ip;
|
||||||
|
use ip.all;
|
||||||
|
use ip.wishbone_package.all;
|
||||||
|
|
||||||
|
entity bench_sram_wb is
|
||||||
|
end entity bench_sram_wb;
|
||||||
|
|
||||||
|
architecture RTL of bench_sram_wb is
|
||||||
|
signal clk : std_logic;
|
||||||
|
signal rst : std_logic;
|
||||||
|
signal wb_in : wishbone_v3_slave_in;
|
||||||
|
signal wb_out : wishbone_v3_slave_out;
|
||||||
|
|
||||||
|
begin
|
||||||
|
sram_wb_inst : entity design.sram_wb
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
wb_in => wb_in,
|
||||||
|
wb_out => wb_out
|
||||||
|
);
|
||||||
|
|
||||||
|
clock_driver : process
|
||||||
|
constant period : time := 10 ns;
|
||||||
|
begin
|
||||||
|
clk <= '0';
|
||||||
|
wait for period / 2;
|
||||||
|
clk <= '1';
|
||||||
|
wait for period / 2;
|
||||||
|
end process clock_driver;
|
||||||
|
|
||||||
|
wb_in.CYC <= wb_in.STB;
|
||||||
|
test : process is
|
||||||
|
begin
|
||||||
|
rst <= '1';
|
||||||
|
wb_in.DAT <= (others => '0');
|
||||||
|
wb_in.STB <= '0';
|
||||||
|
wb_in.SEL <= "1111";
|
||||||
|
wb_in.WE <= '0';
|
||||||
|
wb_in.ADR <= (others => '0');
|
||||||
|
wait for 20 ns;
|
||||||
|
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
rst <= '0';
|
||||||
|
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
|
||||||
|
-- wb_in.DAT <= x"12345678";
|
||||||
|
-- wb_in.WE <= '1';
|
||||||
|
-- wb_in.STB <= '1';
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- --wait until rising_edge(wb_out.ACK);
|
||||||
|
-- wb_in.STB <= '0';
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wb_in.ADR <= x"00000004";
|
||||||
|
-- wb_in.DAT <= x"AABBCCDD";
|
||||||
|
-- wb_in.WE <= '1';
|
||||||
|
-- wb_in.STB <= '1';
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- --wait until rising_edge(wb_out.ACK);
|
||||||
|
-- wb_in.STB <= '0';
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wb_in.ADR <= x"00000004";
|
||||||
|
-- wb_in.DAT <= x"FF111111";
|
||||||
|
-- wb_in.SEL <= "1000";
|
||||||
|
-- wb_in.WE <= '1';
|
||||||
|
-- wb_in.STB <= '1';
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- --wait until rising_edge(wb_out.ACK);
|
||||||
|
-- wb_in.STB <= '0';
|
||||||
|
-- wb_in.SEL <= "1111";
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
--
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wb_in.ADR <= x"00000000";
|
||||||
|
-- wb_in.DAT <= x"FFFFFFFF";
|
||||||
|
-- wb_in.WE <= '0';
|
||||||
|
-- wb_in.STB <= '1';
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wait until rising_edge(wb_out.ACK);
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wb_in.STB <= '0';
|
||||||
|
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wb_in.DAT <= x"FFFFFFFF";
|
||||||
|
-- wb_in.ADR <= x"00000004";
|
||||||
|
-- wb_in.WE <= '0';
|
||||||
|
-- wb_in.STB <= '1';
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wait until rising_edge(wb_out.ACK);
|
||||||
|
-- wait until rising_edge(clk);
|
||||||
|
-- wb_in.STB <= '0';
|
||||||
|
|
||||||
|
for i in 0 to 1000 loop
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wb_in.ADR <= std_logic_vector(to_unsigned(i, 30) & "00");
|
||||||
|
wb_in.WE <= '0';
|
||||||
|
wb_in.STB <= '1';
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wait until rising_edge(wb_out.ACK);
|
||||||
|
wait until rising_edge(clk);
|
||||||
|
wb_in.STB <= '0';
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
wait;
|
||||||
|
end process test;
|
||||||
|
|
||||||
|
end architecture RTL;
|
84
bench/bench_top.vhd
Normal file
84
bench/bench_top.vhd
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library design;
|
||||||
|
use design.all;
|
||||||
|
|
||||||
|
library ip;
|
||||||
|
use ip.wishbone_package.all;
|
||||||
|
|
||||||
|
entity bench_top is
|
||||||
|
end entity bench_top;
|
||||||
|
|
||||||
|
architecture RTL of bench_top is
|
||||||
|
signal clk_hw : std_logic;
|
||||||
|
signal rst_hw : std_logic;
|
||||||
|
signal GPIOA : std_logic_vector(wishbone_data_width - 1 downto 0);
|
||||||
|
signal jinn_uart_rx : std_logic;
|
||||||
|
signal jinn_uart_tx : std_logic;
|
||||||
|
signal uart_rx : std_logic;
|
||||||
|
signal uart_tx : std_logic;
|
||||||
|
-- DDR3
|
||||||
|
signal mem_a : std_logic_vector(12 downto 0);
|
||||||
|
signal mem_ba : std_logic_vector(2 downto 0);
|
||||||
|
signal mem_ck : std_logic_vector(0 downto 0);
|
||||||
|
signal mem_ck_n : std_logic_vector(0 downto 0);
|
||||||
|
signal mem_cke : std_logic_vector(0 downto 0);
|
||||||
|
signal mem_cs_n : std_logic_vector(0 downto 0);
|
||||||
|
signal mem_dm : std_logic_vector(1 downto 0);
|
||||||
|
signal mem_ras_n : std_logic_vector(0 downto 0);
|
||||||
|
signal mem_cas_n : std_logic_vector(0 downto 0);
|
||||||
|
signal mem_we_n : std_logic_vector(0 downto 0);
|
||||||
|
signal mem_reset_n : std_logic;
|
||||||
|
signal mem_dq : std_logic_vector(15 downto 0);
|
||||||
|
signal mem_dqs : std_logic_vector(1 downto 0);
|
||||||
|
signal mem_dqs_n : std_logic_vector(1 downto 0);
|
||||||
|
signal mem_odt : std_logic_vector(0 downto 0);
|
||||||
|
signal oct_rzqin : std_logic;
|
||||||
|
begin
|
||||||
|
top_inst : entity design.top
|
||||||
|
port map(
|
||||||
|
clk_hw => clk_hw,
|
||||||
|
rst_hw => rst_hw,
|
||||||
|
GPIOA => GPIOA,
|
||||||
|
jinn_uart_rx => jinn_uart_rx,
|
||||||
|
jinn_uart_tx => jinn_uart_tx,
|
||||||
|
uart_rx => uart_rx,
|
||||||
|
uart_tx => uart_tx,
|
||||||
|
mem_a => mem_a,
|
||||||
|
mem_ba => mem_ba,
|
||||||
|
mem_ck => mem_ck,
|
||||||
|
mem_ck_n => mem_ck_n,
|
||||||
|
mem_cke => mem_cke,
|
||||||
|
mem_cs_n => mem_cs_n,
|
||||||
|
mem_dm => mem_dm,
|
||||||
|
mem_ras_n => mem_ras_n,
|
||||||
|
mem_cas_n => mem_cas_n,
|
||||||
|
mem_we_n => mem_we_n,
|
||||||
|
mem_reset_n => mem_reset_n,
|
||||||
|
mem_dq => mem_dq,
|
||||||
|
mem_dqs => mem_dqs,
|
||||||
|
mem_dqs_n => mem_dqs_n,
|
||||||
|
mem_odt => mem_odt,
|
||||||
|
oct_rzqin => oct_rzqin
|
||||||
|
);
|
||||||
|
|
||||||
|
clock_driver : process
|
||||||
|
constant period : time := 10 ns;
|
||||||
|
begin
|
||||||
|
clk_hw <= '0';
|
||||||
|
wait for period / 2;
|
||||||
|
clk_hw <= '1';
|
||||||
|
wait for period / 2;
|
||||||
|
end process clock_driver;
|
||||||
|
|
||||||
|
test : process is
|
||||||
|
begin
|
||||||
|
rst_hw <= '0';
|
||||||
|
wait for 50 ns;
|
||||||
|
rst_hw <= '1';
|
||||||
|
wait;
|
||||||
|
end process test;
|
||||||
|
|
||||||
|
end architecture RTL;
|
39
compile.do
Normal file
39
compile.do
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_branch_prediction.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_ctrl_espresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_fetch_espresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_simple_dpram_sclk.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_bus_if_avalon.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_ctrl_prontoespresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_fetch_prontoespresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx-sprs.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_bus_if_wb32.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_dcache.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_fetch_tcm_prontoespresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_store_buffer.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_cache_lru.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_decode_execute_cappuccino.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_icache.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_ticktimer.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_cfgrs.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_decode.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_immu.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_true_dpram_sclk.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_cpu_cappuccino.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx-defines.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_lsu_cappuccino.v
|
||||||
|
vlog -sv -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_utils.vh
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_cpu_espresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_dmmu.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_lsu_espresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_cpu_prontoespresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_execute_alu.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_pic.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_wb_mux_cappuccino.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_cpu.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_execute_ctrl_cappuccino.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_rf_cappuccino.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_wb_mux_espresso.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_ctrl_cappuccino.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_fetch_cappuccino.v
|
||||||
|
vlog -work mor1kx ip/mor1kx-mor1kx_v4/rtl/verilog/mor1kx_rf_espresso.v
|
168
cores/OLDflashrom-wb/flashrom-spi.vhd
Normal file
168
cores/OLDflashrom-wb/flashrom-spi.vhd
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library ip;
|
||||||
|
use ip.all;
|
||||||
|
|
||||||
|
entity flashrom_spi is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
spi_clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
|
||||||
|
-- SPI flash hardware signals
|
||||||
|
spi_si : out std_logic; -- SPI serial in
|
||||||
|
spi_so : in std_logic; -- SPI serial out
|
||||||
|
spi_sck : out std_logic; -- Create clock using PLL, then supply to chip and this module
|
||||||
|
spi_reset_n : out std_logic; -- SPI hard reset
|
||||||
|
spi_cs_n : out std_logic; -- SPI chip select
|
||||||
|
spi_wp_n : out std_logic; -- SPI write protect
|
||||||
|
|
||||||
|
-- FPGA -> ROM
|
||||||
|
toSpiDataIn : in STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
toSpiWrite : in STD_LOGIC;
|
||||||
|
toSpiFull : out STD_LOGIC;
|
||||||
|
|
||||||
|
-- ROM -> FPGA
|
||||||
|
fromSpiDataOut : out STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
fromSpiRead : in STD_LOGIC;
|
||||||
|
fromSpiEmpty : out STD_LOGIC
|
||||||
|
);
|
||||||
|
end entity flashrom_spi;
|
||||||
|
|
||||||
|
architecture RTL of flashrom_spi is
|
||||||
|
signal spi_rst : std_logic;
|
||||||
|
|
||||||
|
signal toSpiRead : STD_LOGIC;
|
||||||
|
signal toSpiDataOut : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
signal toSpiEmpty : STD_LOGIC;
|
||||||
|
signal fromSpiDataIn : STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||||
|
signal fromSpiWrite : STD_LOGIC;
|
||||||
|
signal fromSpiFull : STD_LOGIC;
|
||||||
|
|
||||||
|
signal outshifter_cnt : unsigned(2 downto 0);
|
||||||
|
signal outshifter_data : std_logic_vector(7 downto 0);
|
||||||
|
signal inshifter_cnt : unsigned(2 downto 0);
|
||||||
|
signal inshifter_data : std_logic_vector(7 downto 0);
|
||||||
|
signal spi_cs_n_del : std_logic;
|
||||||
|
begin
|
||||||
|
spi_sck <= spi_clk;
|
||||||
|
|
||||||
|
resetSync : process(rst, spi_clk) is
|
||||||
|
variable cnt : integer range 0 to 1;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
cnt := 1;
|
||||||
|
spi_rst <= '1';
|
||||||
|
elsif rising_edge(spi_clk) then
|
||||||
|
spi_rst <= '1';
|
||||||
|
if cnt = 0 then
|
||||||
|
spi_rst <= '0';
|
||||||
|
else
|
||||||
|
cnt := cnt - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process resetSync;
|
||||||
|
|
||||||
|
-- FPGA -> ROM
|
||||||
|
shifter : process(spi_clk, rst) is
|
||||||
|
variable loaded : std_logic;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
outshifter_data <= (others => '0');
|
||||||
|
outshifter_cnt <= (others => '1');
|
||||||
|
spi_cs_n <= '1';
|
||||||
|
toSpiRead <= '0';
|
||||||
|
loaded := '0';
|
||||||
|
elsif rising_edge(spi_clk) then -- provide data on falling edge
|
||||||
|
toSpiRead <= '0';
|
||||||
|
if outshifter_cnt = "101" then
|
||||||
|
if toSpiEmpty = '0' then
|
||||||
|
toSpiRead <= '1';
|
||||||
|
loaded := '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if outshifter_cnt = "111" then
|
||||||
|
if loaded = '1' then
|
||||||
|
loaded := '0';
|
||||||
|
outshifter_data <= toSpiDataOut;
|
||||||
|
spi_cs_n <= '0';
|
||||||
|
outshifter_cnt <= "000";
|
||||||
|
else
|
||||||
|
spi_cs_n <= '1';
|
||||||
|
--shifter_cnt <= "000";
|
||||||
|
if toSpiEmpty = '0' then
|
||||||
|
outshifter_cnt <= "101";
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
outshifter_cnt <= outshifter_cnt + 1;
|
||||||
|
outshifter_data <= outshifter_data(6 downto 0) & '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process shifter;
|
||||||
|
spi_si <= outshifter_data(7);
|
||||||
|
|
||||||
|
spiFifo_wb2spi_inst : entity ip.spiFifo
|
||||||
|
port map(
|
||||||
|
aclr => rst,
|
||||||
|
data => toSpiDataIn,
|
||||||
|
rdclk => spi_clk,
|
||||||
|
rdreq => toSpiRead,
|
||||||
|
wrclk => clk,
|
||||||
|
wrreq => toSpiWrite,
|
||||||
|
q => toSpiDataOut,
|
||||||
|
rdempty => toSpiEmpty,
|
||||||
|
wrfull => toSpiFull
|
||||||
|
);
|
||||||
|
|
||||||
|
errorHandler_wb : process(clk, rst) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if toSpiWrite = '1' and toSpiFull = '1' then
|
||||||
|
-- TODO: ERROR: Fifo full!
|
||||||
|
report "ERROR: SPI transmit FIFO full!" severity failure;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process errorHandler_wb;
|
||||||
|
|
||||||
|
-- ROM -> FPGA
|
||||||
|
shifter_in : process(spi_clk, rst) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
inshifter_data <= (others => '0');
|
||||||
|
inshifter_cnt <= (others => '0');
|
||||||
|
fromSpiWrite <= '0';
|
||||||
|
spi_cs_n_del <= '1';
|
||||||
|
elsif rising_edge(spi_clk) then -- sample on rising edge
|
||||||
|
spi_cs_n_del <= spi_cs_n;
|
||||||
|
fromSpiWrite <= '0';
|
||||||
|
if spi_cs_n = '0' then
|
||||||
|
inshifter_cnt <= inshifter_cnt + 1;
|
||||||
|
inshifter_data <= inshifter_data(6 downto 0) & spi_so;
|
||||||
|
if inshifter_cnt = "111" then
|
||||||
|
fromSpiWrite <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
inshifter_data <= (others => '0');
|
||||||
|
inshifter_cnt <= (others => '0');
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process shifter_in;
|
||||||
|
|
||||||
|
spiFifo_spi2wb_inst : entity ip.spiFifo
|
||||||
|
port map(
|
||||||
|
aclr => rst,
|
||||||
|
data => fromSpiDataIn,
|
||||||
|
rdclk => clk,
|
||||||
|
rdreq => fromSpiRead,
|
||||||
|
wrclk => spi_clk,
|
||||||
|
wrreq => fromSpiWrite,
|
||||||
|
q => fromSpiDataOut,
|
||||||
|
rdempty => fromSpiEmpty,
|
||||||
|
wrfull => fromSpiFull
|
||||||
|
);
|
||||||
|
fromSpiDataIn <= inshifter_data;
|
||||||
|
end architecture RTL;
|
130
cores/flashrom-wb/flashrom_controller.vhd
Normal file
130
cores/flashrom-wb/flashrom_controller.vhd
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
use work.flashrom_pkg.all;
|
||||||
|
|
||||||
|
entity flashrom_controller is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
clr : in std_logic;
|
||||||
|
|
||||||
|
-- Control IF
|
||||||
|
ready : out std_logic; -- The controller is ready to accept commands
|
||||||
|
page : in std_logic_vector(FLASHROM_ADDR_WIDTH - 1 downto 0);
|
||||||
|
sync_stb : in std_logic; -- Synchronize current memory page with chip, only sampled when ready
|
||||||
|
load_stb : in std_logic; -- Load page into local buffer, only sampled when ready
|
||||||
|
status_update_stb : in std_logic; -- Update status vector
|
||||||
|
status : out std_logic_vector(31 downto 0); -- value of the status register (update using status_update_stb)
|
||||||
|
info : out std_logic_vector(31 downto 0); -- value of the information register (updated on reset)
|
||||||
|
|
||||||
|
-- Data IF
|
||||||
|
data_in : in std_logic_vector(7 downto 0);
|
||||||
|
data_in_valid : in std_logic;
|
||||||
|
data_out : out std_logic_vector(7 downto 0);
|
||||||
|
data_out_valid : out std_logic;
|
||||||
|
|
||||||
|
-- SPI flash hardware signals
|
||||||
|
spi_si : out std_logic; -- SPI serial in
|
||||||
|
spi_so : in std_logic; -- SPI serial out
|
||||||
|
spi_sck : out std_logic; -- Create clock using PLL, then supply to chip and this module
|
||||||
|
spi_reset_n : out std_logic; -- SPI hard reset
|
||||||
|
spi_cs_n : out std_logic; -- SPI chip select
|
||||||
|
spi_wp_n : out std_logic -- SPI write protect
|
||||||
|
);
|
||||||
|
end entity flashrom_controller;
|
||||||
|
|
||||||
|
architecture RTL of flashrom_controller is
|
||||||
|
constant spif_max_word_length : integer := 32;
|
||||||
|
constant max_dummy_bits : integer := 16;
|
||||||
|
|
||||||
|
type state_t is (INIT, GETINFO, IDLE);
|
||||||
|
signal state : state_t;
|
||||||
|
|
||||||
|
signal spif_data_in_valid : std_logic;
|
||||||
|
signal spif_data_in : std_logic_vector(spif_max_word_length - 1 downto 0);
|
||||||
|
signal spif_data_in_length : integer range 0 to spif_max_word_length;
|
||||||
|
signal spif_data_next : std_logic;
|
||||||
|
signal spif_data_out : std_logic_vector(spif_max_word_length - 1 downto 0);
|
||||||
|
signal spif_data_out_valid : std_logic;
|
||||||
|
signal spif_data_out_length : integer range 0 to spif_max_word_length;
|
||||||
|
|
||||||
|
signal words_sent : integer range 0 to 511;
|
||||||
|
signal spif_data_out_dummy_bits : integer range 0 to max_dummy_bits;
|
||||||
|
signal spif_transmission_active : std_logic;
|
||||||
|
begin
|
||||||
|
spi_wp_n <= '1';
|
||||||
|
|
||||||
|
flashrom_spi_inst : entity work.flashrom_spi
|
||||||
|
generic map(
|
||||||
|
clk_divider => 2,
|
||||||
|
max_word_length => spif_max_word_length,
|
||||||
|
max_dummy_bits => max_dummy_bits)
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
clr => clr,
|
||||||
|
spi_si => spi_si,
|
||||||
|
spi_so => spi_so,
|
||||||
|
spi_sck => spi_sck,
|
||||||
|
spi_cs_n => spi_cs_n,
|
||||||
|
data_in_valid => spif_data_in_valid,
|
||||||
|
data_in => spif_data_in,
|
||||||
|
data_in_length => spif_data_in_length,
|
||||||
|
data_next => spif_data_next,
|
||||||
|
data_out => spif_data_out,
|
||||||
|
data_out_valid => spif_data_out_valid,
|
||||||
|
data_out_length => spif_data_out_length,
|
||||||
|
data_out_dummy_bits => spif_data_out_dummy_bits,
|
||||||
|
transmission_active => spif_transmission_active);
|
||||||
|
|
||||||
|
flashrom_controller_p : process(clk, rst) is
|
||||||
|
procedure default_state is
|
||||||
|
begin
|
||||||
|
spi_reset_n <= '1';
|
||||||
|
spif_data_in_valid <= '0';
|
||||||
|
end procedure default_state;
|
||||||
|
|
||||||
|
procedure reset_state is
|
||||||
|
begin
|
||||||
|
default_state;
|
||||||
|
state <= INIT;
|
||||||
|
spi_reset_n <= '0';
|
||||||
|
words_sent <= 0;
|
||||||
|
|
||||||
|
spif_data_in <= (others => '0');
|
||||||
|
spif_data_in_length <= 0;
|
||||||
|
spif_data_out_length <= 0;
|
||||||
|
spif_data_out_dummy_bits <= 0;
|
||||||
|
end procedure reset_state;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
reset_state;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
default_state;
|
||||||
|
if clr = '1' then
|
||||||
|
reset_state;
|
||||||
|
else
|
||||||
|
case state is
|
||||||
|
when INIT =>
|
||||||
|
words_sent <= 0;
|
||||||
|
state <= GETINFO;
|
||||||
|
when GETINFO =>
|
||||||
|
spif_data_in_length <= 16; -- Other bits after OpCode are don't care, so just repeat OPC
|
||||||
|
spif_data_out_length <= 32;
|
||||||
|
spif_data_out_dummy_bits <= 8;
|
||||||
|
spif_data_in_valid <= '1';
|
||||||
|
spif_data_in <= FLASHROM_COMMAND_MANUFACTURER_ID & padBits(spif_data_in, FLASHROM_COMMAND_MANUFACTURER_ID);
|
||||||
|
if spif_data_out_valid = '1' then
|
||||||
|
info <= spif_data_out;
|
||||||
|
state <= IDLE;
|
||||||
|
spif_data_in_valid <= '0';
|
||||||
|
end if;
|
||||||
|
when IDLE =>
|
||||||
|
null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process flashrom_controller_p;
|
||||||
|
end architecture RTL;
|
18
cores/flashrom-wb/flashrom_pkg.vhd
Normal file
18
cores/flashrom-wb/flashrom_pkg.vhd
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
package flashrom_pkg is
|
||||||
|
constant FLASHROM_ADDR_WIDTH : integer := 12;
|
||||||
|
constant FLASHROM_COMMAND_MANUFACTURER_ID : std_logic_vector(7 downto 0) := x"9F";
|
||||||
|
|
||||||
|
function padBits(target : std_logic_vector; other : std_logic_vector) return std_logic_vector;
|
||||||
|
end package flashrom_pkg;
|
||||||
|
|
||||||
|
package body flashrom_pkg is
|
||||||
|
function padBits(target : std_logic_vector; other : std_logic_vector) return std_logic_vector is
|
||||||
|
begin
|
||||||
|
return std_logic_vector(to_unsigned(0, target'length - other'length));
|
||||||
|
end function padBits;
|
||||||
|
|
||||||
|
end package body flashrom_pkg;
|
145
cores/flashrom-wb/flashrom_spi.vhd
Normal file
145
cores/flashrom-wb/flashrom_spi.vhd
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity flashrom_spi is
|
||||||
|
generic(
|
||||||
|
clk_divider : integer range 2 to 9999 := 2;
|
||||||
|
max_word_length : integer := 32;
|
||||||
|
max_dummy_bits : integer := 8
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
clr : in std_logic;
|
||||||
|
|
||||||
|
-- SPI flash hardware signals
|
||||||
|
spi_si : out std_logic; -- SPI serial in
|
||||||
|
spi_so : in std_logic; -- SPI serial out
|
||||||
|
spi_sck : out std_logic; -- Create clock using PLL, then supply to chip and this module
|
||||||
|
spi_cs_n : out std_logic; -- SPI chip select
|
||||||
|
|
||||||
|
-- Logic interface
|
||||||
|
data_in_valid : in std_logic; -- Data to Flash ROM
|
||||||
|
data_in : in std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
data_in_length : in integer range 0 to max_word_length;
|
||||||
|
data_next : out std_logic;
|
||||||
|
data_out : out std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
data_out_valid : out std_logic; -- Data from Flash ROM
|
||||||
|
data_out_length : in integer range 0 to max_word_length;
|
||||||
|
data_out_dummy_bits : in integer range 0 to max_dummy_bits;
|
||||||
|
transmission_active : out std_logic
|
||||||
|
);
|
||||||
|
end entity flashrom_spi;
|
||||||
|
|
||||||
|
architecture RTL of flashrom_spi is
|
||||||
|
type txstate_t is (IDLE, TX);
|
||||||
|
signal state : txstate_t;
|
||||||
|
signal ckDiv : integer range 0 to clk_divider - 2;
|
||||||
|
signal shiftreg : std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
signal bitCounter : integer range 0 to max_word_length - 1;
|
||||||
|
signal bitCounterIn : integer range 0 to max_word_length + max_dummy_bits - 1; -- TODO: Actually this must count until the higher of the two
|
||||||
|
signal data_in_length_i : integer range 0 to max_word_length;
|
||||||
|
signal data_out_length_i : integer range 0 to max_word_length;
|
||||||
|
signal delayCycle : std_logic;
|
||||||
|
signal oneBitRead : std_logic;
|
||||||
|
signal dummy_passed : boolean;
|
||||||
|
begin
|
||||||
|
toSpi : process(clk, rst) is
|
||||||
|
procedure default_state is
|
||||||
|
begin
|
||||||
|
data_next <= '0';
|
||||||
|
data_out_valid <= '0';
|
||||||
|
end procedure default_state;
|
||||||
|
|
||||||
|
procedure reset_state is
|
||||||
|
begin
|
||||||
|
state <= IDLE;
|
||||||
|
spi_sck <= '0';
|
||||||
|
shiftreg <= (others => '0');
|
||||||
|
bitCounter <= 0;
|
||||||
|
bitCounterIn <= 0;
|
||||||
|
data_out <= (others => '0');
|
||||||
|
delayCycle <= '0';
|
||||||
|
oneBitRead <= '0';
|
||||||
|
dummy_passed <= false;
|
||||||
|
default_state;
|
||||||
|
end procedure reset_state;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
reset_state;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
default_state;
|
||||||
|
if clr = '1' then
|
||||||
|
reset_state;
|
||||||
|
else
|
||||||
|
case state is
|
||||||
|
when IDLE =>
|
||||||
|
delayCycle <= '0';
|
||||||
|
spi_sck <= '0';
|
||||||
|
oneBitRead <= '0';
|
||||||
|
dummy_passed <= false;
|
||||||
|
data_out <= (others => '0');
|
||||||
|
if data_in_valid = '1' then
|
||||||
|
state <= TX;
|
||||||
|
bitCounter <= 0;
|
||||||
|
bitCounterIn <= 0;
|
||||||
|
data_in_length_i <= 0;
|
||||||
|
end if;
|
||||||
|
when TX =>
|
||||||
|
if ckDiv = clk_divider - 2 then
|
||||||
|
spi_sck <= not spi_sck;
|
||||||
|
if spi_sck = '0' then -- rising edge
|
||||||
|
if bitCounter = data_in_length_i then
|
||||||
|
bitCounter <= 0;
|
||||||
|
if data_in_valid = '1' then
|
||||||
|
shiftreg <= data_in;
|
||||||
|
data_in_length_i <= data_in_length - 1;
|
||||||
|
data_out_length_i <= data_out_length - 1;
|
||||||
|
data_next <= '1';
|
||||||
|
else
|
||||||
|
delayCycle <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
shiftreg <= shiftreg(shiftreg'high - 1 downto 0) & '0';
|
||||||
|
end if;
|
||||||
|
else -- spi_sck = '1' (falling edge)
|
||||||
|
data_out <= data_out(data_out'high - 1 downto 0) & spi_so;
|
||||||
|
|
||||||
|
if bitCounterIn = 0 then
|
||||||
|
if dummy_passed then
|
||||||
|
data_out_valid <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if not dummy_passed then
|
||||||
|
if bitCounterIn = data_out_dummy_bits then
|
||||||
|
dummy_passed <= true;
|
||||||
|
bitCounterIn <= 1;
|
||||||
|
else
|
||||||
|
bitCounterIn <= bitCounterIn + 1;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
if bitCounterIn = data_out_length_i then
|
||||||
|
bitCounterIn <= 0;
|
||||||
|
else
|
||||||
|
bitCounterIn <= bitCounterIn + 1;
|
||||||
|
end if;
|
||||||
|
if delayCycle = '1' then
|
||||||
|
spi_sck <= '0';
|
||||||
|
state <= IDLE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
ckDiv <= ckDiv + 1;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process toSpi;
|
||||||
|
spi_si <= shiftreg(shiftreg'high);
|
||||||
|
spi_cs_n <= '0' when state = TX else '1';
|
||||||
|
|
||||||
|
transmission_active <= '1' when state = TX else '0';
|
||||||
|
end architecture RTL;
|
141
cores/flashrom-wb/flashrom_spi2.copyvhd
Normal file
141
cores/flashrom-wb/flashrom_spi2.copyvhd
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity flashrom_spi is
|
||||||
|
generic(
|
||||||
|
clk_divider : integer range 2 to 9999 := 2;
|
||||||
|
max_word_length : integer := 32;
|
||||||
|
max_dummy_bits : integer := 8
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
clr : in std_logic;
|
||||||
|
|
||||||
|
-- SPI flash hardware signals
|
||||||
|
spi_si : out std_logic; -- SPI serial in
|
||||||
|
spi_so : in std_logic; -- SPI serial out
|
||||||
|
spi_sck : out std_logic; -- Create clock using PLL, then supply to chip and this module
|
||||||
|
spi_cs_n : out std_logic; -- SPI chip select
|
||||||
|
|
||||||
|
-- Logic interface
|
||||||
|
data_in_valid : in std_logic;
|
||||||
|
data_in : in std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
data_in_length : in integer range 0 to max_word_length;
|
||||||
|
data_next : out std_logic;
|
||||||
|
data_out : out std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
data_out_valid : out std_logic;
|
||||||
|
data_out_length : in integer range 0 to max_word_length;
|
||||||
|
data_out_dummy_bits : in integer range 0 to max_dummy_bits;
|
||||||
|
transmission_active : out std_logic
|
||||||
|
);
|
||||||
|
end entity flashrom_spi;
|
||||||
|
|
||||||
|
architecture RTL of flashrom_spi is
|
||||||
|
type txstate_t is (IDLE, TX);
|
||||||
|
signal state : txstate_t;
|
||||||
|
signal ckDiv : integer range 0 to clk_divider - 2;
|
||||||
|
signal shiftreg : std_logic_vector(max_word_length - 1 downto 0);
|
||||||
|
signal bitCounter : integer range 0 to max_word_length - 1;
|
||||||
|
signal bitCounterIn : integer range 0 to max_word_length + max_dummy_bits - 1;
|
||||||
|
signal data_in_length_i : integer range 0 to max_word_length;
|
||||||
|
signal data_out_length_i : integer range 0 to max_word_length;
|
||||||
|
signal delayCycle : std_logic;
|
||||||
|
signal oneBitRead : std_logic;
|
||||||
|
signal dummy_passed : boolean;
|
||||||
|
begin
|
||||||
|
toSpi : process(clk, rst) is
|
||||||
|
procedure default_state is
|
||||||
|
begin
|
||||||
|
data_next <= '0';
|
||||||
|
data_out_valid <= '0';
|
||||||
|
end procedure default_state;
|
||||||
|
|
||||||
|
procedure reset_state is
|
||||||
|
begin
|
||||||
|
state <= IDLE;
|
||||||
|
spi_sck <= '0';
|
||||||
|
shiftreg <= (others => '0');
|
||||||
|
bitCounter <= 0;
|
||||||
|
bitCounterIn <= 0;
|
||||||
|
data_out <= (others => '0');
|
||||||
|
delayCycle <= '0';
|
||||||
|
oneBitRead <= '0';
|
||||||
|
dummy_passed <= false;
|
||||||
|
default_state;
|
||||||
|
end procedure reset_state;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
reset_state;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
default_state;
|
||||||
|
if clr = '1' then
|
||||||
|
reset_state;
|
||||||
|
else
|
||||||
|
case state is
|
||||||
|
when IDLE =>
|
||||||
|
delayCycle <= '0';
|
||||||
|
spi_sck <= '0';
|
||||||
|
oneBitRead <= '0';
|
||||||
|
dummy_passed <= false;
|
||||||
|
data_out <= (others => '0');
|
||||||
|
if data_in_valid = '1' then
|
||||||
|
state <= TX;
|
||||||
|
bitCounter <= 0;
|
||||||
|
bitCounterIn <= 0;
|
||||||
|
data_in_length_i <= 0;
|
||||||
|
end if;
|
||||||
|
when TX =>
|
||||||
|
if ckDiv = clk_divider - 2 then
|
||||||
|
spi_sck <= not spi_sck;
|
||||||
|
if spi_sck = '0' then -- rising edge
|
||||||
|
if bitCounter = data_in_length_i then
|
||||||
|
bitCounter <= 0;
|
||||||
|
if data_in_valid = '1' then
|
||||||
|
shiftreg <= data_in;
|
||||||
|
data_in_length_i <= data_in_length - 1;
|
||||||
|
data_out_length_i <= data_out_length - 1;
|
||||||
|
data_next <= '1';
|
||||||
|
else
|
||||||
|
delayCycle <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
shiftreg <= shiftreg(shiftreg'high - 1 downto 0) & '0';
|
||||||
|
end if;
|
||||||
|
else -- spi_sck = '1' (falling edge)
|
||||||
|
data_out <= data_out(data_out'high - 1 downto 0) & spi_so;
|
||||||
|
oneBitRead <= '1';
|
||||||
|
if bitCounterIn = 0 then
|
||||||
|
if dummy_passed then
|
||||||
|
data_out_valid <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if not dummy_passed and bitCounterIn = data_out_dummy_bits then
|
||||||
|
dummy_passed <= true;
|
||||||
|
bitCounterIn <= 1;
|
||||||
|
else
|
||||||
|
if bitCounterIn = data_out_length_i then
|
||||||
|
bitCounterIn <= 0;
|
||||||
|
else
|
||||||
|
bitCounterIn <= bitCounterIn + 1;
|
||||||
|
end if;
|
||||||
|
if delayCycle = '1' then
|
||||||
|
spi_sck <= '0';
|
||||||
|
state <= IDLE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
ckDiv <= ckDiv + 1;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process toSpi;
|
||||||
|
spi_si <= shiftreg(shiftreg'high);
|
||||||
|
spi_cs_n <= '0' when state = TX else '1';
|
||||||
|
|
||||||
|
transmission_active <= '1' when state = TX else '0';
|
||||||
|
end architecture RTL;
|
31
cores/generic/edgeDetector.vhd
Normal file
31
cores/generic/edgeDetector.vhd
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity edgeDetector is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
sig : in std_logic;
|
||||||
|
risingEdge : out std_logic;
|
||||||
|
fallingEdge : out std_logic;
|
||||||
|
anyEdge : out std_logic
|
||||||
|
);
|
||||||
|
end entity edgeDetector;
|
||||||
|
|
||||||
|
architecture RTL of edgeDetector is
|
||||||
|
signal temp : std_logic_vector(1 downto 0);
|
||||||
|
begin
|
||||||
|
shiftomat : process(rst, clk) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
temp <= "00";
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
temp <= temp(0) & sig;
|
||||||
|
end if;
|
||||||
|
end process shiftomat;
|
||||||
|
|
||||||
|
risingEdge <= '1' when (temp = "01") else '0';
|
||||||
|
fallingEdge <= '1' when (temp = "10") else '0';
|
||||||
|
anyEdge <= '1' when (temp = "01" or temp = "10") else '0';
|
||||||
|
end architecture RTL;
|
31
cores/generic/synchronizer.vhd
Normal file
31
cores/generic/synchronizer.vhd
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity synchronizer is
|
||||||
|
generic(COUNT : integer := 1);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
dIn : in std_logic_vector(COUNT - 1 downto 0);
|
||||||
|
dOut : out std_logic_vector(COUNT - 1 downto 0)
|
||||||
|
);
|
||||||
|
end entity synchronizer;
|
||||||
|
|
||||||
|
architecture RTL of synchronizer is
|
||||||
|
signal temp : std_logic_vector(COUNT - 1 downto 0);
|
||||||
|
begin
|
||||||
|
synch : process(rst, clk) is
|
||||||
|
begin
|
||||||
|
for i in 0 to COUNT - 1 loop
|
||||||
|
if rst = '1' then
|
||||||
|
temp(i) <= '0';
|
||||||
|
dOut(i) <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
temp(i) <= dIn(i);
|
||||||
|
dOut(i) <= temp(i);
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end process synch;
|
||||||
|
|
||||||
|
end architecture RTL;
|
199
cores/jinn.vhd
Normal file
199
cores/jinn.vhd
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
-- A simple Wishbone interface, controllable via UART.
|
||||||
|
-- Author: Markus Koch <markus-oliver.koch@thalesgroup.com>
|
||||||
|
--
|
||||||
|
-- Instructions:
|
||||||
|
-- Write: TX [Write-Count] [32b Addr] [32b Data] -------- [32b Addr] [32b Data] -------- ... [Write-Count] [32b Addr] [32b Data] ...
|
||||||
|
-- RX ----------------------------------- [8b CKS] --------------------- [8b CKS] ... ----------------------------------- ...
|
||||||
|
--
|
||||||
|
-- Read: TX [8b 0x0] [32b Addr] ---------- [32b Addr] ...
|
||||||
|
-- RX ------------------- [32b Data] ---------- ...
|
||||||
|
--
|
||||||
|
-- Stall: TX [8b 0xFF]
|
||||||
|
-- RX ---------
|
||||||
|
--
|
||||||
|
-- Reset: TX [8b 0xFE]
|
||||||
|
-- ---------
|
||||||
|
--
|
||||||
|
-- Log:
|
||||||
|
-- 2015/06/24: Created file
|
||||||
|
-- 2015/06/24: Removed logic for tx/rx buffers
|
||||||
|
-- 2015/07/14: Added stall/reset logic
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library ip;
|
||||||
|
use ip.wishbone_package.all;
|
||||||
|
|
||||||
|
entity jinn is
|
||||||
|
port(
|
||||||
|
clk_i : in std_logic;
|
||||||
|
rst_i : in std_logic;
|
||||||
|
|
||||||
|
-- Wishbone
|
||||||
|
master_i : in wishbone_v3_master_in;
|
||||||
|
master_o : out wishbone_v3_master_out;
|
||||||
|
|
||||||
|
-- CPU Control
|
||||||
|
cpu_stall : out std_logic;
|
||||||
|
cpu_reset : out std_logic;
|
||||||
|
|
||||||
|
-- Data link
|
||||||
|
data_i : in std_logic_vector(7 downto 0); -- Data in from UART
|
||||||
|
data_available : in std_logic; -- UART RX strobe
|
||||||
|
|
||||||
|
data_o : out std_logic_vector(7 downto 0); -- Data out to UART
|
||||||
|
data_valid_o : out std_logic; -- Data out strobe
|
||||||
|
output_busy_i : in std_logic -- Transmit busy -> stall core
|
||||||
|
);
|
||||||
|
end entity jinn;
|
||||||
|
|
||||||
|
architecture RTL of jinn is
|
||||||
|
signal write_counter : integer range 0 to 255;
|
||||||
|
signal position : integer range 0 to 7;
|
||||||
|
signal address : wishbone_address;
|
||||||
|
signal data : wishbone_data;
|
||||||
|
signal cks : unsigned(7 downto 0);
|
||||||
|
|
||||||
|
type state_t is (COMMAND, PARSE, EXECUTE, TXSERIAL);
|
||||||
|
signal state : state_t;
|
||||||
|
signal txDelay : std_logic;
|
||||||
|
begin
|
||||||
|
jinn_p : process(clk_i, rst_i) is
|
||||||
|
begin
|
||||||
|
if rst_i = '1' then
|
||||||
|
-- RESET!
|
||||||
|
position <= 0;
|
||||||
|
state <= COMMAND;
|
||||||
|
write_counter <= 0;
|
||||||
|
data_valid_o <= '0';
|
||||||
|
address <= (others => '0');
|
||||||
|
data <= (others => '0');
|
||||||
|
master_o.CYC <= '0';
|
||||||
|
master_o.STB <= '0';
|
||||||
|
master_o.ADR <= (others => '0');
|
||||||
|
master_o.DAT <= (others => '0');
|
||||||
|
master_o.WE <= '0';
|
||||||
|
txDelay <= '0';
|
||||||
|
cks <= (others => '0');
|
||||||
|
cpu_stall <= '0';
|
||||||
|
cpu_reset <= '1';
|
||||||
|
elsif rising_edge(clk_i) then
|
||||||
|
data_valid_o <= '0';
|
||||||
|
master_o.CYC <= '0';
|
||||||
|
master_o.STB <= '0';
|
||||||
|
|
||||||
|
cpu_reset <= '0';
|
||||||
|
|
||||||
|
case state is
|
||||||
|
when COMMAND =>
|
||||||
|
cks <= (others => '0');
|
||||||
|
position <= 0;
|
||||||
|
txDelay <= '0';
|
||||||
|
if data_available = '1' then
|
||||||
|
if unsigned(data_i) = x"FF" then
|
||||||
|
cpu_stall <= '1';
|
||||||
|
elsif unsigned(data_i) = x"FE" then
|
||||||
|
cpu_reset <= '1';
|
||||||
|
cpu_stall <= '0';
|
||||||
|
else
|
||||||
|
write_counter <= to_integer(unsigned(data_i));
|
||||||
|
state <= PARSE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when PARSE =>
|
||||||
|
if data_available = '1' then
|
||||||
|
cks <= cks + unsigned(data_i); -- Sum everything, address and data
|
||||||
|
if position < 7 then
|
||||||
|
position <= position + 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if position < 4 then -- addr word
|
||||||
|
--address(8 * (position + 1) - 1 downto 8 * position) <= data_i;
|
||||||
|
address <= address(23 downto 0) & data_i;
|
||||||
|
else -- data word
|
||||||
|
--data(8 * (position + 1 - 4) - 1 downto 8 * (position - 4)) <= data_i;
|
||||||
|
data <= data(23 downto 0) & data_i;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if (position = 7) or (position = 3 and write_counter = 0) then -- only retrieve address in read mode
|
||||||
|
position <= 0;
|
||||||
|
state <= EXECUTE;
|
||||||
|
|
||||||
|
-- master_o.ADR <= address;
|
||||||
|
-- master_o.DAT <= data;
|
||||||
|
-- master_o.CYC <= '1';
|
||||||
|
-- master_o.STB <= '1';
|
||||||
|
-- if write_counter = 0 then
|
||||||
|
-- master_o.WE <= '0';
|
||||||
|
-- else
|
||||||
|
-- master_o.WE <= '1';
|
||||||
|
-- end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when EXECUTE =>
|
||||||
|
master_o.ADR <= address;
|
||||||
|
master_o.DAT <= data;
|
||||||
|
master_o.CYC <= '1';
|
||||||
|
master_o.STB <= '1';
|
||||||
|
if write_counter = 0 then
|
||||||
|
master_o.WE <= '0';
|
||||||
|
else
|
||||||
|
master_o.WE <= '1';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if master_i.ERR = '1' or master_i.ACK = '1' then -- END OF transmission
|
||||||
|
master_o.CYC <= '0';
|
||||||
|
master_o.STB <= '0';
|
||||||
|
|
||||||
|
if write_counter = 0 then -- read
|
||||||
|
data <= master_i.DAT;
|
||||||
|
state <= TXSERIAL;
|
||||||
|
position <= 0;
|
||||||
|
else
|
||||||
|
write_counter <= write_counter - 1;
|
||||||
|
if master_i.ACK = '1' then
|
||||||
|
data <= std_logic_vector(cks) & x"000000"; -- ACK!
|
||||||
|
else
|
||||||
|
data <= not std_logic_vector(cks) & x"FFFFFF"; -- NAK! by sending a probably woring checksum
|
||||||
|
end if;
|
||||||
|
position <= 3; -- Only transmit one byte (the checksum)
|
||||||
|
state <= TXSERIAL;
|
||||||
|
cks <= (others => '0');
|
||||||
|
end if;
|
||||||
|
elsif master_i.RTY = '1' then
|
||||||
|
null;
|
||||||
|
-- wait
|
||||||
|
end if;
|
||||||
|
when TXSERIAL =>
|
||||||
|
txDelay <= not txDelay;
|
||||||
|
if txDelay = '0' and output_busy_i = '0' then -- only every odd cycle (uart has a busy-activate delay of 1)
|
||||||
|
--data_o <= address(8 * (position + 1) - 1 downto 8 * position);
|
||||||
|
data_o <= data(31 downto 24);
|
||||||
|
data <= data(23 downto 0) & x"00";
|
||||||
|
data_valid_o <= '1';
|
||||||
|
|
||||||
|
if position = 3 then
|
||||||
|
position <= 0;
|
||||||
|
if write_counter = 0 then
|
||||||
|
state <= COMMAND; -- R/W selector (Write-Count)
|
||||||
|
else
|
||||||
|
state <= PARSE; -- more writes are following directly
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
position <= position + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
--master_o.CYC <= '0'; -- DEBUG ONLY - diasble moduel
|
||||||
|
--master_o.STB <= '0'; -- DEBUG ONYL
|
||||||
|
end if;
|
||||||
|
end process jinn_p;
|
||||||
|
master_o.SEL <= "1111";
|
||||||
|
|
||||||
|
master_o.BTE <= (others => '0');
|
||||||
|
master_o.CTI <= (others => '0');
|
||||||
|
master_o.LOCK <= '0';
|
||||||
|
end architecture RTL;
|
60
cores/sram/sram_wb.vhd
Normal file
60
cores/sram/sram_wb.vhd
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library ip;
|
||||||
|
use ip.wishbone_package.all;
|
||||||
|
use ip.all;
|
||||||
|
|
||||||
|
entity sram_wb is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
|
||||||
|
-- Wishbone
|
||||||
|
wb_in : in wishbone_v3_slave_in;
|
||||||
|
wb_out : out wishbone_v3_slave_out
|
||||||
|
);
|
||||||
|
end entity sram_wb;
|
||||||
|
|
||||||
|
architecture RTL of sram_wb is
|
||||||
|
signal ram_address : std_logic_vector(10 DOWNTO 0);
|
||||||
|
signal ram_byteena : std_logic_vector(3 DOWNTO 0);
|
||||||
|
signal ram_dIn : std_logic_vector(31 DOWNTO 0);
|
||||||
|
signal ram_we : std_logic;
|
||||||
|
signal ram_dOut : std_logic_vector(31 DOWNTO 0);
|
||||||
|
signal ackRead : std_logic;
|
||||||
|
begin
|
||||||
|
ram0_inst : entity ip.ram0
|
||||||
|
port map(
|
||||||
|
address => ram_address,
|
||||||
|
byteena => ram_byteena,
|
||||||
|
clock => clk,
|
||||||
|
data => ram_dIn,
|
||||||
|
wren => ram_we,
|
||||||
|
q => ram_dOut
|
||||||
|
);
|
||||||
|
|
||||||
|
sram_p : process(clk, rst) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
ackRead <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
ackRead <= '0';
|
||||||
|
if wb_in.CYC = '1' and wb_in.STB = '1' and wb_in.WE = '0' then
|
||||||
|
ackRead <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process sram_p;
|
||||||
|
|
||||||
|
ram_address <= wb_in.ADR(12 downto 2);
|
||||||
|
ram_we <= wb_in.WE and wb_in.CYC and wb_in.STB;
|
||||||
|
wb_out.ACK <= (wb_in.WE or ackRead) and wb_in.CYC and wb_in.STB;
|
||||||
|
wb_out.ERR <= '0';
|
||||||
|
wb_out.RTY <= '0';
|
||||||
|
wb_out.DAT <= ram_dOut;
|
||||||
|
|
||||||
|
ram_dIn <= wb_in.DAT;
|
||||||
|
ram_byteena <= wb_in.SEL;
|
||||||
|
|
||||||
|
end architecture RTL;
|
155
cores/uart/uart_rx.vhd
Normal file
155
cores/uart/uart_rx.vhd
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
-- A simple UART (TX)
|
||||||
|
-- Author : Kurisu <kurisu@shimatta.de>
|
||||||
|
-- Modifed : Markus <markus-oliver.koch@thalesgroup.com>
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity uart_rx is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
data : out std_logic_vector(7 downto 0);
|
||||||
|
byte_ready : out std_logic;
|
||||||
|
error : out std_logic;
|
||||||
|
|
||||||
|
ckDiv : in std_logic_vector(15 downto 0);
|
||||||
|
parityEnable : in std_logic;
|
||||||
|
parityOdd : in std_logic;
|
||||||
|
twoStopBits : in std_logic;
|
||||||
|
|
||||||
|
rx : in std_logic
|
||||||
|
);
|
||||||
|
end entity uart_rx;
|
||||||
|
|
||||||
|
architecture RTL of uart_rx is
|
||||||
|
constant SYNCH_COUNT : integer := 11; -- Min. 8
|
||||||
|
constant BITCOUNT : integer := 8;
|
||||||
|
|
||||||
|
type state_t is (SYNCH, IDLE, START, RECEIVE, PARITY, STOP);
|
||||||
|
|
||||||
|
signal state : state_t;
|
||||||
|
signal clkDivider : unsigned(15 downto 0);
|
||||||
|
signal bitCounter : integer range 0 to SYNCH_COUNT;
|
||||||
|
signal data_i : std_logic_vector(7 downto 0);
|
||||||
|
signal rx_edge : std_logic;
|
||||||
|
signal parity_calc : std_logic;
|
||||||
|
signal rx_i : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
synchronizer_inst : entity work.synchronizer
|
||||||
|
generic map(
|
||||||
|
COUNT => 1
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
dIn(0) => rx,
|
||||||
|
dOut(0) => rx_i
|
||||||
|
);
|
||||||
|
|
||||||
|
edgeDetector_inst : entity work.edgeDetector
|
||||||
|
port map(clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
sig => rx_i,
|
||||||
|
risingEdge => open,
|
||||||
|
fallingEdge => open,
|
||||||
|
anyEdge => rx_edge);
|
||||||
|
|
||||||
|
rxFSM : process(clk, rst, parityOdd, ckDiv) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
state <= SYNCH;
|
||||||
|
bitCounter <= SYNCH_COUNT;
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
error <= '0';
|
||||||
|
parity_calc <= parityOdd;
|
||||||
|
data_i <= x"00";
|
||||||
|
data <= x"00";
|
||||||
|
byte_ready <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
byte_ready <= '0';
|
||||||
|
error <= '0';
|
||||||
|
if (clkDivider = 0) then
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
else
|
||||||
|
clkDivider <= clkDivider - 1;
|
||||||
|
end if;
|
||||||
|
case state is
|
||||||
|
when SYNCH => -- Wait for 11 consecutive ones
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if rx_i = '1' then
|
||||||
|
if bitCounter = 0 then
|
||||||
|
state <= IDLE;
|
||||||
|
else
|
||||||
|
bitCounter <= bitcounter - 1;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= SYNCH_COUNT;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when IDLE => -- Detect transition for sync
|
||||||
|
if rx_i = '0' then
|
||||||
|
state <= START;
|
||||||
|
clkDivider <= unsigned('0' & ckDiv(15 downto 1)); -- cMax_half. After that we are in the middle of the start bit
|
||||||
|
parity_calc <= parityOdd;
|
||||||
|
end if;
|
||||||
|
when START =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if rx_i = '0' then
|
||||||
|
state <= RECEIVE;
|
||||||
|
bitCounter <= 0;
|
||||||
|
else
|
||||||
|
report "uart_rx: START BIT ERROR" severity warning;
|
||||||
|
error <= '1';
|
||||||
|
state <= SYNCH;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when RECEIVE =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
data_i(bitCounter) <= rx_i;
|
||||||
|
if rx_i = '1' then
|
||||||
|
parity_calc <= not parity_calc;
|
||||||
|
end if;
|
||||||
|
if bitCounter = BITCOUNT - 1 then
|
||||||
|
bitCounter <= 0;
|
||||||
|
if parityEnable = '1' then
|
||||||
|
state <= PARITY;
|
||||||
|
else
|
||||||
|
state <= STOP;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when PARITY =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if parity_calc = rx_i then
|
||||||
|
state <= STOP;
|
||||||
|
else
|
||||||
|
state <= SYNCH;
|
||||||
|
error <= '1';
|
||||||
|
report "uart_rx: PARITY ERROR" severity warning;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when STOP =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
if (rx_i = '1') then
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
if bitCounter = 1 or twoStopBits = '0' then
|
||||||
|
state <= IDLE;
|
||||||
|
data <= data_i;
|
||||||
|
byte_ready <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
error <= '1';
|
||||||
|
state <= SYNCH;
|
||||||
|
report "uart_rx: STOP BIT ERROR" severity warning;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process rxFSM;
|
||||||
|
|
||||||
|
end architecture RTL;
|
104
cores/uart/uart_tx.vhd
Normal file
104
cores/uart/uart_tx.vhd
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
-- A simple UART (TX)
|
||||||
|
-- Author : Kurisu <kurisu@shimatta.de>
|
||||||
|
-- Modifed : Markus <markus-oliver.koch@thalesgroup.com>
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity uart_tx is
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
data : in std_logic_vector(7 downto 0);
|
||||||
|
byte_ready : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
|
||||||
|
ckDiv : in std_logic_vector(15 downto 0);
|
||||||
|
parityEnable : in std_logic;
|
||||||
|
parityOdd : in std_logic;
|
||||||
|
twoStopBits : in std_logic;
|
||||||
|
|
||||||
|
tx : out std_logic
|
||||||
|
);
|
||||||
|
end entity uart_tx;
|
||||||
|
|
||||||
|
architecture RTL of uart_tx is
|
||||||
|
type state_t is (IDLE, START, TRANSMIT, PARITY, STOP);
|
||||||
|
|
||||||
|
signal state : state_t;
|
||||||
|
signal clkDivider : unsigned(15 downto 0);
|
||||||
|
signal data_i : std_logic_vector(7 downto 0);
|
||||||
|
signal bitCounter : integer range 0 to 7;
|
||||||
|
signal parity_calc : std_logic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
txFSM : process(clk, rst, ckDiv, parityOdd) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
data_i <= x"00";
|
||||||
|
state <= IDLE;
|
||||||
|
tx <= '1';
|
||||||
|
bitCounter <= 0;
|
||||||
|
busy <= '0';
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
parity_calc <= parityOdd;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
busy <= '1';
|
||||||
|
|
||||||
|
if (clkDivider = 0) then
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
else
|
||||||
|
clkDivider <= clkDivider - 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
case state is
|
||||||
|
when IDLE =>
|
||||||
|
busy <= '0';
|
||||||
|
tx <= '1';
|
||||||
|
if byte_ready = '1' then
|
||||||
|
data_i <= data;
|
||||||
|
state <= START;
|
||||||
|
clkDivider <= unsigned(ckDiv);
|
||||||
|
bitCounter <= 0;
|
||||||
|
parity_calc <= '0';
|
||||||
|
busy <= '1';
|
||||||
|
tx <= '1';
|
||||||
|
end if;
|
||||||
|
when START =>
|
||||||
|
tx <= '0';
|
||||||
|
state <= TRANSMIT;
|
||||||
|
when TRANSMIT =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
tx <= data_i(bitCounter);
|
||||||
|
if data_i(bitCounter) = '1' then
|
||||||
|
parity_calc <= not parity_calc;
|
||||||
|
end if;
|
||||||
|
if bitCounter = 7 then
|
||||||
|
bitCounter <= 0;
|
||||||
|
if parityEnable = '1' then
|
||||||
|
state <= PARITY;
|
||||||
|
else
|
||||||
|
state <= STOP;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when PARITY =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
tx <= parity_calc;
|
||||||
|
state <= STOP;
|
||||||
|
end if;
|
||||||
|
when STOP =>
|
||||||
|
if (clkDivider = to_unsigned(0, clkDivider'length)) then
|
||||||
|
tx <= '1';
|
||||||
|
bitCounter <= bitCounter + 1;
|
||||||
|
if (bitCounter = 1 and twoStopBits = '0') or (bitCounter = 2 and twoStopBits = '1') then
|
||||||
|
state <= IDLE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process txFSM;
|
||||||
|
end architecture RTL;
|
162
cores/uart/uart_wb.vhd
Normal file
162
cores/uart/uart_wb.vhd
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
use ieee.std_logic_misc.OR_REDUCE;
|
||||||
|
|
||||||
|
library ip;
|
||||||
|
use ip.wishbone_package.all;
|
||||||
|
|
||||||
|
entity uart_wb is
|
||||||
|
generic(
|
||||||
|
portcount : integer := 1
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
-- Wishbone
|
||||||
|
slave_i : in wishbone_slave_in;
|
||||||
|
slave_o : out wishbone_slave_out;
|
||||||
|
irq_o : out std_logic_vector(portcount - 1 downto 0);
|
||||||
|
-- UART
|
||||||
|
rx : in std_logic_vector(portcount - 1 downto 0);
|
||||||
|
tx : out std_logic_vector(portcount - 1 downto 0)
|
||||||
|
);
|
||||||
|
end entity uart_wb;
|
||||||
|
|
||||||
|
architecture RTL of uart_wb is
|
||||||
|
constant addressQuantum : integer := 4;
|
||||||
|
constant registersPerCore : integer := 5;
|
||||||
|
|
||||||
|
type uart_data is array (portcount - 1 downto 0) of std_logic_vector(7 downto 0);
|
||||||
|
type uart_ckDiv is array (portcount - 1 downto 0) of std_logic_vector(15 downto 0);
|
||||||
|
type uart_register is array (portcount - 1 downto 0) of std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
|
signal rx_data : uart_data;
|
||||||
|
signal rx_byte_ready : std_logic_vector(portcount - 1 downto 0);
|
||||||
|
signal rx_error : std_logic_vector(portcount - 1 downto 0);
|
||||||
|
signal ckDiv : uart_ckDiv;
|
||||||
|
signal parityEnable : std_logic_vector(portcount - 1 downto 0);
|
||||||
|
signal parityOdd : std_logic_vector(portcount - 1 downto 0);
|
||||||
|
signal twoStopBits : std_logic_vector(portcount - 1 downto 0);
|
||||||
|
signal tx_data : uart_data;
|
||||||
|
signal tx_strobe : std_logic_vector(portcount - 1 downto 0);
|
||||||
|
signal tx_busy : std_logic_vector(portcount - 1 downto 0);
|
||||||
|
|
||||||
|
signal CR : uart_register;
|
||||||
|
signal SR : uart_register;
|
||||||
|
signal IMR : uart_register;
|
||||||
|
signal MASKEDSR : uart_register;
|
||||||
|
|
||||||
|
signal data_in_buffered : uart_data;
|
||||||
|
|
||||||
|
begin
|
||||||
|
generate_label : for i in 0 to portcount - 1 generate
|
||||||
|
uart_rx_inst : entity work.uart_rx
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
data => rx_data(i),
|
||||||
|
byte_ready => rx_byte_ready(i),
|
||||||
|
error => rx_error(i),
|
||||||
|
ckDiv => ckDiv(i),
|
||||||
|
parityEnable => parityEnable(i),
|
||||||
|
parityOdd => parityOdd(i),
|
||||||
|
twoStopBits => twoStopBits(i),
|
||||||
|
rx => rx(i)
|
||||||
|
);
|
||||||
|
uart_tx_inst : entity work.uart_tx
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
data => tx_data(i),
|
||||||
|
byte_ready => tx_strobe(i),
|
||||||
|
busy => tx_busy(i),
|
||||||
|
ckDiv => ckDiv(i),
|
||||||
|
parityEnable => parityEnable(i),
|
||||||
|
parityOdd => parityOdd(i),
|
||||||
|
twoStopBits => twoStopBits(i),
|
||||||
|
tx => tx(i)
|
||||||
|
);
|
||||||
|
end generate generate_label;
|
||||||
|
|
||||||
|
wb : process(rst, clk) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
slave_o.DAT <= (others => '0');
|
||||||
|
|
||||||
|
for i in 0 to portcount - 1 loop
|
||||||
|
SR(i) <= (others => '0');
|
||||||
|
CR(i) <= (others => '0');
|
||||||
|
IMR(i) <= (others => '0');
|
||||||
|
tx_strobe(i) <= '0';
|
||||||
|
tx_data(i) <= (others => '0');
|
||||||
|
end loop;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
for i in 0 to portcount - 1 loop
|
||||||
|
slave_o.ACK <= '0';
|
||||||
|
tx_strobe(i) <= '0';
|
||||||
|
|
||||||
|
--SR update
|
||||||
|
if (rx_error(i) = '1') then
|
||||||
|
SR(i)(17) <= '1'; -- Set RXEI
|
||||||
|
end if;
|
||||||
|
if (rx_byte_ready(i) = '1') then
|
||||||
|
SR(i)(18) <= '1'; -- Set RXI
|
||||||
|
SR(i)(16) <= '1'; -- Set RXNE (no FIFO yet)
|
||||||
|
data_in_buffered(i) <= rx_data(i);
|
||||||
|
end if;
|
||||||
|
|
||||||
|
SR(i)(0) <= tx_busy(i); -- TXBF; no FIFO
|
||||||
|
SR(i)(1) <= tx_busy(i); -- TXActive
|
||||||
|
|
||||||
|
-- WB
|
||||||
|
if slave_i.CYC = '1' and slave_i.STB = '1' then
|
||||||
|
if unsigned(slave_i.ADR) = to_unsigned((registersPerCore * i), slave_i.ADR'length) then -- CRx
|
||||||
|
slave_o.DAT <= CR(i);
|
||||||
|
if slave_i.we = '1' then
|
||||||
|
CR(i) <= slave_i.DAT;
|
||||||
|
end if;
|
||||||
|
elsif unsigned(slave_i.ADR) = to_unsigned((registersPerCore * i) + 1 * addressQuantum, slave_i.ADR'length) then --SRx
|
||||||
|
slave_o.DAT <= SR(i);
|
||||||
|
if slave_i.we = '1' then
|
||||||
|
SR(i) <= slave_i.DAT and (x"00" & "00000110" & x"0000"); -- mask RO bits
|
||||||
|
end if;
|
||||||
|
elsif unsigned(slave_i.ADR) = to_unsigned((registersPerCore * i) + 2 * addressQuantum, slave_i.ADR'length) then --IMRx
|
||||||
|
slave_o.DAT <= IMR(i);
|
||||||
|
if slave_i.we = '1' then
|
||||||
|
IMR(i) <= slave_i.DAT;
|
||||||
|
end if;
|
||||||
|
elsif unsigned(slave_i.ADR) = to_unsigned((registersPerCore * i) + 3 * addressQuantum, slave_i.ADR'length) then --ODRx
|
||||||
|
slave_o.DAT <= x"000000" & tx_data(i); --(others => '0');
|
||||||
|
if slave_i.we = '1' then
|
||||||
|
tx_data(i) <= slave_i.DAT(7 downto 0);
|
||||||
|
tx_strobe(i) <= '1';
|
||||||
|
end if;
|
||||||
|
elsif unsigned(slave_i.ADR) = to_unsigned((registersPerCore * i) + 4 * addressQuantum, slave_i.ADR'length) then --IDRx
|
||||||
|
slave_o.DAT <= x"000000" & data_in_buffered(i);
|
||||||
|
SR(i)(18) <= '0'; -- RXI Clear interrupt
|
||||||
|
SR(i)(16) <= '0'; -- RXNE No FIFO -> buffer is immediately empty again
|
||||||
|
end if;
|
||||||
|
slave_o.ACK <= '1';
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
end process wb;
|
||||||
|
|
||||||
|
slave_o.RTY <= '0';
|
||||||
|
slave_o.STALL <= '0';
|
||||||
|
slave_o.ERR <= '0';
|
||||||
|
|
||||||
|
applyCR : for i in 0 to portcount - 1 generate
|
||||||
|
ckDiv(i) <= CR(i)(31 downto 16);
|
||||||
|
parityEnable(i) <= CR(i)(1);
|
||||||
|
parityOdd(i) <= CR(i)(0);
|
||||||
|
twoStopBits(i) <= CR(i)(2);
|
||||||
|
end generate applyCR;
|
||||||
|
|
||||||
|
masking : for i in 0 to portcount - 1 generate
|
||||||
|
MASKEDSR(i) <= SR(i) and IMR(i);
|
||||||
|
irq_o(i) <= OR_REDUCE(MASKEDSR(i));
|
||||||
|
end generate masking;
|
||||||
|
|
||||||
|
end architecture RTL;
|
53
datasets/ram_init - Copy.hex
Normal file
53
datasets/ram_init - Copy.hex
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
:1000000000000000150000000000000000000000DB
|
||||||
|
:1000100000000000000000000000000000000000E0
|
||||||
|
:1000200000000000000000000000000000000000D0
|
||||||
|
:1000300000000000000000000000000000000000C0
|
||||||
|
:1000400000000000000000000000000000000000B0
|
||||||
|
:1000500000000000000000000000000000000000A0
|
||||||
|
:100060000000000000000000000000000000000090
|
||||||
|
:100070000000000000000000000000000000000080
|
||||||
|
:100080000000000000000000000000000000000070
|
||||||
|
:100090000000000000000000000000000000000060
|
||||||
|
:1000A0000000000000000000000000000000000050
|
||||||
|
:1000B0000000000000000000000000000000000040
|
||||||
|
:1000C0000000000000000000000000000000000030
|
||||||
|
:1000D0000000000000000000000000000000000020
|
||||||
|
:1000E0000000000000000000000000000000000010
|
||||||
|
:1000F0000000000000000000000000000000000000
|
||||||
|
:100100001500000015000000180000001820000174
|
||||||
|
:10011000A821FFFC18400001A842FFFC1860000164
|
||||||
|
:10012000A863738018800001A8847474E404180024
|
||||||
|
:100130001000000615000000D80300009C630001B9
|
||||||
|
:1001400003FFFFFB1500000018600001A8636800B2
|
||||||
|
:1001500018800001A88470C818A00001A8A5279DD8
|
||||||
|
:10016000E404180010000008150000008CC5000011
|
||||||
|
:10017000D80330009C6300019CA5000103FFFFF938
|
||||||
|
:10018000150000009C6000009C8000009CA0000006
|
||||||
|
:100190009CC000009CE000009D0000009D4000000D
|
||||||
|
:1001A0009D6000009D8000009DA000009DC000009B
|
||||||
|
:1001B0009DE000009E0000009E2000009E40000088
|
||||||
|
:1001C0009E6000009E8000009EA00000188000003D
|
||||||
|
:1001D000A8842004480020001500000018800001B9
|
||||||
|
:1001E000A88412704800200015000000188000004C
|
||||||
|
:1001F000A88420284800200015000000000000000E
|
||||||
|
:10020000150000009C21FF0CD4014818040002D402
|
||||||
|
:100210001500000019200000A9290DD41860000065
|
||||||
|
:10022000A86322E044001800150000000000000050
|
||||||
|
:1002300000000000000000000000000000000000BE
|
||||||
|
:1002400000000000000000000000000000000000AE
|
||||||
|
:10025000000000000000000000000000000000009E
|
||||||
|
:10026000000000000000000000000000000000008E
|
||||||
|
:10027000000000000000000000000000000000007E
|
||||||
|
:10028000000000000000000000000000000000006E
|
||||||
|
:10029000000000000000000000000000000000005E
|
||||||
|
:1002A000000000000000000000000000000000004E
|
||||||
|
:1002B000000000000000000000000000000000003E
|
||||||
|
:1002C000000000000000000000000000000000002E
|
||||||
|
:1002D000000000000000000000000000000000001E
|
||||||
|
:1002E000000000000000000000000000000000000E
|
||||||
|
:1002F00000000000000000000000000000000000FE
|
||||||
|
:10030000150000009C21FF0CD40148180400029441
|
||||||
|
:100310001500000019200000A9290DD41860000064
|
||||||
|
:10032000A8630D2C44001800150000000000000018
|
||||||
|
:1003300000000000000000000000000000000000BD
|
||||||
|
:1003400000000000000000000000000000000000AD
|
37
datasets/ram_init.hex
Normal file
37
datasets/ram_init.hex
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
:100040001500000015000000180000001820000174
|
||||||
|
:10004400A821FFFC18400001A842FFFC1860000164
|
||||||
|
:10004800A863738018800001A8847474E404180024
|
||||||
|
:10004C001000000615000000D80300009C630001B9
|
||||||
|
:1000500003FFFFFB1500000018600001A8636800B2
|
||||||
|
:1000540018800001A88470C818A00001A8A5279DD8
|
||||||
|
:10005800E404180010000008150000008CC5000011
|
||||||
|
:10005C00D80330009C6300019CA5000103FFFFF938
|
||||||
|
:10006000150000009C6000009C8000009CA0000006
|
||||||
|
:100064009CC000009CE000009D0000009D4000000D
|
||||||
|
:100068009D6000009D8000009DA000009DC000009B
|
||||||
|
:10006C009DE000009E0000009E2000009E40000088
|
||||||
|
:100070009E6000009E8000009EA00000188000003D
|
||||||
|
:1001D000A8842004480020001500000018800001B9
|
||||||
|
:1001E000A88412704800200015000000188000004C
|
||||||
|
:1001F000A88420284800200015000000000000000E
|
||||||
|
:10020000150000009C21FF0CD4014818040002D402
|
||||||
|
:100210001500000019200000A9290DD41860000065
|
||||||
|
:10022000A86322E044001800150000000000000050
|
||||||
|
:1002300000000000000000000000000000000000BE
|
||||||
|
:1002400000000000000000000000000000000000AE
|
||||||
|
:10025000000000000000000000000000000000009E
|
||||||
|
:10026000000000000000000000000000000000008E
|
||||||
|
:10027000000000000000000000000000000000007E
|
||||||
|
:10028000000000000000000000000000000000006E
|
||||||
|
:10029000000000000000000000000000000000005E
|
||||||
|
:1002A000000000000000000000000000000000004E
|
||||||
|
:1002B000000000000000000000000000000000003E
|
||||||
|
:1002C000000000000000000000000000000000002E
|
||||||
|
:1002D000000000000000000000000000000000001E
|
||||||
|
:1002E000000000000000000000000000000000000E
|
||||||
|
:1002F00000000000000000000000000000000000FE
|
||||||
|
:10030000150000009C21FF0CD40148180400029441
|
||||||
|
:100310001500000019200000A9290DD41860000064
|
||||||
|
:10032000A8630D2C44001800150000000000000018
|
||||||
|
:1003300000000000000000000000000000000000BD
|
||||||
|
:1003400000000000000000000000000000000000AD
|
321
design/top.vhd
Normal file
321
design/top.vhd
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library ddr3;
|
||||||
|
|
||||||
|
library ip;
|
||||||
|
use ip.wishbone_package.all;
|
||||||
|
use ip.mor1kx_pkg.all;
|
||||||
|
|
||||||
|
entity top is
|
||||||
|
port(
|
||||||
|
clk_hw : in std_logic;
|
||||||
|
rst_hw : in std_logic;
|
||||||
|
|
||||||
|
-- GPIO
|
||||||
|
GPIOA : inout std_logic_vector(wishbone_data_width - 1 downto 0);
|
||||||
|
|
||||||
|
-- JINN
|
||||||
|
jinn_uart_rx : in std_logic;
|
||||||
|
jinn_uart_tx : out std_logic;
|
||||||
|
|
||||||
|
-- UART
|
||||||
|
uart_rx : in std_logic;
|
||||||
|
uart_tx : out std_logic;
|
||||||
|
|
||||||
|
-- DDR3 RAM
|
||||||
|
mem_a : out std_logic_vector(12 downto 0); -- memory.mem_a
|
||||||
|
mem_ba : out std_logic_vector(2 downto 0); -- .mem_ba
|
||||||
|
mem_ck : out std_logic_vector(0 downto 0); -- .mem_ck
|
||||||
|
mem_ck_n : out std_logic_vector(0 downto 0); -- .mem_ck_n
|
||||||
|
mem_cke : out std_logic_vector(0 downto 0); -- .mem_cke
|
||||||
|
mem_cs_n : out std_logic_vector(0 downto 0); -- .mem_cs_n
|
||||||
|
mem_dm : out std_logic_vector(1 downto 0); -- .mem_dm
|
||||||
|
mem_ras_n : out std_logic_vector(0 downto 0); -- .mem_ras_n
|
||||||
|
mem_cas_n : out std_logic_vector(0 downto 0); -- .mem_cas_n
|
||||||
|
mem_we_n : out std_logic_vector(0 downto 0); -- .mem_we_n
|
||||||
|
mem_reset_n : out std_logic; -- .mem_reset_n
|
||||||
|
mem_dq : inout std_logic_vector(15 downto 0) := (others => '0'); -- .mem_dq
|
||||||
|
mem_dqs : inout std_logic_vector(1 downto 0) := (others => '0'); -- .mem_dqs
|
||||||
|
mem_dqs_n : inout std_logic_vector(1 downto 0) := (others => '0'); -- .mem_dqs_n
|
||||||
|
mem_odt : out std_logic_vector(0 downto 0); -- .mem_odt
|
||||||
|
oct_rzqin : in std_logic -- oct.rzqin
|
||||||
|
);
|
||||||
|
|
||||||
|
end entity top;
|
||||||
|
|
||||||
|
architecture RTL of top is
|
||||||
|
constant debug_baud : natural := 460800;
|
||||||
|
constant F_CPU : natural := 50000000;
|
||||||
|
|
||||||
|
-- WB config
|
||||||
|
constant masters : natural := 3;
|
||||||
|
constant slaves : natural := 2;
|
||||||
|
constant INTERCON_ID_SRAM : natural := 0;
|
||||||
|
constant INTERCON_ID_DDR3 : natural := 1;
|
||||||
|
constant INTERCON_ID_GPIO : natural := 2;
|
||||||
|
constant INTERCON_ID_UART : natural := 3;
|
||||||
|
constant INTERCON_ID_NS16550 : natural := 4;
|
||||||
|
|
||||||
|
constant in_simulation : boolean := false
|
||||||
|
--pragma synthesis_off
|
||||||
|
or true
|
||||||
|
--pragma synthesis_on
|
||||||
|
;
|
||||||
|
constant in_synthesis : boolean := not in_simulation;
|
||||||
|
|
||||||
|
signal clk : std_logic;
|
||||||
|
signal rst : std_logic;
|
||||||
|
signal interrupt : std_logic_vector(32 - 1 downto 0);
|
||||||
|
signal intercon_slave_i : wishbone_v3_slave_in_vector(slaves - 1 downto 0);
|
||||||
|
signal intercon_slave_o : wishbone_v3_slave_out_vector(slaves - 1 downto 0);
|
||||||
|
signal intercon_master_i : wishbone_v3_master_in_vector(masters - 1 downto 0);
|
||||||
|
signal intercon_master_o : wishbone_v3_master_out_vector(masters - 1 downto 0);
|
||||||
|
|
||||||
|
signal pll_locked : std_logic;
|
||||||
|
signal rst_ddr3_n : std_logic;
|
||||||
|
signal debug_o : debug_interface_o;
|
||||||
|
signal debug_i : debug_interface_i;
|
||||||
|
signal traceport_exec_valid_o : std_logic;
|
||||||
|
signal traceport_exec_pc_o : std_logic_vector(31 downto 0);
|
||||||
|
signal traceport_exec_insn_o : std_logic_vector(OR1K_INSN_WIDTH - 1 downto 0);
|
||||||
|
signal traceport_exec_wbdata_o : std_logic_vector(OPTION_OPERAND_WIDTH - 1 downto 0);
|
||||||
|
signal traceport_exec_wbreg_o : std_logic_vector(OPTION_RF_ADDR_WIDTH - 1 downto 0);
|
||||||
|
signal traceport_exec_wben_o : std_logic;
|
||||||
|
signal mor1kx_rst : std_logic;
|
||||||
|
signal jinn_data_i : std_logic_vector(7 downto 0);
|
||||||
|
signal jinn_data_available : std_logic;
|
||||||
|
signal jinn_data_o : std_logic_vector(7 downto 0);
|
||||||
|
signal jinn_data_valid_o : std_logic;
|
||||||
|
signal jinn_uart_busy_i : std_logic;
|
||||||
|
|
||||||
|
signal avl_ready_0 : std_logic;
|
||||||
|
signal avl_burstbegin_0 : std_logic;
|
||||||
|
signal avl_addr_0 : std_logic_vector(24 downto 0);
|
||||||
|
signal avl_rdata_valid_0 : std_logic;
|
||||||
|
signal avl_rdata_0 : std_logic_vector(31 downto 0);
|
||||||
|
signal avl_wdata_0 : std_logic_vector(31 downto 0);
|
||||||
|
signal avl_be_0 : std_logic_vector(3 downto 0);
|
||||||
|
signal avl_read_req_0 : std_logic;
|
||||||
|
signal avl_write_req_0 : std_logic;
|
||||||
|
signal avl_size_0 : std_logic_vector(2 downto 0);
|
||||||
|
|
||||||
|
signal local_init_done : std_logic; -- status.local_init_done
|
||||||
|
signal local_cal_success : std_logic; -- .local_cal_success
|
||||||
|
signal local_cal_fail : std_logic; -- .local_cal_fail
|
||||||
|
|
||||||
|
signal avl_reqEn : std_logic;
|
||||||
|
signal writeAck : std_logic;
|
||||||
|
signal readAck : std_logic;
|
||||||
|
begin
|
||||||
|
debug_i.addr <= (others => '0');
|
||||||
|
debug_i.dat <= (others => '0');
|
||||||
|
debug_i.stb <= '1';
|
||||||
|
debug_i.we <= '0';
|
||||||
|
|
||||||
|
-- System controller
|
||||||
|
resetSync : process(clk, rst_hw) is
|
||||||
|
begin
|
||||||
|
if rst_hw = '0' then -- low active
|
||||||
|
rst <= '1';
|
||||||
|
rst_ddr3_n <= '0';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if pll_locked = '1' then
|
||||||
|
rst_ddr3_n <= '1'; -- Start DDR3 Controller
|
||||||
|
if local_init_done = '1' and local_cal_success = '1' then
|
||||||
|
rst <= '0'; -- Start system!
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process resetSync;
|
||||||
|
|
||||||
|
-- Clock management
|
||||||
|
clk <= clk_hw;
|
||||||
|
pll_locked <= '1';
|
||||||
|
|
||||||
|
-- SRAM
|
||||||
|
sram_wb_inst : entity work.sram_wb
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
wb_in => intercon_slave_i(INTERCON_ID_SRAM),
|
||||||
|
wb_out => intercon_slave_o(INTERCON_ID_SRAM)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CPU
|
||||||
|
interrupt <= (others => '0');
|
||||||
|
mor1kx_vhdl_inst : entity ip.mor1kx_vhdl
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => mor1kx_rst,
|
||||||
|
data_o => intercon_master_o(1),
|
||||||
|
data_i => intercon_master_i(1),
|
||||||
|
inst_o => intercon_master_o(0),
|
||||||
|
inst_i => intercon_master_i(0),
|
||||||
|
irq_i => interrupt,
|
||||||
|
debug_o => debug_o,
|
||||||
|
debug_i => debug_i,
|
||||||
|
traceport_exec_valid_o => traceport_exec_valid_o,
|
||||||
|
traceport_exec_pc_o => traceport_exec_pc_o,
|
||||||
|
traceport_exec_insn_o => traceport_exec_insn_o,
|
||||||
|
traceport_exec_wbdata_o => traceport_exec_wbdata_o,
|
||||||
|
traceport_exec_wbreg_o => traceport_exec_wbreg_o,
|
||||||
|
traceport_exec_wben_o => traceport_exec_wben_o
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Debug interface
|
||||||
|
jinn_inst : entity work.jinn
|
||||||
|
port map(
|
||||||
|
clk_i => clk,
|
||||||
|
rst_i => rst,
|
||||||
|
master_i => intercon_master_i(2),
|
||||||
|
master_o => intercon_master_o(2),
|
||||||
|
cpu_stall => debug_i.stall,
|
||||||
|
cpu_reset => mor1kx_rst,
|
||||||
|
data_i => jinn_data_i,
|
||||||
|
data_available => jinn_data_available,
|
||||||
|
data_o => jinn_data_o,
|
||||||
|
data_valid_o => jinn_data_valid_o,
|
||||||
|
output_busy_i => jinn_uart_busy_i
|
||||||
|
);
|
||||||
|
|
||||||
|
uart_rx_inst : entity work.uart_rx
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
data => jinn_data_i,
|
||||||
|
byte_ready => jinn_data_available,
|
||||||
|
error => open,
|
||||||
|
ckDiv => std_logic_vector(to_unsigned(F_CPU / debug_baud - 1, 16)),
|
||||||
|
parityEnable => '0',
|
||||||
|
parityOdd => '0',
|
||||||
|
twoStopBits => '0',
|
||||||
|
rx => jinn_uart_rx
|
||||||
|
);
|
||||||
|
|
||||||
|
uart_tx_inst : entity work.uart_tx
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
data => jinn_data_o,
|
||||||
|
byte_ready => jinn_data_valid_o,
|
||||||
|
busy => jinn_uart_busy_i,
|
||||||
|
ckDiv => std_logic_vector(to_unsigned(F_CPU / debug_baud - 1, 16)),
|
||||||
|
parityEnable => '0',
|
||||||
|
parityOdd => '0',
|
||||||
|
twoStopBits => '0',
|
||||||
|
tx => jinn_uart_tx
|
||||||
|
);
|
||||||
|
|
||||||
|
-- DDR3 RAM
|
||||||
|
ddr3_inst : entity ddr3.ddr3
|
||||||
|
port map(
|
||||||
|
pll_ref_clk => clk,
|
||||||
|
global_reset_n => rst_hw,
|
||||||
|
soft_reset_n => '1',
|
||||||
|
afi_clk => open,
|
||||||
|
afi_half_clk => open,
|
||||||
|
afi_reset_n => open,
|
||||||
|
afi_reset_export_n => open,
|
||||||
|
mem_a => mem_a,
|
||||||
|
mem_ba => mem_ba,
|
||||||
|
mem_ck => mem_ck,
|
||||||
|
mem_ck_n => mem_ck_n,
|
||||||
|
mem_cke => mem_cke,
|
||||||
|
mem_cs_n => mem_cs_n,
|
||||||
|
mem_dm => mem_dm,
|
||||||
|
mem_ras_n => mem_ras_n,
|
||||||
|
mem_cas_n => mem_cas_n,
|
||||||
|
mem_we_n => mem_we_n,
|
||||||
|
mem_reset_n => mem_reset_n,
|
||||||
|
mem_dq => mem_dq,
|
||||||
|
mem_dqs => mem_dqs,
|
||||||
|
mem_dqs_n => mem_dqs_n,
|
||||||
|
mem_odt => mem_odt,
|
||||||
|
avl_ready_0 => avl_ready_0,
|
||||||
|
avl_burstbegin_0 => avl_burstbegin_0,
|
||||||
|
avl_addr_0 => avl_addr_0,
|
||||||
|
avl_rdata_valid_0 => avl_rdata_valid_0,
|
||||||
|
avl_rdata_0 => avl_rdata_0,
|
||||||
|
avl_wdata_0 => avl_wdata_0,
|
||||||
|
avl_be_0 => avl_be_0,
|
||||||
|
avl_read_req_0 => avl_read_req_0,
|
||||||
|
avl_write_req_0 => avl_write_req_0,
|
||||||
|
avl_size_0 => avl_size_0,
|
||||||
|
mp_cmd_clk_0_clk => clk,
|
||||||
|
mp_cmd_reset_n_0_reset_n => rst_hw,
|
||||||
|
mp_rfifo_clk_0_clk => clk,
|
||||||
|
mp_rfifo_reset_n_0_reset_n => rst_hw,
|
||||||
|
mp_wfifo_clk_0_clk => clk,
|
||||||
|
mp_wfifo_reset_n_0_reset_n => rst_hw,
|
||||||
|
local_init_done => local_init_done,
|
||||||
|
local_cal_success => local_cal_success,
|
||||||
|
local_cal_fail => local_cal_fail,
|
||||||
|
oct_rzqin => oct_rzqin,
|
||||||
|
pll_mem_clk => open,
|
||||||
|
pll_write_clk => open,
|
||||||
|
pll_locked => open,
|
||||||
|
pll_write_clk_pre_phy_clk => open,
|
||||||
|
pll_addr_cmd_clk => open,
|
||||||
|
pll_avl_clk => open,
|
||||||
|
pll_config_clk => open,
|
||||||
|
pll_mem_phy_clk => open,
|
||||||
|
afi_phy_clk => open,
|
||||||
|
pll_avl_phy_clk => open,
|
||||||
|
csr_clk => clk,
|
||||||
|
csr_reset_n => rst_hw
|
||||||
|
);
|
||||||
|
|
||||||
|
avl_addr_0 <= intercon_slave_i(INTERCON_ID_DDR3).ADR(26 downto 2); -- & "00";
|
||||||
|
avl_be_0 <= intercon_slave_i(INTERCON_ID_DDR3).SEL;
|
||||||
|
avl_burstbegin_0 <= '0';
|
||||||
|
|
||||||
|
avl_wdata_0 <= intercon_slave_i(INTERCON_ID_DDR3).DAT;
|
||||||
|
avl_read_req_0 <= (intercon_slave_i(INTERCON_ID_DDR3).STB and (not intercon_slave_i(INTERCON_ID_DDR3).WE)) and avl_reqEn;
|
||||||
|
avl_write_req_0 <= (intercon_slave_i(INTERCON_ID_DDR3).STB and intercon_slave_i(INTERCON_ID_DDR3).WE) and avl_reqEn;
|
||||||
|
avl_size_0 <= "001";
|
||||||
|
|
||||||
|
intercon_slave_o(INTERCON_ID_DDR3).DAT <= avl_rdata_0;
|
||||||
|
intercon_slave_o(INTERCON_ID_DDR3).ERR <= '0';
|
||||||
|
intercon_slave_o(INTERCON_ID_DDR3).RTY <= '0';
|
||||||
|
intercon_slave_o(INTERCON_ID_DDR3).ACK <= (readAck or writeAck) and intercon_slave_i(INTERCON_ID_DDR3).STB;
|
||||||
|
|
||||||
|
readAck <= avl_rdata_valid_0; --(avl_rdata_valid_0 and not intercon_slave_i(INTERCON_ID_SRAM).WE);
|
||||||
|
writeAck <= (intercon_slave_i(INTERCON_ID_DDR3).WE and avl_ready_0);
|
||||||
|
|
||||||
|
wb2avl : process(clk, rst) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
avl_reqEn <= '1';
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
if intercon_slave_i(INTERCON_ID_DDR3).STB = '1' then
|
||||||
|
avl_reqEn <= '0';
|
||||||
|
else
|
||||||
|
avl_reqEn <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process wb2avl;
|
||||||
|
|
||||||
|
-- Intercon
|
||||||
|
crossbar_inst : entity ip.crossbar
|
||||||
|
generic map(
|
||||||
|
masters => masters,
|
||||||
|
slaves => slaves,
|
||||||
|
async => true
|
||||||
|
)
|
||||||
|
port map(
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
slave_i => intercon_master_o,
|
||||||
|
slave_o => intercon_master_i,
|
||||||
|
master_i => intercon_slave_o,
|
||||||
|
master_o => intercon_slave_i,
|
||||||
|
address => (0 => x"00000000", -- SRAM
|
||||||
|
1 => x"80000000"
|
||||||
|
),
|
||||||
|
mask => (0 => x"ffff0000",
|
||||||
|
1 => x"f0000000"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
end architecture RTL;
|
BIN
devicemodels/atmel_flash_user_guide_with_rapids.doc
Normal file
BIN
devicemodels/atmel_flash_user_guide_with_rapids.doc
Normal file
Binary file not shown.
3780
devicemodels/dataflash2.1.vhd
Normal file
3780
devicemodels/dataflash2.1.vhd
Normal file
File diff suppressed because it is too large
Load Diff
4096
devicemodels/memory.txt
Normal file
4096
devicemodels/memory.txt
Normal file
File diff suppressed because it is too large
Load Diff
105
devicemodels/readme.txt
Normal file
105
devicemodels/readme.txt
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
please do for modelsim
|
||||||
|
|
||||||
|
vlib work
|
||||||
|
vmap work work
|
||||||
|
|
||||||
|
|
||||||
|
compiledataflashDF.do
|
||||||
|
|
||||||
|
for testing opcodes
|
||||||
|
|
||||||
|
Buffer 1 write
|
||||||
|
Buffer 2 write
|
||||||
|
Buffer 1 to main memory page program with built in Erase
|
||||||
|
Buffer 2 to main memory page program with built in Erase
|
||||||
|
main memory page to buffer 2 transfer
|
||||||
|
main memory page to buffer 1 transfer
|
||||||
|
buffer 1 read
|
||||||
|
buffer 2 read
|
||||||
|
|
||||||
|
*************************************************8
|
||||||
|
compiledataflashCE.do
|
||||||
|
|
||||||
|
|
||||||
|
for testing opcodes
|
||||||
|
|
||||||
|
chip erase
|
||||||
|
|
||||||
|
*****************************************************
|
||||||
|
compiledataflashE.do
|
||||||
|
|
||||||
|
|
||||||
|
for testing opcodes
|
||||||
|
|
||||||
|
Page erase
|
||||||
|
Block Erase
|
||||||
|
sector erase
|
||||||
|
|
||||||
|
************************************************
|
||||||
|
|
||||||
|
compiledataflashRR.do
|
||||||
|
|
||||||
|
|
||||||
|
for testing opcodes
|
||||||
|
|
||||||
|
Enable sector protection
|
||||||
|
Disable sector Protection
|
||||||
|
Erase sector protection register
|
||||||
|
Program sector lock down Register
|
||||||
|
Program security register
|
||||||
|
Program sector protection register
|
||||||
|
Status Register Read
|
||||||
|
Manufacturing ID Read
|
||||||
|
Deep power down
|
||||||
|
Resume from deep power down
|
||||||
|
Read sector protection register
|
||||||
|
Read security register
|
||||||
|
Read sector lock down register
|
||||||
|
*************************************************
|
||||||
|
|
||||||
|
compiledataflashMEM.do
|
||||||
|
|
||||||
|
|
||||||
|
for testing opcodes
|
||||||
|
|
||||||
|
main memory page program through buffer 1
|
||||||
|
Auto page rewrite through buffer 1
|
||||||
|
main memory page read
|
||||||
|
main memory continuous array read
|
||||||
|
|
||||||
|
***************************************************
|
||||||
|
|
||||||
|
compiledataflashBPS.do
|
||||||
|
|
||||||
|
|
||||||
|
for testing opcodes
|
||||||
|
|
||||||
|
binary page setup
|
||||||
|
buffer 2 write
|
||||||
|
buffer 2 to main memory page program with out built in erase.
|
||||||
|
main memory page compare with buffer 1
|
||||||
|
main memory to buffer 1 transfer
|
||||||
|
|
||||||
|
|
||||||
|
********************************************************
|
||||||
|
|
||||||
|
For all simulatcases you have simulate only one test becnh top
|
||||||
|
|
||||||
|
vsim work.tb_Dataflashtestbench
|
||||||
|
|
||||||
|
run -all
|
||||||
|
|
||||||
|
|
||||||
|
or at modelsim> prompt
|
||||||
|
|
||||||
|
do simcommon.do
|
||||||
|
|
||||||
|
run -all
|
||||||
|
|
||||||
|
if needed add wave -r * to view all waveforms
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
530
ip/altera/ddr3.bsf
Normal file
530
ip/altera/ddr3.bsf
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
/*
|
||||||
|
WARNING: Do NOT edit the input and output ports in this file in a text
|
||||||
|
editor if you plan to continue editing the block that represents it in
|
||||||
|
the Block Editor! File corruption is VERY likely to occur.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
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 Prime 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.
|
||||||
|
*/
|
||||||
|
(header "symbol" (version "1.1"))
|
||||||
|
(symbol
|
||||||
|
(rect 0 0 512 984)
|
||||||
|
(text "ddr3" (rect 244 -1 261 11)(font "Arial" (font_size 10)))
|
||||||
|
(text "inst" (rect 8 968 20 980)(font "Arial" ))
|
||||||
|
(port
|
||||||
|
(pt 0 72)
|
||||||
|
(input)
|
||||||
|
(text "pll_ref_clk" (rect 0 0 41 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_ref_clk" (rect 4 61 70 72)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 72)(pt 160 72)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 112)
|
||||||
|
(input)
|
||||||
|
(text "global_reset_n" (rect 0 0 57 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "global_reset_n" (rect 4 101 88 112)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 112)(pt 160 112)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 152)
|
||||||
|
(input)
|
||||||
|
(text "soft_reset_n" (rect 0 0 51 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "soft_reset_n" (rect 4 141 76 152)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 152)(pt 160 152)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 208)
|
||||||
|
(input)
|
||||||
|
(text "avl_burstbegin_0" (rect 0 0 68 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_burstbegin_0" (rect 4 197 100 208)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 208)(pt 160 208)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 224)
|
||||||
|
(input)
|
||||||
|
(text "avl_addr_0[24..0]" (rect 0 0 71 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_addr_0[24..0]" (rect 4 213 106 224)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 224)(pt 160 224)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 272)
|
||||||
|
(input)
|
||||||
|
(text "avl_wdata_0[31..0]" (rect 0 0 74 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_wdata_0[31..0]" (rect 4 261 112 272)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 272)(pt 160 272)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 288)
|
||||||
|
(input)
|
||||||
|
(text "avl_be_0[3..0]" (rect 0 0 57 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_be_0[3..0]" (rect 4 277 88 288)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 288)(pt 160 288)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 304)
|
||||||
|
(input)
|
||||||
|
(text "avl_read_req_0" (rect 0 0 64 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_read_req_0" (rect 4 293 88 304)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 304)(pt 160 304)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 320)
|
||||||
|
(input)
|
||||||
|
(text "avl_write_req_0" (rect 0 0 64 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_write_req_0" (rect 4 309 94 320)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 320)(pt 160 320)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 336)
|
||||||
|
(input)
|
||||||
|
(text "avl_size_0[2..0]" (rect 0 0 62 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_size_0[2..0]" (rect 4 325 100 336)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 336)(pt 160 336)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 376)
|
||||||
|
(input)
|
||||||
|
(text "mp_cmd_clk_0_clk" (rect 0 0 80 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mp_cmd_clk_0_clk" (rect 4 365 100 376)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 376)(pt 160 376)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 416)
|
||||||
|
(input)
|
||||||
|
(text "mp_cmd_reset_n_0_reset_n" (rect 0 0 120 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mp_cmd_reset_n_0_reset_n" (rect 4 405 148 416)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 416)(pt 160 416)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 456)
|
||||||
|
(input)
|
||||||
|
(text "mp_rfifo_clk_0_clk" (rect 0 0 79 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mp_rfifo_clk_0_clk" (rect 4 445 112 456)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 456)(pt 160 456)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 496)
|
||||||
|
(input)
|
||||||
|
(text "mp_rfifo_reset_n_0_reset_n" (rect 0 0 119 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mp_rfifo_reset_n_0_reset_n" (rect 4 485 160 496)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 496)(pt 160 496)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 536)
|
||||||
|
(input)
|
||||||
|
(text "mp_wfifo_clk_0_clk" (rect 0 0 81 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mp_wfifo_clk_0_clk" (rect 4 525 112 536)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 536)(pt 160 536)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 576)
|
||||||
|
(input)
|
||||||
|
(text "mp_wfifo_reset_n_0_reset_n" (rect 0 0 121 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mp_wfifo_reset_n_0_reset_n" (rect 4 565 160 576)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 576)(pt 160 576)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 616)
|
||||||
|
(input)
|
||||||
|
(text "csr_clk" (rect 0 0 29 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "csr_clk" (rect 4 605 46 616)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 616)(pt 160 616)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 656)
|
||||||
|
(input)
|
||||||
|
(text "csr_reset_n" (rect 0 0 49 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "csr_reset_n" (rect 4 645 70 656)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 656)(pt 160 656)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 768)
|
||||||
|
(input)
|
||||||
|
(text "oct_rzqin" (rect 0 0 35 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "oct_rzqin" (rect 4 757 58 768)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 768)(pt 160 768)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 72)
|
||||||
|
(output)
|
||||||
|
(text "afi_clk" (rect 0 0 25 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "afi_clk" (rect 477 61 519 72)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 72)(pt 352 72)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 112)
|
||||||
|
(output)
|
||||||
|
(text "afi_half_clk" (rect 0 0 46 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "afi_half_clk" (rect 451 101 523 112)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 112)(pt 352 112)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 152)
|
||||||
|
(output)
|
||||||
|
(text "afi_reset_n" (rect 0 0 46 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "afi_reset_n" (rect 452 141 518 152)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 152)(pt 352 152)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 192)
|
||||||
|
(output)
|
||||||
|
(text "afi_reset_export_n" (rect 0 0 76 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "afi_reset_export_n" (rect 414 181 522 192)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 192)(pt 352 192)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 232)
|
||||||
|
(output)
|
||||||
|
(text "mem_a[12..0]" (rect 0 0 55 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_a[12..0]" (rect 447 221 519 232)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 232)(pt 352 232)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 248)
|
||||||
|
(output)
|
||||||
|
(text "mem_ba[2..0]" (rect 0 0 56 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_ba[2..0]" (rect 445 237 517 248)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 248)(pt 352 248)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 264)
|
||||||
|
(output)
|
||||||
|
(text "mem_ck" (rect 0 0 36 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_ck" (rect 470 253 506 264)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 264)(pt 352 264)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 280)
|
||||||
|
(output)
|
||||||
|
(text "mem_ck_n" (rect 0 0 47 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_ck_n" (rect 457 269 505 280)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 280)(pt 352 280)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 296)
|
||||||
|
(output)
|
||||||
|
(text "mem_cke" (rect 0 0 41 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_cke" (rect 464 285 506 296)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 296)(pt 352 296)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 312)
|
||||||
|
(output)
|
||||||
|
(text "mem_cs_n" (rect 0 0 47 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_cs_n" (rect 456 301 504 312)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 312)(pt 352 312)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 328)
|
||||||
|
(output)
|
||||||
|
(text "mem_dm[1..0]" (rect 0 0 59 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_dm[1..0]" (rect 445 317 517 328)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 328)(pt 352 328)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 344)
|
||||||
|
(output)
|
||||||
|
(text "mem_ras_n" (rect 0 0 50 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_ras_n" (rect 452 333 506 344)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 344)(pt 352 344)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 360)
|
||||||
|
(output)
|
||||||
|
(text "mem_cas_n" (rect 0 0 51 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_cas_n" (rect 450 349 504 360)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 360)(pt 352 360)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 376)
|
||||||
|
(output)
|
||||||
|
(text "mem_we_n" (rect 0 0 48 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_we_n" (rect 452 365 500 376)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 376)(pt 352 376)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 392)
|
||||||
|
(output)
|
||||||
|
(text "mem_reset_n" (rect 0 0 57 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_reset_n" (rect 443 381 509 392)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 392)(pt 352 392)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 456)
|
||||||
|
(output)
|
||||||
|
(text "mem_odt" (rect 0 0 38 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_odt" (rect 466 445 508 456)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 456)(pt 352 456)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 192)
|
||||||
|
(output)
|
||||||
|
(text "avl_ready_0" (rect 0 0 51 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_ready_0" (rect 4 181 70 192)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 192)(pt 160 192)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 240)
|
||||||
|
(output)
|
||||||
|
(text "avl_rdata_valid_0" (rect 0 0 71 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_rdata_valid_0" (rect 4 229 106 240)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 240)(pt 160 240)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 256)
|
||||||
|
(output)
|
||||||
|
(text "avl_rdata_0[31..0]" (rect 0 0 71 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "avl_rdata_0[31..0]" (rect 4 245 112 256)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 256)(pt 160 256)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 696)
|
||||||
|
(output)
|
||||||
|
(text "local_init_done" (rect 0 0 56 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "local_init_done" (rect 4 685 94 696)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 696)(pt 160 696)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 712)
|
||||||
|
(output)
|
||||||
|
(text "local_cal_success" (rect 0 0 71 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "local_cal_success" (rect 4 701 106 712)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 712)(pt 160 712)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 728)
|
||||||
|
(output)
|
||||||
|
(text "local_cal_fail" (rect 0 0 49 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "local_cal_fail" (rect 4 717 88 728)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 728)(pt 160 728)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 808)
|
||||||
|
(output)
|
||||||
|
(text "pll_mem_clk" (rect 0 0 50 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_mem_clk" (rect 4 797 70 808)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 808)(pt 160 808)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 824)
|
||||||
|
(output)
|
||||||
|
(text "pll_write_clk" (rect 0 0 47 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_write_clk" (rect 4 813 82 824)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 824)(pt 160 824)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 840)
|
||||||
|
(output)
|
||||||
|
(text "pll_locked" (rect 0 0 37 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_locked" (rect 4 829 64 840)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 840)(pt 160 840)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 856)
|
||||||
|
(output)
|
||||||
|
(text "pll_write_clk_pre_phy_clk" (rect 0 0 103 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_write_clk_pre_phy_clk" (rect 4 845 154 856)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 856)(pt 160 856)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 872)
|
||||||
|
(output)
|
||||||
|
(text "pll_addr_cmd_clk" (rect 0 0 70 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_addr_cmd_clk" (rect 4 861 100 872)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 872)(pt 160 872)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 888)
|
||||||
|
(output)
|
||||||
|
(text "pll_avl_clk" (rect 0 0 41 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_avl_clk" (rect 4 877 70 888)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 888)(pt 160 888)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 904)
|
||||||
|
(output)
|
||||||
|
(text "pll_config_clk" (rect 0 0 53 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_config_clk" (rect 4 893 88 904)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 904)(pt 160 904)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 920)
|
||||||
|
(output)
|
||||||
|
(text "pll_mem_phy_clk" (rect 0 0 71 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_mem_phy_clk" (rect 4 909 94 920)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 920)(pt 160 920)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 936)
|
||||||
|
(output)
|
||||||
|
(text "afi_phy_clk" (rect 0 0 47 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "afi_phy_clk" (rect 4 925 70 936)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 936)(pt 160 936)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 0 952)
|
||||||
|
(output)
|
||||||
|
(text "pll_avl_phy_clk" (rect 0 0 62 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "pll_avl_phy_clk" (rect 4 941 94 952)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 0 952)(pt 160 952)(line_width 1))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 408)
|
||||||
|
(bidir)
|
||||||
|
(text "mem_dq[15..0]" (rect 0 0 60 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_dq[15..0]" (rect 441 397 519 408)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 408)(pt 352 408)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 424)
|
||||||
|
(bidir)
|
||||||
|
(text "mem_dqs[1..0]" (rect 0 0 60 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_dqs[1..0]" (rect 441 413 519 424)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 424)(pt 352 424)(line_width 3))
|
||||||
|
)
|
||||||
|
(port
|
||||||
|
(pt 512 440)
|
||||||
|
(bidir)
|
||||||
|
(text "mem_dqs_n[1..0]" (rect 0 0 70 12)(font "Arial" (font_size 8)))
|
||||||
|
(text "mem_dqs_n[1..0]" (rect 428 429 518 440)(font "Arial" (font_size 8)))
|
||||||
|
(line (pt 512 440)(pt 352 440)(line_width 3))
|
||||||
|
)
|
||||||
|
(drawing
|
||||||
|
(text "pll_ref_clk" (rect 99 43 264 99)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "clk" (rect 165 67 348 144)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "global_reset" (rect 89 83 250 179)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 165 107 372 224)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "soft_reset" (rect 100 123 260 259)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 165 147 372 304)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "afi_clk" (rect 353 43 748 99)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "clk" (rect 337 67 692 144)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "afi_half_clk" (rect 353 83 778 179)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "clk" (rect 337 107 692 224)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "afi_reset" (rect 353 123 760 259)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 316 147 674 304)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "afi_reset_export" (rect 353 163 802 339)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 316 187 674 384)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "memory" (rect 353 203 742 419)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "mem_a" (rect 317 227 664 464)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_ba" (rect 312 243 660 496)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_ck" (rect 312 259 660 528)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_ck_n" (rect 301 275 650 560)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_cke" (rect 307 291 656 592)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_cs_n" (rect 301 307 650 624)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_dm" (rect 309 323 654 656)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_ras_n" (rect 297 339 648 688)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_cas_n" (rect 296 355 646 720)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_we_n" (rect 300 371 648 752)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_reset_n" (rect 289 387 644 784)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_dq" (rect 312 403 660 816)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_dqs" (rect 307 419 656 848)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_dqs_n" (rect 296 435 646 880)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mem_odt" (rect 309 451 660 912)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "avl_0" (rect 130 163 290 339)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "waitrequest_n" (rect 165 187 408 384)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "beginbursttransfer" (rect 165 203 438 416)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "address" (rect 165 219 372 448)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "readdatavalid" (rect 165 235 408 480)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "readdata" (rect 165 251 378 512)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "writedata" (rect 165 267 384 544)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "byteenable" (rect 165 283 390 576)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "read" (rect 165 299 354 608)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "write" (rect 165 315 360 640)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "burstcount" (rect 165 331 390 672)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mp_cmd_clk_0" (rect 72 347 216 707)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "clk" (rect 165 371 348 752)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mp_cmd_reset_n_0" (rect 43 387 182 787)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 165 411 372 832)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mp_rfifo_clk_0" (rect 71 427 226 867)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "clk" (rect 165 451 348 912)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mp_rfifo_reset_n_0" (rect 42 467 192 947)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 165 491 372 992)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mp_wfifo_clk_0" (rect 66 507 216 1027)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "clk" (rect 165 531 348 1072)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "mp_wfifo_reset_n_0" (rect 37 547 182 1107)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 165 571 372 1152)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "csr_clk" (rect 119 587 280 1187)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "clk" (rect 165 611 348 1232)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "csr_reset_n" (rect 90 627 246 1267)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "reset_n" (rect 165 651 372 1312)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "status" (rect 125 667 286 1347)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "local_init_done" (rect 165 691 420 1392)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "local_cal_success" (rect 165 707 432 1424)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "local_cal_fail" (rect 165 723 414 1456)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "oct" (rect 144 739 306 1491)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "rzqin" (rect 165 763 360 1536)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_sharing" (rect 97 779 260 1571)(font "Arial" (color 128 0 0)(font_size 9)))
|
||||||
|
(text "pll_mem_clk" (rect 165 803 396 1616)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_write_clk" (rect 165 819 408 1648)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_locked" (rect 165 835 390 1680)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_write_clk_pre_phy_clk" (rect 165 851 480 1712)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_addr_cmd_clk" (rect 165 867 426 1744)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_avl_clk" (rect 165 883 396 1776)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_config_clk" (rect 165 899 414 1808)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_mem_phy_clk" (rect 165 915 420 1840)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "afi_phy_clk" (rect 165 931 396 1872)(font "Arial" (color 0 0 0)))
|
||||||
|
(text "pll_avl_phy_clk" (rect 165 947 420 1904)(font "Arial" (color 0 0 0)))
|
||||||
|
(text " altera_mem_if_ddr3_emif " (rect 396 968 942 1946)(font "Arial" ))
|
||||||
|
(line (pt 160 32)(pt 352 32)(line_width 1))
|
||||||
|
(line (pt 352 32)(pt 352 968)(line_width 1))
|
||||||
|
(line (pt 160 968)(pt 352 968)(line_width 1))
|
||||||
|
(line (pt 160 32)(pt 160 968)(line_width 1))
|
||||||
|
(line (pt 161 52)(pt 161 76)(line_width 1))
|
||||||
|
(line (pt 162 52)(pt 162 76)(line_width 1))
|
||||||
|
(line (pt 161 92)(pt 161 116)(line_width 1))
|
||||||
|
(line (pt 162 92)(pt 162 116)(line_width 1))
|
||||||
|
(line (pt 161 132)(pt 161 156)(line_width 1))
|
||||||
|
(line (pt 162 132)(pt 162 156)(line_width 1))
|
||||||
|
(line (pt 351 52)(pt 351 76)(line_width 1))
|
||||||
|
(line (pt 350 52)(pt 350 76)(line_width 1))
|
||||||
|
(line (pt 351 92)(pt 351 116)(line_width 1))
|
||||||
|
(line (pt 350 92)(pt 350 116)(line_width 1))
|
||||||
|
(line (pt 351 132)(pt 351 156)(line_width 1))
|
||||||
|
(line (pt 350 132)(pt 350 156)(line_width 1))
|
||||||
|
(line (pt 351 172)(pt 351 196)(line_width 1))
|
||||||
|
(line (pt 350 172)(pt 350 196)(line_width 1))
|
||||||
|
(line (pt 351 212)(pt 351 460)(line_width 1))
|
||||||
|
(line (pt 350 212)(pt 350 460)(line_width 1))
|
||||||
|
(line (pt 161 172)(pt 161 340)(line_width 1))
|
||||||
|
(line (pt 162 172)(pt 162 340)(line_width 1))
|
||||||
|
(line (pt 161 356)(pt 161 380)(line_width 1))
|
||||||
|
(line (pt 162 356)(pt 162 380)(line_width 1))
|
||||||
|
(line (pt 161 396)(pt 161 420)(line_width 1))
|
||||||
|
(line (pt 162 396)(pt 162 420)(line_width 1))
|
||||||
|
(line (pt 161 436)(pt 161 460)(line_width 1))
|
||||||
|
(line (pt 162 436)(pt 162 460)(line_width 1))
|
||||||
|
(line (pt 161 476)(pt 161 500)(line_width 1))
|
||||||
|
(line (pt 162 476)(pt 162 500)(line_width 1))
|
||||||
|
(line (pt 161 516)(pt 161 540)(line_width 1))
|
||||||
|
(line (pt 162 516)(pt 162 540)(line_width 1))
|
||||||
|
(line (pt 161 556)(pt 161 580)(line_width 1))
|
||||||
|
(line (pt 162 556)(pt 162 580)(line_width 1))
|
||||||
|
(line (pt 161 596)(pt 161 620)(line_width 1))
|
||||||
|
(line (pt 162 596)(pt 162 620)(line_width 1))
|
||||||
|
(line (pt 161 636)(pt 161 660)(line_width 1))
|
||||||
|
(line (pt 162 636)(pt 162 660)(line_width 1))
|
||||||
|
(line (pt 161 676)(pt 161 732)(line_width 1))
|
||||||
|
(line (pt 162 676)(pt 162 732)(line_width 1))
|
||||||
|
(line (pt 161 748)(pt 161 772)(line_width 1))
|
||||||
|
(line (pt 162 748)(pt 162 772)(line_width 1))
|
||||||
|
(line (pt 161 788)(pt 161 956)(line_width 1))
|
||||||
|
(line (pt 162 788)(pt 162 956)(line_width 1))
|
||||||
|
(line (pt 0 0)(pt 512 0)(line_width 1))
|
||||||
|
(line (pt 512 0)(pt 512 984)(line_width 1))
|
||||||
|
(line (pt 0 984)(pt 512 984)(line_width 1))
|
||||||
|
(line (pt 0 0)(pt 0 984)(line_width 1))
|
||||||
|
)
|
||||||
|
)
|
59
ip/altera/ddr3.cmp
Normal file
59
ip/altera/ddr3.cmp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
component ddr3 is
|
||||||
|
port (
|
||||||
|
pll_ref_clk : in std_logic := 'X'; -- clk
|
||||||
|
global_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
soft_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
afi_clk : out std_logic; -- clk
|
||||||
|
afi_half_clk : out std_logic; -- clk
|
||||||
|
afi_reset_n : out std_logic; -- reset_n
|
||||||
|
afi_reset_export_n : out std_logic; -- reset_n
|
||||||
|
mem_a : out std_logic_vector(12 downto 0); -- mem_a
|
||||||
|
mem_ba : out std_logic_vector(2 downto 0); -- mem_ba
|
||||||
|
mem_ck : out std_logic_vector(0 downto 0); -- mem_ck
|
||||||
|
mem_ck_n : out std_logic_vector(0 downto 0); -- mem_ck_n
|
||||||
|
mem_cke : out std_logic_vector(0 downto 0); -- mem_cke
|
||||||
|
mem_cs_n : out std_logic_vector(0 downto 0); -- mem_cs_n
|
||||||
|
mem_dm : out std_logic_vector(1 downto 0); -- mem_dm
|
||||||
|
mem_ras_n : out std_logic_vector(0 downto 0); -- mem_ras_n
|
||||||
|
mem_cas_n : out std_logic_vector(0 downto 0); -- mem_cas_n
|
||||||
|
mem_we_n : out std_logic_vector(0 downto 0); -- mem_we_n
|
||||||
|
mem_reset_n : out std_logic; -- mem_reset_n
|
||||||
|
mem_dq : inout std_logic_vector(15 downto 0) := (others => 'X'); -- mem_dq
|
||||||
|
mem_dqs : inout std_logic_vector(1 downto 0) := (others => 'X'); -- mem_dqs
|
||||||
|
mem_dqs_n : inout std_logic_vector(1 downto 0) := (others => 'X'); -- mem_dqs_n
|
||||||
|
mem_odt : out std_logic_vector(0 downto 0); -- mem_odt
|
||||||
|
avl_ready_0 : out std_logic; -- waitrequest_n
|
||||||
|
avl_burstbegin_0 : in std_logic := 'X'; -- beginbursttransfer
|
||||||
|
avl_addr_0 : in std_logic_vector(24 downto 0) := (others => 'X'); -- address
|
||||||
|
avl_rdata_valid_0 : out std_logic; -- readdatavalid
|
||||||
|
avl_rdata_0 : out std_logic_vector(31 downto 0); -- readdata
|
||||||
|
avl_wdata_0 : in std_logic_vector(31 downto 0) := (others => 'X'); -- writedata
|
||||||
|
avl_be_0 : in std_logic_vector(3 downto 0) := (others => 'X'); -- byteenable
|
||||||
|
avl_read_req_0 : in std_logic := 'X'; -- read
|
||||||
|
avl_write_req_0 : in std_logic := 'X'; -- write
|
||||||
|
avl_size_0 : in std_logic_vector(2 downto 0) := (others => 'X'); -- burstcount
|
||||||
|
mp_cmd_clk_0_clk : in std_logic := 'X'; -- clk
|
||||||
|
mp_cmd_reset_n_0_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
mp_rfifo_clk_0_clk : in std_logic := 'X'; -- clk
|
||||||
|
mp_rfifo_reset_n_0_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
mp_wfifo_clk_0_clk : in std_logic := 'X'; -- clk
|
||||||
|
mp_wfifo_reset_n_0_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
csr_clk : in std_logic := 'X'; -- clk
|
||||||
|
csr_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
local_init_done : out std_logic; -- local_init_done
|
||||||
|
local_cal_success : out std_logic; -- local_cal_success
|
||||||
|
local_cal_fail : out std_logic; -- local_cal_fail
|
||||||
|
oct_rzqin : in std_logic := 'X'; -- rzqin
|
||||||
|
pll_mem_clk : out std_logic; -- pll_mem_clk
|
||||||
|
pll_write_clk : out std_logic; -- pll_write_clk
|
||||||
|
pll_locked : out std_logic; -- pll_locked
|
||||||
|
pll_write_clk_pre_phy_clk : out std_logic; -- pll_write_clk_pre_phy_clk
|
||||||
|
pll_addr_cmd_clk : out std_logic; -- pll_addr_cmd_clk
|
||||||
|
pll_avl_clk : out std_logic; -- pll_avl_clk
|
||||||
|
pll_config_clk : out std_logic; -- pll_config_clk
|
||||||
|
pll_mem_phy_clk : out std_logic; -- pll_mem_phy_clk
|
||||||
|
afi_phy_clk : out std_logic; -- afi_phy_clk
|
||||||
|
pll_avl_phy_clk : out std_logic -- pll_avl_phy_clk
|
||||||
|
);
|
||||||
|
end component ddr3;
|
||||||
|
|
63
ip/altera/ddr3.ppf
Normal file
63
ip/altera/ddr3.ppf
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<pinplan
|
||||||
|
variation_name="ddr3"
|
||||||
|
megafunction_name="ALTERA_MEM_IF_DDR3_EMIF"
|
||||||
|
intended_family="Cyclone V"
|
||||||
|
specifies="all_ports">
|
||||||
|
<global>
|
||||||
|
<pin name="pll_ref_clk" direction="input" scope="external" />
|
||||||
|
<pin name="global_reset_n" direction="input" scope="external" />
|
||||||
|
<pin name="soft_reset_n" direction="input" scope="external" />
|
||||||
|
<pin name="afi_clk" direction="output" scope="external" />
|
||||||
|
<pin name="afi_half_clk" direction="output" scope="external" />
|
||||||
|
<pin name="afi_reset_n" direction="output" scope="external" />
|
||||||
|
<pin name="afi_reset_export_n" direction="output" scope="external" />
|
||||||
|
<pin name="mem_a[12..0]" direction="output" scope="external" />
|
||||||
|
<pin name="mem_ba[2..0]" direction="output" scope="external" />
|
||||||
|
<pin name="mem_ck" direction="output" scope="external" />
|
||||||
|
<pin name="mem_ck_n" direction="output" scope="external" />
|
||||||
|
<pin name="mem_cke" direction="output" scope="external" />
|
||||||
|
<pin name="mem_cs_n" direction="output" scope="external" />
|
||||||
|
<pin name="mem_dm[1..0]" direction="output" scope="external" />
|
||||||
|
<pin name="mem_ras_n" direction="output" scope="external" />
|
||||||
|
<pin name="mem_cas_n" direction="output" scope="external" />
|
||||||
|
<pin name="mem_we_n" direction="output" scope="external" />
|
||||||
|
<pin name="mem_reset_n" direction="output" scope="external" />
|
||||||
|
<pin name="mem_dq[15..0]" direction="bidir" scope="external" />
|
||||||
|
<pin name="mem_dqs[1..0]" direction="bidir" scope="external" />
|
||||||
|
<pin name="mem_dqs_n[1..0]" direction="bidir" scope="external" />
|
||||||
|
<pin name="mem_odt" direction="output" scope="external" />
|
||||||
|
<pin name="avl_ready_0" direction="output" scope="external" />
|
||||||
|
<pin name="avl_burstbegin_0" direction="input" scope="external" />
|
||||||
|
<pin name="avl_addr_0[24..0]" direction="input" scope="external" />
|
||||||
|
<pin name="avl_rdata_valid_0" direction="output" scope="external" />
|
||||||
|
<pin name="avl_rdata_0[31..0]" direction="output" scope="external" />
|
||||||
|
<pin name="avl_wdata_0[31..0]" direction="input" scope="external" />
|
||||||
|
<pin name="avl_be_0[3..0]" direction="input" scope="external" />
|
||||||
|
<pin name="avl_read_req_0" direction="input" scope="external" />
|
||||||
|
<pin name="avl_write_req_0" direction="input" scope="external" />
|
||||||
|
<pin name="avl_size_0[2..0]" direction="input" scope="external" />
|
||||||
|
<pin name="mp_cmd_clk_0_clk" direction="input" scope="external" />
|
||||||
|
<pin name="mp_cmd_reset_n_0_reset_n" direction="input" scope="external" />
|
||||||
|
<pin name="mp_rfifo_clk_0_clk" direction="input" scope="external" />
|
||||||
|
<pin name="mp_rfifo_reset_n_0_reset_n" direction="input" scope="external" />
|
||||||
|
<pin name="mp_wfifo_clk_0_clk" direction="input" scope="external" />
|
||||||
|
<pin name="mp_wfifo_reset_n_0_reset_n" direction="input" scope="external" />
|
||||||
|
<pin name="csr_clk" direction="input" scope="external" />
|
||||||
|
<pin name="csr_reset_n" direction="input" scope="external" />
|
||||||
|
<pin name="local_init_done" direction="output" scope="external" />
|
||||||
|
<pin name="local_cal_success" direction="output" scope="external" />
|
||||||
|
<pin name="local_cal_fail" direction="output" scope="external" />
|
||||||
|
<pin name="oct_rzqin" direction="input" scope="external" />
|
||||||
|
<pin name="pll_mem_clk" direction="output" scope="external" />
|
||||||
|
<pin name="pll_write_clk" direction="output" scope="external" />
|
||||||
|
<pin name="pll_locked" direction="output" scope="external" />
|
||||||
|
<pin name="pll_write_clk_pre_phy_clk" direction="output" scope="external" />
|
||||||
|
<pin name="pll_addr_cmd_clk" direction="output" scope="external" />
|
||||||
|
<pin name="pll_avl_clk" direction="output" scope="external" />
|
||||||
|
<pin name="pll_config_clk" direction="output" scope="external" />
|
||||||
|
<pin name="pll_mem_phy_clk" direction="output" scope="external" />
|
||||||
|
<pin name="afi_phy_clk" direction="output" scope="external" />
|
||||||
|
<pin name="pll_avl_phy_clk" direction="output" scope="external" />
|
||||||
|
</global>
|
||||||
|
</pinplan>
|
5460
ip/altera/ddr3.qip
Normal file
5460
ip/altera/ddr3.qip
Normal file
File diff suppressed because it is too large
Load Diff
9
ip/altera/ddr3.sip
Normal file
9
ip/altera/ddr3.sip
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
set_global_assignment -entity "ddr3" -library "lib_ddr3" -name IP_TOOL_NAME "altera_mem_if_ddr3_emif"
|
||||||
|
set_global_assignment -entity "ddr3" -library "lib_ddr3" -name IP_TOOL_VERSION "15.1"
|
||||||
|
set_global_assignment -entity "ddr3" -library "lib_ddr3" -name IP_TOOL_ENV "mwpim"
|
||||||
|
set_global_assignment -library "lib_ddr3" -name SPD_FILE [file join $::quartus(sip_path) "ddr3.spd"]
|
||||||
|
|
||||||
|
set_global_assignment -library "lib_ddr3" -name MISC_FILE [file join $::quartus(sip_path) "ddr3_sim/ddr3.vhd"]
|
||||||
|
set_global_assignment -library "lib_ddr3" -name MISC_FILE [file join $::quartus(sip_path) "ddr3_sim/ddr3/ddr3_0002.vhd"]
|
||||||
|
set_global_assignment -library "lib_ddr3" -name MISC_FILE [file join $::quartus(sip_path) "ddr3_sim/ddr3/ddr3_pll0.vho"]
|
||||||
|
set_global_assignment -library "lib_ddr3" -name MISC_FILE [file join $::quartus(sip_path) "ddr3_sim/ddr3/ddr3_pll0_sim_delay.vhd"]
|
51759
ip/altera/ddr3.sopcinfo
Normal file
51759
ip/altera/ddr3.sopcinfo
Normal file
File diff suppressed because it is too large
Load Diff
13
ip/altera/ddr3.spd
Normal file
13
ip/altera/ddr3.spd
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simPackage>
|
||||||
|
<file path="ddr3_sim/ddr3/ddr3_pll0.vho" type="VHDL" library="pll0" />
|
||||||
|
<file
|
||||||
|
path="ddr3_sim/ddr3/ddr3_pll0_sim_delay.vhd"
|
||||||
|
type="VHDL"
|
||||||
|
library="pll0" />
|
||||||
|
<file path="ddr3_sim/ddr3/ddr3_0002.vhd" type="VHDL" library="ddr3" />
|
||||||
|
<file path="ddr3_sim/ddr3.vhd" type="VHDL" />
|
||||||
|
<topLevel name="ddr3" />
|
||||||
|
<deviceFamily name="cyclonev" />
|
||||||
|
<modelMap controllerPath="ddr3" modelPath="ddr3" />
|
||||||
|
</simPackage>
|
536
ip/altera/ddr3.vhd
Normal file
536
ip/altera/ddr3.vhd
Normal file
@ -0,0 +1,536 @@
|
|||||||
|
-- megafunction wizard: %DDR3 SDRAM Controller with UniPHY v15.1%
|
||||||
|
-- GENERATION: XML
|
||||||
|
-- ddr3.vhd
|
||||||
|
|
||||||
|
-- Generated using ACDS version 15.1 185
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
use IEEE.numeric_std.all;
|
||||||
|
|
||||||
|
entity ddr3 is
|
||||||
|
port (
|
||||||
|
pll_ref_clk : in std_logic := '0'; -- pll_ref_clk.clk
|
||||||
|
global_reset_n : in std_logic := '0'; -- global_reset.reset_n
|
||||||
|
soft_reset_n : in std_logic := '0'; -- soft_reset.reset_n
|
||||||
|
afi_clk : out std_logic; -- afi_clk.clk
|
||||||
|
afi_half_clk : out std_logic; -- afi_half_clk.clk
|
||||||
|
afi_reset_n : out std_logic; -- afi_reset.reset_n
|
||||||
|
afi_reset_export_n : out std_logic; -- afi_reset_export.reset_n
|
||||||
|
mem_a : out std_logic_vector(12 downto 0); -- memory.mem_a
|
||||||
|
mem_ba : out std_logic_vector(2 downto 0); -- .mem_ba
|
||||||
|
mem_ck : out std_logic_vector(0 downto 0); -- .mem_ck
|
||||||
|
mem_ck_n : out std_logic_vector(0 downto 0); -- .mem_ck_n
|
||||||
|
mem_cke : out std_logic_vector(0 downto 0); -- .mem_cke
|
||||||
|
mem_cs_n : out std_logic_vector(0 downto 0); -- .mem_cs_n
|
||||||
|
mem_dm : out std_logic_vector(1 downto 0); -- .mem_dm
|
||||||
|
mem_ras_n : out std_logic_vector(0 downto 0); -- .mem_ras_n
|
||||||
|
mem_cas_n : out std_logic_vector(0 downto 0); -- .mem_cas_n
|
||||||
|
mem_we_n : out std_logic_vector(0 downto 0); -- .mem_we_n
|
||||||
|
mem_reset_n : out std_logic; -- .mem_reset_n
|
||||||
|
mem_dq : inout std_logic_vector(15 downto 0) := (others => '0'); -- .mem_dq
|
||||||
|
mem_dqs : inout std_logic_vector(1 downto 0) := (others => '0'); -- .mem_dqs
|
||||||
|
mem_dqs_n : inout std_logic_vector(1 downto 0) := (others => '0'); -- .mem_dqs_n
|
||||||
|
mem_odt : out std_logic_vector(0 downto 0); -- .mem_odt
|
||||||
|
avl_ready_0 : out std_logic; -- avl_0.waitrequest_n
|
||||||
|
avl_burstbegin_0 : in std_logic := '0'; -- .beginbursttransfer
|
||||||
|
avl_addr_0 : in std_logic_vector(24 downto 0) := (others => '0'); -- .address
|
||||||
|
avl_rdata_valid_0 : out std_logic; -- .readdatavalid
|
||||||
|
avl_rdata_0 : out std_logic_vector(31 downto 0); -- .readdata
|
||||||
|
avl_wdata_0 : in std_logic_vector(31 downto 0) := (others => '0'); -- .writedata
|
||||||
|
avl_be_0 : in std_logic_vector(3 downto 0) := (others => '0'); -- .byteenable
|
||||||
|
avl_read_req_0 : in std_logic := '0'; -- .read
|
||||||
|
avl_write_req_0 : in std_logic := '0'; -- .write
|
||||||
|
avl_size_0 : in std_logic_vector(2 downto 0) := (others => '0'); -- .burstcount
|
||||||
|
mp_cmd_clk_0_clk : in std_logic := '0'; -- mp_cmd_clk_0.clk
|
||||||
|
mp_cmd_reset_n_0_reset_n : in std_logic := '0'; -- mp_cmd_reset_n_0.reset_n
|
||||||
|
mp_rfifo_clk_0_clk : in std_logic := '0'; -- mp_rfifo_clk_0.clk
|
||||||
|
mp_rfifo_reset_n_0_reset_n : in std_logic := '0'; -- mp_rfifo_reset_n_0.reset_n
|
||||||
|
mp_wfifo_clk_0_clk : in std_logic := '0'; -- mp_wfifo_clk_0.clk
|
||||||
|
mp_wfifo_reset_n_0_reset_n : in std_logic := '0'; -- mp_wfifo_reset_n_0.reset_n
|
||||||
|
csr_clk : in std_logic := '0'; -- csr_clk.clk
|
||||||
|
csr_reset_n : in std_logic := '0'; -- csr_reset_n.reset_n
|
||||||
|
local_init_done : out std_logic; -- status.local_init_done
|
||||||
|
local_cal_success : out std_logic; -- .local_cal_success
|
||||||
|
local_cal_fail : out std_logic; -- .local_cal_fail
|
||||||
|
oct_rzqin : in std_logic := '0'; -- oct.rzqin
|
||||||
|
pll_mem_clk : out std_logic; -- pll_sharing.pll_mem_clk
|
||||||
|
pll_write_clk : out std_logic; -- .pll_write_clk
|
||||||
|
pll_locked : out std_logic; -- .pll_locked
|
||||||
|
pll_write_clk_pre_phy_clk : out std_logic; -- .pll_write_clk_pre_phy_clk
|
||||||
|
pll_addr_cmd_clk : out std_logic; -- .pll_addr_cmd_clk
|
||||||
|
pll_avl_clk : out std_logic; -- .pll_avl_clk
|
||||||
|
pll_config_clk : out std_logic; -- .pll_config_clk
|
||||||
|
pll_mem_phy_clk : out std_logic; -- .pll_mem_phy_clk
|
||||||
|
afi_phy_clk : out std_logic; -- .afi_phy_clk
|
||||||
|
pll_avl_phy_clk : out std_logic -- .pll_avl_phy_clk
|
||||||
|
);
|
||||||
|
end entity ddr3;
|
||||||
|
|
||||||
|
architecture rtl of ddr3 is
|
||||||
|
component ddr3_0002 is
|
||||||
|
port (
|
||||||
|
pll_ref_clk : in std_logic := 'X'; -- clk
|
||||||
|
global_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
soft_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
afi_clk : out std_logic; -- clk
|
||||||
|
afi_half_clk : out std_logic; -- clk
|
||||||
|
afi_reset_n : out std_logic; -- reset_n
|
||||||
|
afi_reset_export_n : out std_logic; -- reset_n
|
||||||
|
mem_a : out std_logic_vector(12 downto 0); -- mem_a
|
||||||
|
mem_ba : out std_logic_vector(2 downto 0); -- mem_ba
|
||||||
|
mem_ck : out std_logic_vector(0 downto 0); -- mem_ck
|
||||||
|
mem_ck_n : out std_logic_vector(0 downto 0); -- mem_ck_n
|
||||||
|
mem_cke : out std_logic_vector(0 downto 0); -- mem_cke
|
||||||
|
mem_cs_n : out std_logic_vector(0 downto 0); -- mem_cs_n
|
||||||
|
mem_dm : out std_logic_vector(1 downto 0); -- mem_dm
|
||||||
|
mem_ras_n : out std_logic_vector(0 downto 0); -- mem_ras_n
|
||||||
|
mem_cas_n : out std_logic_vector(0 downto 0); -- mem_cas_n
|
||||||
|
mem_we_n : out std_logic_vector(0 downto 0); -- mem_we_n
|
||||||
|
mem_reset_n : out std_logic; -- mem_reset_n
|
||||||
|
mem_dq : inout std_logic_vector(15 downto 0) := (others => 'X'); -- mem_dq
|
||||||
|
mem_dqs : inout std_logic_vector(1 downto 0) := (others => 'X'); -- mem_dqs
|
||||||
|
mem_dqs_n : inout std_logic_vector(1 downto 0) := (others => 'X'); -- mem_dqs_n
|
||||||
|
mem_odt : out std_logic_vector(0 downto 0); -- mem_odt
|
||||||
|
avl_ready_0 : out std_logic; -- waitrequest_n
|
||||||
|
avl_burstbegin_0 : in std_logic := 'X'; -- beginbursttransfer
|
||||||
|
avl_addr_0 : in std_logic_vector(24 downto 0) := (others => 'X'); -- address
|
||||||
|
avl_rdata_valid_0 : out std_logic; -- readdatavalid
|
||||||
|
avl_rdata_0 : out std_logic_vector(31 downto 0); -- readdata
|
||||||
|
avl_wdata_0 : in std_logic_vector(31 downto 0) := (others => 'X'); -- writedata
|
||||||
|
avl_be_0 : in std_logic_vector(3 downto 0) := (others => 'X'); -- byteenable
|
||||||
|
avl_read_req_0 : in std_logic := 'X'; -- read
|
||||||
|
avl_write_req_0 : in std_logic := 'X'; -- write
|
||||||
|
avl_size_0 : in std_logic_vector(2 downto 0) := (others => 'X'); -- burstcount
|
||||||
|
mp_cmd_clk_0_clk : in std_logic := 'X'; -- clk
|
||||||
|
mp_cmd_reset_n_0_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
mp_rfifo_clk_0_clk : in std_logic := 'X'; -- clk
|
||||||
|
mp_rfifo_reset_n_0_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
mp_wfifo_clk_0_clk : in std_logic := 'X'; -- clk
|
||||||
|
mp_wfifo_reset_n_0_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
csr_clk : in std_logic := 'X'; -- clk
|
||||||
|
csr_reset_n : in std_logic := 'X'; -- reset_n
|
||||||
|
local_init_done : out std_logic; -- local_init_done
|
||||||
|
local_cal_success : out std_logic; -- local_cal_success
|
||||||
|
local_cal_fail : out std_logic; -- local_cal_fail
|
||||||
|
oct_rzqin : in std_logic := 'X'; -- rzqin
|
||||||
|
pll_mem_clk : out std_logic; -- pll_mem_clk
|
||||||
|
pll_write_clk : out std_logic; -- pll_write_clk
|
||||||
|
pll_locked : out std_logic; -- pll_locked
|
||||||
|
pll_write_clk_pre_phy_clk : out std_logic; -- pll_write_clk_pre_phy_clk
|
||||||
|
pll_addr_cmd_clk : out std_logic; -- pll_addr_cmd_clk
|
||||||
|
pll_avl_clk : out std_logic; -- pll_avl_clk
|
||||||
|
pll_config_clk : out std_logic; -- pll_config_clk
|
||||||
|
pll_mem_phy_clk : out std_logic; -- pll_mem_phy_clk
|
||||||
|
afi_phy_clk : out std_logic; -- afi_phy_clk
|
||||||
|
pll_avl_phy_clk : out std_logic -- pll_avl_phy_clk
|
||||||
|
);
|
||||||
|
end component ddr3_0002;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
ddr3_inst : component ddr3_0002
|
||||||
|
port map (
|
||||||
|
pll_ref_clk => pll_ref_clk, -- pll_ref_clk.clk
|
||||||
|
global_reset_n => global_reset_n, -- global_reset.reset_n
|
||||||
|
soft_reset_n => soft_reset_n, -- soft_reset.reset_n
|
||||||
|
afi_clk => afi_clk, -- afi_clk.clk
|
||||||
|
afi_half_clk => afi_half_clk, -- afi_half_clk.clk
|
||||||
|
afi_reset_n => afi_reset_n, -- afi_reset.reset_n
|
||||||
|
afi_reset_export_n => afi_reset_export_n, -- afi_reset_export.reset_n
|
||||||
|
mem_a => mem_a, -- memory.mem_a
|
||||||
|
mem_ba => mem_ba, -- .mem_ba
|
||||||
|
mem_ck => mem_ck, -- .mem_ck
|
||||||
|
mem_ck_n => mem_ck_n, -- .mem_ck_n
|
||||||
|
mem_cke => mem_cke, -- .mem_cke
|
||||||
|
mem_cs_n => mem_cs_n, -- .mem_cs_n
|
||||||
|
mem_dm => mem_dm, -- .mem_dm
|
||||||
|
mem_ras_n => mem_ras_n, -- .mem_ras_n
|
||||||
|
mem_cas_n => mem_cas_n, -- .mem_cas_n
|
||||||
|
mem_we_n => mem_we_n, -- .mem_we_n
|
||||||
|
mem_reset_n => mem_reset_n, -- .mem_reset_n
|
||||||
|
mem_dq => mem_dq, -- .mem_dq
|
||||||
|
mem_dqs => mem_dqs, -- .mem_dqs
|
||||||
|
mem_dqs_n => mem_dqs_n, -- .mem_dqs_n
|
||||||
|
mem_odt => mem_odt, -- .mem_odt
|
||||||
|
avl_ready_0 => avl_ready_0, -- avl_0.waitrequest_n
|
||||||
|
avl_burstbegin_0 => avl_burstbegin_0, -- .beginbursttransfer
|
||||||
|
avl_addr_0 => avl_addr_0, -- .address
|
||||||
|
avl_rdata_valid_0 => avl_rdata_valid_0, -- .readdatavalid
|
||||||
|
avl_rdata_0 => avl_rdata_0, -- .readdata
|
||||||
|
avl_wdata_0 => avl_wdata_0, -- .writedata
|
||||||
|
avl_be_0 => avl_be_0, -- .byteenable
|
||||||
|
avl_read_req_0 => avl_read_req_0, -- .read
|
||||||
|
avl_write_req_0 => avl_write_req_0, -- .write
|
||||||
|
avl_size_0 => avl_size_0, -- .burstcount
|
||||||
|
mp_cmd_clk_0_clk => mp_cmd_clk_0_clk, -- mp_cmd_clk_0.clk
|
||||||
|
mp_cmd_reset_n_0_reset_n => mp_cmd_reset_n_0_reset_n, -- mp_cmd_reset_n_0.reset_n
|
||||||
|
mp_rfifo_clk_0_clk => mp_rfifo_clk_0_clk, -- mp_rfifo_clk_0.clk
|
||||||
|
mp_rfifo_reset_n_0_reset_n => mp_rfifo_reset_n_0_reset_n, -- mp_rfifo_reset_n_0.reset_n
|
||||||
|
mp_wfifo_clk_0_clk => mp_wfifo_clk_0_clk, -- mp_wfifo_clk_0.clk
|
||||||
|
mp_wfifo_reset_n_0_reset_n => mp_wfifo_reset_n_0_reset_n, -- mp_wfifo_reset_n_0.reset_n
|
||||||
|
csr_clk => csr_clk, -- csr_clk.clk
|
||||||
|
csr_reset_n => csr_reset_n, -- csr_reset_n.reset_n
|
||||||
|
local_init_done => local_init_done, -- status.local_init_done
|
||||||
|
local_cal_success => local_cal_success, -- .local_cal_success
|
||||||
|
local_cal_fail => local_cal_fail, -- .local_cal_fail
|
||||||
|
oct_rzqin => oct_rzqin, -- oct.rzqin
|
||||||
|
pll_mem_clk => pll_mem_clk, -- pll_sharing.pll_mem_clk
|
||||||
|
pll_write_clk => pll_write_clk, -- .pll_write_clk
|
||||||
|
pll_locked => pll_locked, -- .pll_locked
|
||||||
|
pll_write_clk_pre_phy_clk => pll_write_clk_pre_phy_clk, -- .pll_write_clk_pre_phy_clk
|
||||||
|
pll_addr_cmd_clk => pll_addr_cmd_clk, -- .pll_addr_cmd_clk
|
||||||
|
pll_avl_clk => pll_avl_clk, -- .pll_avl_clk
|
||||||
|
pll_config_clk => pll_config_clk, -- .pll_config_clk
|
||||||
|
pll_mem_phy_clk => pll_mem_phy_clk, -- .pll_mem_phy_clk
|
||||||
|
afi_phy_clk => afi_phy_clk, -- .afi_phy_clk
|
||||||
|
pll_avl_phy_clk => pll_avl_phy_clk -- .pll_avl_phy_clk
|
||||||
|
);
|
||||||
|
|
||||||
|
end architecture rtl; -- of ddr3
|
||||||
|
-- Retrieval info: <?xml version="1.0"?>
|
||||||
|
--<!--
|
||||||
|
-- Generated by Altera MegaWizard Launcher Utility version 1.0
|
||||||
|
-- ************************************************************
|
||||||
|
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||||
|
-- ************************************************************
|
||||||
|
-- Copyright (C) 1991-2016 Altera Corporation
|
||||||
|
-- Any megafunction design, and related net list (encrypted or decrypted),
|
||||||
|
-- support information, device programming or simulation file, and any other
|
||||||
|
-- associated documentation or information provided by Altera or a partner
|
||||||
|
-- under Altera's Megafunction Partnership Program may be used only to
|
||||||
|
-- program PLD devices (but not masked PLD devices) from Altera. Any other
|
||||||
|
-- use of such megafunction design, net list, support information, device
|
||||||
|
-- programming or simulation file, or any other related documentation or
|
||||||
|
-- information is prohibited for any other purpose, including, but not
|
||||||
|
-- limited to modification, reverse engineering, de-compiling, or use with
|
||||||
|
-- any other silicon devices, unless such use is explicitly licensed under
|
||||||
|
-- a separate agreement with Altera or a megafunction partner. Title to
|
||||||
|
-- the intellectual property, including patents, copyrights, trademarks,
|
||||||
|
-- trade secrets, or maskworks, embodied in any such megafunction design,
|
||||||
|
-- net list, support information, device programming or simulation file, or
|
||||||
|
-- any other related documentation or information provided by Altera or a
|
||||||
|
-- megafunction partner, remains with Altera, the megafunction partner, or
|
||||||
|
-- their respective licensors. No other licenses, including any licenses
|
||||||
|
-- needed under any third party's intellectual property, are provided herein.
|
||||||
|
---->
|
||||||
|
-- Retrieval info: <instance entity-name="altera_mem_if_ddr3_emif" version="15.1" >
|
||||||
|
-- Retrieval info: <generic name="MEM_VENDOR" value="Micron" />
|
||||||
|
-- Retrieval info: <generic name="MEM_FORMAT" value="DISCRETE" />
|
||||||
|
-- Retrieval info: <generic name="RDIMM_CONFIG" value="0" />
|
||||||
|
-- Retrieval info: <generic name="LRDIMM_EXTENDED_CONFIG" value="0x0" />
|
||||||
|
-- Retrieval info: <generic name="DISCRETE_FLY_BY" value="true" />
|
||||||
|
-- Retrieval info: <generic name="DEVICE_DEPTH" value="1" />
|
||||||
|
-- Retrieval info: <generic name="MEM_MIRROR_ADDRESSING" value="0" />
|
||||||
|
-- Retrieval info: <generic name="MEM_CLK_FREQ_MAX" value="666.667" />
|
||||||
|
-- Retrieval info: <generic name="MEM_ROW_ADDR_WIDTH" value="13" />
|
||||||
|
-- Retrieval info: <generic name="MEM_COL_ADDR_WIDTH" value="10" />
|
||||||
|
-- Retrieval info: <generic name="MEM_DQ_WIDTH" value="16" />
|
||||||
|
-- Retrieval info: <generic name="MEM_DQ_PER_DQS" value="8" />
|
||||||
|
-- Retrieval info: <generic name="MEM_BANKADDR_WIDTH" value="3" />
|
||||||
|
-- Retrieval info: <generic name="MEM_IF_DM_PINS_EN" value="true" />
|
||||||
|
-- Retrieval info: <generic name="MEM_IF_DQSN_EN" value="true" />
|
||||||
|
-- Retrieval info: <generic name="MEM_NUMBER_OF_DIMMS" value="1" />
|
||||||
|
-- Retrieval info: <generic name="MEM_NUMBER_OF_RANKS_PER_DIMM" value="1" />
|
||||||
|
-- Retrieval info: <generic name="MEM_NUMBER_OF_RANKS_PER_DEVICE" value="1" />
|
||||||
|
-- Retrieval info: <generic name="MEM_RANK_MULTIPLICATION_FACTOR" value="1" />
|
||||||
|
-- Retrieval info: <generic name="MEM_CK_WIDTH" value="1" />
|
||||||
|
-- Retrieval info: <generic name="MEM_CS_WIDTH" value="1" />
|
||||||
|
-- Retrieval info: <generic name="MEM_CLK_EN_WIDTH" value="1" />
|
||||||
|
-- Retrieval info: <generic name="ALTMEMPHY_COMPATIBLE_MODE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="NEXTGEN" value="true" />
|
||||||
|
-- Retrieval info: <generic name="MEM_IF_BOARD_BASE_DELAY" value="10" />
|
||||||
|
-- Retrieval info: <generic name="MEM_IF_SIM_VALID_WINDOW" value="0" />
|
||||||
|
-- Retrieval info: <generic name="MEM_GUARANTEED_WRITE_INIT" value="false" />
|
||||||
|
-- Retrieval info: <generic name="MEM_VERBOSE" value="true" />
|
||||||
|
-- Retrieval info: <generic name="PINGPONGPHY_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="DUPLICATE_AC" value="false" />
|
||||||
|
-- Retrieval info: <generic name="REFRESH_BURST_VALIDATION" value="false" />
|
||||||
|
-- Retrieval info: <generic name="AP_MODE_EN" value="0" />
|
||||||
|
-- Retrieval info: <generic name="AP_MODE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="MEM_BL" value="OTF" />
|
||||||
|
-- Retrieval info: <generic name="MEM_BT" value="Sequential" />
|
||||||
|
-- Retrieval info: <generic name="MEM_ASR" value="Manual" />
|
||||||
|
-- Retrieval info: <generic name="MEM_SRT" value="Normal" />
|
||||||
|
-- Retrieval info: <generic name="MEM_PD" value="DLL off" />
|
||||||
|
-- Retrieval info: <generic name="MEM_DRV_STR" value="RZQ/6" />
|
||||||
|
-- Retrieval info: <generic name="MEM_DLL_EN" value="true" />
|
||||||
|
-- Retrieval info: <generic name="MEM_RTT_NOM" value="RZQ/2" />
|
||||||
|
-- Retrieval info: <generic name="MEM_RTT_WR" value="Dynamic ODT off" />
|
||||||
|
-- Retrieval info: <generic name="MEM_WTCL" value="6" />
|
||||||
|
-- Retrieval info: <generic name="MEM_ATCL" value="Disabled" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TCL" value="7" />
|
||||||
|
-- Retrieval info: <generic name="MEM_AUTO_LEVELING_MODE" value="true" />
|
||||||
|
-- Retrieval info: <generic name="MEM_USER_LEVELING_MODE" value="Leveling" />
|
||||||
|
-- Retrieval info: <generic name="MEM_INIT_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="MEM_INIT_FILE" value="" />
|
||||||
|
-- Retrieval info: <generic name="DAT_DATA_WIDTH" value="32" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TIS" value="190" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TIH" value="140" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDS" value="30" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDH" value="65" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDQSQ" value="125" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TQH" value="0.38" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDQSCK" value="255" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDQSCKDS" value="450" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDQSCKDM" value="900" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDQSCKDL" value="1200" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDQSS" value="0.25" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TQSH" value="0.4" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDSH" value="0.2" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_TDSS" value="0.2" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TINIT_US" value="500" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TMRD_CK" value="4" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TRAS_NS" value="36.0" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TRCD_NS" value="13.5" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TRP_NS" value="13.5" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TREFI_US" value="7.8" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TRFC_NS" value="110.0" />
|
||||||
|
-- Retrieval info: <generic name="CFG_TCCD_NS" value="2.5" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TWR_NS" value="15.0" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TWTR" value="5" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TFAW_NS" value="45.0" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TRRD_NS" value="7.5" />
|
||||||
|
-- Retrieval info: <generic name="MEM_TRTP_NS" value="7.5" />
|
||||||
|
-- Retrieval info: <generic name="RATE" value="Full" />
|
||||||
|
-- Retrieval info: <generic name="MEM_CLK_FREQ" value="300.0" />
|
||||||
|
-- Retrieval info: <generic name="USE_MEM_CLK_FREQ" value="false" />
|
||||||
|
-- Retrieval info: <generic name="FORCE_DQS_TRACKING" value="AUTO" />
|
||||||
|
-- Retrieval info: <generic name="FORCE_SHADOW_REGS" value="AUTO" />
|
||||||
|
-- Retrieval info: <generic name="MRS_MIRROR_PING_PONG_ATSO" value="false" />
|
||||||
|
-- Retrieval info: <generic name="SYS_INFO_DEVICE_FAMILY" value="Cyclone V" />
|
||||||
|
-- Retrieval info: <generic name="PARSE_FRIENDLY_DEVICE_FAMILY_PARAM_VALID" value="false" />
|
||||||
|
-- Retrieval info: <generic name="PARSE_FRIENDLY_DEVICE_FAMILY_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="DEVICE_FAMILY_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="SPEED_GRADE" value="8" />
|
||||||
|
-- Retrieval info: <generic name="IS_ES_DEVICE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="DISABLE_CHILD_MESSAGING" value="false" />
|
||||||
|
-- Retrieval info: <generic name="HARD_EMIF" value="true" />
|
||||||
|
-- Retrieval info: <generic name="HHP_HPS" value="false" />
|
||||||
|
-- Retrieval info: <generic name="HHP_HPS_VERIFICATION" value="false" />
|
||||||
|
-- Retrieval info: <generic name="HHP_HPS_SIMULATION" value="false" />
|
||||||
|
-- Retrieval info: <generic name="HPS_PROTOCOL" value="DEFAULT" />
|
||||||
|
-- Retrieval info: <generic name="CUT_NEW_FAMILY_TIMING" value="true" />
|
||||||
|
-- Retrieval info: <generic name="POWER_OF_TWO_BUS" value="false" />
|
||||||
|
-- Retrieval info: <generic name="SOPC_COMPAT_RESET" value="false" />
|
||||||
|
-- Retrieval info: <generic name="AVL_MAX_SIZE" value="4" />
|
||||||
|
-- Retrieval info: <generic name="BYTE_ENABLE" value="true" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_CTRL_AVALON_INTERFACE" value="true" />
|
||||||
|
-- Retrieval info: <generic name="CTL_DEEP_POWERDN_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_SELF_REFRESH_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="AUTO_POWERDN_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="AUTO_PD_CYCLES" value="0" />
|
||||||
|
-- Retrieval info: <generic name="CTL_USR_REFRESH_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_AUTOPCH_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_ZQCAL_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ADDR_ORDER" value="0" />
|
||||||
|
-- Retrieval info: <generic name="CTL_LOOK_AHEAD_DEPTH" value="4" />
|
||||||
|
-- Retrieval info: <generic name="CONTROLLER_LATENCY" value="5" />
|
||||||
|
-- Retrieval info: <generic name="CFG_REORDER_DATA" value="false" />
|
||||||
|
-- Retrieval info: <generic name="STARVE_LIMIT" value="10" />
|
||||||
|
-- Retrieval info: <generic name="CTL_CSR_ENABLED" value="true" />
|
||||||
|
-- Retrieval info: <generic name="CTL_CSR_CONNECTION" value="INTERNAL_JTAG" />
|
||||||
|
-- Retrieval info: <generic name="CTL_ECC_ENABLED" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_HRB_ENABLED" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_ECC_AUTO_CORRECTION_ENABLED" value="false" />
|
||||||
|
-- Retrieval info: <generic name="MULTICAST_EN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_DYNAMIC_BANK_ALLOCATION" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_DYNAMIC_BANK_NUM" value="4" />
|
||||||
|
-- Retrieval info: <generic name="DEBUG_MODE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_BURST_MERGE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_ENABLE_BURST_INTERRUPT" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_ENABLE_BURST_TERMINATE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="LOCAL_ID_WIDTH" value="8" />
|
||||||
|
-- Retrieval info: <generic name="WRBUFFER_ADDR_WIDTH" value="6" />
|
||||||
|
-- Retrieval info: <generic name="MAX_PENDING_WR_CMD" value="16" />
|
||||||
|
-- Retrieval info: <generic name="MAX_PENDING_RD_CMD" value="32" />
|
||||||
|
-- Retrieval info: <generic name="USE_MM_ADAPTOR" value="true" />
|
||||||
|
-- Retrieval info: <generic name="USE_AXI_ADAPTOR" value="false" />
|
||||||
|
-- Retrieval info: <generic name="HCX_COMPAT_MODE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CTL_CMD_QUEUE_DEPTH" value="8" />
|
||||||
|
-- Retrieval info: <generic name="CTL_CSR_READ_ONLY" value="1" />
|
||||||
|
-- Retrieval info: <generic name="CFG_DATA_REORDERING_TYPE" value="INTER_BANK" />
|
||||||
|
-- Retrieval info: <generic name="NUM_OF_PORTS" value="1" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_BONDING" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_USER_ECC" value="false" />
|
||||||
|
-- Retrieval info: <generic name="AVL_DATA_WIDTH_PORT" value="32,32,32,32,32,32" />
|
||||||
|
-- Retrieval info: <generic name="PRIORITY_PORT" value="1,1,1,1,1,1" />
|
||||||
|
-- Retrieval info: <generic name="WEIGHT_PORT" value="0,0,0,0,0,0" />
|
||||||
|
-- Retrieval info: <generic name="CPORT_TYPE_PORT" value="Bidirectional,Bidirectional,Bidirectional,Bidirectional,Bidirectional,Bidirectional" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_EMIT_BFM_MASTER" value="false" />
|
||||||
|
-- Retrieval info: <generic name="FORCE_SEQUENCER_TCL_DEBUG_MODE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_SEQUENCER_MARGINING_ON_BY_DEFAULT" value="false" />
|
||||||
|
-- Retrieval info: <generic name="REF_CLK_FREQ" value="50.0" />
|
||||||
|
-- Retrieval info: <generic name="REF_CLK_FREQ_PARAM_VALID" value="false" />
|
||||||
|
-- Retrieval info: <generic name="REF_CLK_FREQ_MIN_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="REF_CLK_FREQ_MAX_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_DR_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_DR_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_DR_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_DR_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_DR_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_DR_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_MEM_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_MEM_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_MEM_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_MEM_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_MEM_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_MEM_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_WRITE_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_WRITE_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_WRITE_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_WRITE_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_WRITE_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_WRITE_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_ADDR_CMD_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_ADDR_CMD_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_ADDR_CMD_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_ADDR_CMD_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_ADDR_CMD_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_ADDR_CMD_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_HALF_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_HALF_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_HALF_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_HALF_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_HALF_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_HALF_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_NIOS_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_NIOS_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_NIOS_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_NIOS_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_NIOS_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_NIOS_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_CONFIG_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_CONFIG_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_CONFIG_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_CONFIG_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_CONFIG_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_CONFIG_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_P2C_READ_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_P2C_READ_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_P2C_READ_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_P2C_READ_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_P2C_READ_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_P2C_READ_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_C2P_WRITE_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_C2P_WRITE_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_C2P_WRITE_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_C2P_WRITE_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_C2P_WRITE_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_C2P_WRITE_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_HR_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_HR_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_HR_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_HR_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_HR_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_HR_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_PHY_CLK_FREQ_PARAM" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_PHY_CLK_FREQ_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_PHY_CLK_PHASE_PS_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_PHY_CLK_PHASE_PS_SIM_STR_PARAM" value="" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_PHY_CLK_MULT_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_AFI_PHY_CLK_DIV_PARAM" value="0" />
|
||||||
|
-- Retrieval info: <generic name="PLL_CLK_PARAM_VALID" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_EXTRA_REPORTING" value="false" />
|
||||||
|
-- Retrieval info: <generic name="NUM_EXTRA_REPORT_PATH" value="10" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_ISS_PROBES" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CALIB_REG_WIDTH" value="8" />
|
||||||
|
-- Retrieval info: <generic name="USE_SEQUENCER_BFM" value="false" />
|
||||||
|
-- Retrieval info: <generic name="PLL_SHARING_MODE" value="None" />
|
||||||
|
-- Retrieval info: <generic name="NUM_PLL_SHARING_INTERFACES" value="1" />
|
||||||
|
-- Retrieval info: <generic name="EXPORT_AFI_HALF_CLK" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ABSTRACT_REAL_COMPARE_TEST" value="false" />
|
||||||
|
-- Retrieval info: <generic name="INCLUDE_BOARD_DELAY_MODEL" value="false" />
|
||||||
|
-- Retrieval info: <generic name="INCLUDE_MULTIRANK_BOARD_DELAY_MODEL" value="false" />
|
||||||
|
-- Retrieval info: <generic name="USE_FAKE_PHY" value="false" />
|
||||||
|
-- Retrieval info: <generic name="FORCE_MAX_LATENCY_COUNT_WIDTH" value="0" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_NON_DESTRUCTIVE_CALIB" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_DELAY_CHAIN_WRITE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="TRACKING_ERROR_TEST" value="false" />
|
||||||
|
-- Retrieval info: <generic name="TRACKING_WATCH_TEST" value="false" />
|
||||||
|
-- Retrieval info: <generic name="MARGIN_VARIATION_TEST" value="false" />
|
||||||
|
-- Retrieval info: <generic name="AC_ROM_USER_ADD_0" value="0_0000_0000_0000" />
|
||||||
|
-- Retrieval info: <generic name="AC_ROM_USER_ADD_1" value="0_0000_0000_1000" />
|
||||||
|
-- Retrieval info: <generic name="TREFI" value="35100" />
|
||||||
|
-- Retrieval info: <generic name="REFRESH_INTERVAL" value="15000" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_NON_DES_CAL_TEST" value="false" />
|
||||||
|
-- Retrieval info: <generic name="TRFC" value="350" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_NON_DES_CAL" value="false" />
|
||||||
|
-- Retrieval info: <generic name="EXTRA_SETTINGS" value="" />
|
||||||
|
-- Retrieval info: <generic name="MEM_DEVICE" value="MISSING_MODEL" />
|
||||||
|
-- Retrieval info: <generic name="FORCE_SYNTHESIS_LANGUAGE" value="" />
|
||||||
|
-- Retrieval info: <generic name="FORCED_NUM_WRITE_FR_CYCLE_SHIFTS" value="0" />
|
||||||
|
-- Retrieval info: <generic name="SEQUENCER_TYPE" value="NIOS" />
|
||||||
|
-- Retrieval info: <generic name="ADVERTIZE_SEQUENCER_SW_BUILD_FILES" value="false" />
|
||||||
|
-- Retrieval info: <generic name="FORCED_NON_LDC_ADDR_CMD_MEM_CK_INVERT" value="false" />
|
||||||
|
-- Retrieval info: <generic name="PHY_ONLY" value="false" />
|
||||||
|
-- Retrieval info: <generic name="SEQ_MODE" value="0" />
|
||||||
|
-- Retrieval info: <generic name="ADVANCED_CK_PHASES" value="false" />
|
||||||
|
-- Retrieval info: <generic name="COMMAND_PHASE" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="MEM_CK_PHASE" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="P2C_READ_CLOCK_ADD_PHASE" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="C2P_WRITE_CLOCK_ADD_PHASE" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="ACV_PHY_CLK_ADD_FR_PHASE" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="MEM_VOLTAGE" value="1.5V DDR3" />
|
||||||
|
-- Retrieval info: <generic name="PLL_LOCATION" value="Top_Bottom" />
|
||||||
|
-- Retrieval info: <generic name="SKIP_MEM_INIT" value="true" />
|
||||||
|
-- Retrieval info: <generic name="READ_DQ_DQS_CLOCK_SOURCE" value="INVERTED_DQS_BUS" />
|
||||||
|
-- Retrieval info: <generic name="DQ_INPUT_REG_USE_CLKN" value="false" />
|
||||||
|
-- Retrieval info: <generic name="DQS_DQSN_MODE" value="DIFFERENTIAL" />
|
||||||
|
-- Retrieval info: <generic name="AFI_DEBUG_INFO_WIDTH" value="32" />
|
||||||
|
-- Retrieval info: <generic name="CALIBRATION_MODE" value="Quick" />
|
||||||
|
-- Retrieval info: <generic name="NIOS_ROM_DATA_WIDTH" value="32" />
|
||||||
|
-- Retrieval info: <generic name="READ_FIFO_SIZE" value="8" />
|
||||||
|
-- Retrieval info: <generic name="PHY_CSR_ENABLED" value="false" />
|
||||||
|
-- Retrieval info: <generic name="PHY_CSR_CONNECTION" value="INTERNAL_JTAG" />
|
||||||
|
-- Retrieval info: <generic name="USER_DEBUG_LEVEL" value="1" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_DERATE_METHOD" value="AUTO" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_CK_CKN_SLEW_RATE" value="2.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_AC_SLEW_RATE" value="1.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_DQS_DQSN_SLEW_RATE" value="2.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_DQ_SLEW_RATE" value="1.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_TIS" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_TIH" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_TDS" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_TDH" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_ISI_METHOD" value="AUTO" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_AC_EYE_REDUCTION_SU" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_AC_EYE_REDUCTION_H" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_DQ_EYE_REDUCTION" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_DELTA_DQS_ARRIVAL_TIME" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_READ_DQ_EYE_REDUCTION" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_DELTA_READ_DQS_ARRIVAL_TIME" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="PACKAGE_DESKEW" value="false" />
|
||||||
|
-- Retrieval info: <generic name="AC_PACKAGE_DESKEW" value="false" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_MAX_CK_DELAY" value="0.6" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_MAX_DQS_DELAY" value="0.6" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_SKEW_CKDQS_DIMM_MIN" value="-0.01" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_SKEW_CKDQS_DIMM_MAX" value="0.01" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_SKEW_BETWEEN_DIMMS" value="0.05" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_SKEW_WITHIN_DQS" value="0.02" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_SKEW_BETWEEN_DQS" value="0.02" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_DQ_TO_DQS_SKEW" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_AC_SKEW" value="0.02" />
|
||||||
|
-- Retrieval info: <generic name="TIMING_BOARD_AC_TO_CK_SKEW" value="0.0" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_EXPORT_SEQ_DEBUG_BRIDGE" value="false" />
|
||||||
|
-- Retrieval info: <generic name="CORE_DEBUG_CONNECTION" value="EXPORT" />
|
||||||
|
-- Retrieval info: <generic name="ADD_EXTERNAL_SEQ_DEBUG_NIOS" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ED_EXPORT_SEQ_DEBUG" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ADD_EFFICIENCY_MONITOR" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ENABLE_ABS_RAM_MEM_INIT" value="false" />
|
||||||
|
-- Retrieval info: <generic name="ABS_RAM_MEM_INIT_FILENAME" value="meminit" />
|
||||||
|
-- Retrieval info: <generic name="DLL_SHARING_MODE" value="None" />
|
||||||
|
-- Retrieval info: <generic name="NUM_DLL_SHARING_INTERFACES" value="1" />
|
||||||
|
-- Retrieval info: <generic name="OCT_SHARING_MODE" value="None" />
|
||||||
|
-- Retrieval info: <generic name="NUM_OCT_SHARING_INTERFACES" value="1" />
|
||||||
|
-- Retrieval info: <generic name="AUTO_DEVICE" value="5CEBA2F17A7" />
|
||||||
|
-- Retrieval info: <generic name="AUTO_DEVICE_SPEEDGRADE" value="7" />
|
||||||
|
-- Retrieval info: </instance>
|
||||||
|
-- IPFS_FILES : ddr3.vho
|
||||||
|
-- RELATED_FILES: ddr3.vhd, ddr3_0002.v, ddr3_pll0.sv, ddr3_p0_clock_pair_generator.v, ddr3_p0_acv_hard_addr_cmd_pads.v, ddr3_p0_acv_hard_memphy.v, ddr3_p0_acv_ldc.v, ddr3_p0_acv_hard_io_pads.v, ddr3_p0_generic_ddio.v, ddr3_p0_reset.v, ddr3_p0_reset_sync.v, ddr3_p0_phy_csr.sv, ddr3_p0_iss_probe.v, ddr3_p0.sv, ddr3_p0_altdqdqs.v, altdq_dqs2_acv_connect_to_hard_phy_cyclonev.sv, ddr3_s0.v, ddr3_s0_mm_interconnect_0_avalon_st_adapter_error_adapter_0.sv, ddr3_s0_mm_interconnect_0_avalon_st_adapter.v, ddr3_s0_mm_interconnect_0_rsp_mux_002.sv, ddr3_s0_mm_interconnect_0_rsp_mux_001.sv, ddr3_s0_mm_interconnect_0_rsp_mux.sv, ddr3_s0_mm_interconnect_0_rsp_demux_003.sv, ddr3_s0_mm_interconnect_0_rsp_demux_001.sv, ddr3_s0_mm_interconnect_0_cmd_mux_003.sv, ddr3_s0_mm_interconnect_0_cmd_mux_001.sv, ddr3_s0_mm_interconnect_0_cmd_mux.sv, altera_merlin_arbitrator.sv, ddr3_s0_mm_interconnect_0_cmd_demux_002.sv, ddr3_s0_mm_interconnect_0_cmd_demux_001.sv, ddr3_s0_mm_interconnect_0_cmd_demux.sv, altera_merlin_reorder_memory.sv, altera_merlin_traffic_limiter.sv, ddr3_s0_mm_interconnect_0_router_006.sv, ddr3_s0_mm_interconnect_0_router_004.sv, ddr3_s0_mm_interconnect_0_router_003.sv, ddr3_s0_mm_interconnect_0_router_002.sv, ddr3_s0_mm_interconnect_0_router_001.sv, ddr3_s0_mm_interconnect_0_router.sv, altera_merlin_burst_uncompressor.sv, altera_merlin_slave_agent.sv, altera_merlin_master_agent.sv, ddr3_s0_irq_mapper.sv, ddr3_s0_mm_interconnect_0.v, altera_avalon_mm_bridge.v, altera_mem_if_sequencer_mem_no_ifdef_params.sv, altera_mem_if_simple_avalon_mm_bridge.sv, sequencer_reg_file.sv, sequencer_scc_reg_file.v, sequencer_scc_acv_phase_decode.v, sequencer_scc_acv_wrapper.sv, sequencer_scc_sv_phase_decode.v, sequencer_scc_sv_wrapper.sv, sequencer_scc_siii_phase_decode.v, sequencer_scc_siii_wrapper.sv, sequencer_scc_mgr.sv, altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench.v, altera_mem_if_sequencer_cpu_cv_synth_cpu_inst.v, altera_mem_if_sequencer_rst.sv, ddr3_dmaster.v, altera_mem_if_hard_memory_controller_top_cyclonev.sv, altera_mem_if_oct_cyclonev.sv, altera_mem_if_dll_cyclonev.sv, ddr3_mm_interconnect_1.v, ddr3_mm_interconnect_2.v, altera_reset_controller.v, altera_reset_synchronizer.v, altera_avalon_st_jtag_interface.v, altera_jtag_dc_streaming.v, altera_jtag_sld_node.v, altera_jtag_streaming.v, altera_avalon_st_clock_crosser.v, altera_std_synchronizer_nocut.v, altera_avalon_st_pipeline_base.v, altera_avalon_st_idle_remover.v, altera_avalon_st_idle_inserter.v, altera_avalon_st_pipeline_stage.sv, ddr3_dmaster_timing_adt.sv, altera_avalon_sc_fifo.v, altera_avalon_st_bytes_to_packets.v, altera_avalon_st_packets_to_bytes.v, altera_avalon_packets_to_master.v, ddr3_dmaster_b2p_adapter.sv, ddr3_dmaster_p2b_adapter.sv, altera_merlin_master_translator.sv, altera_merlin_slave_translator.sv, ddr3_mm_interconnect_2_router.sv, ddr3_mm_interconnect_2_router_001.sv, ddr3_mm_interconnect_2_router_002.sv, altera_merlin_burst_adapter.sv, altera_merlin_burst_adapter_uncmpr.sv, altera_merlin_burst_adapter_13_1.sv, altera_merlin_burst_adapter_new.sv, altera_incr_burst_converter.sv, altera_wrap_burst_converter.sv, altera_default_burst_converter.sv, altera_merlin_address_alignment.sv, ddr3_mm_interconnect_2_cmd_demux.sv, ddr3_mm_interconnect_2_cmd_mux.sv, ddr3_mm_interconnect_2_rsp_demux.sv, ddr3_mm_interconnect_2_rsp_mux.sv, altera_merlin_width_adapter.sv, ddr3_mm_interconnect_2_avalon_st_adapter.v, ddr3_mm_interconnect_2_avalon_st_adapter_001.v, ddr3_mm_interconnect_2_avalon_st_adapter_error_adapter_0.sv, ddr3_mm_interconnect_2_avalon_st_adapter_001_error_adapter_0.sv
|
2457
ip/altera/ddr3/altdq_dqs2_acv_connect_to_hard_phy_cyclonev.sv
Normal file
2457
ip/altera/ddr3/altdq_dqs2_acv_connect_to_hard_phy_cyclonev.sv
Normal file
File diff suppressed because it is too large
Load Diff
300
ip/altera/ddr3/altera_avalon_mm_bridge.v
Normal file
300
ip/altera/ddr3/altera_avalon_mm_bridge.v
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_avalon_mm_bridge/altera_avalon_mm_bridge.v#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
// --------------------------------------
|
||||||
|
// Avalon-MM pipeline bridge
|
||||||
|
//
|
||||||
|
// Optionally registers Avalon-MM command and response signals
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
module altera_avalon_mm_bridge
|
||||||
|
#(
|
||||||
|
parameter DATA_WIDTH = 32,
|
||||||
|
parameter SYMBOL_WIDTH = 8,
|
||||||
|
parameter RESPONSE_WIDTH = 2,
|
||||||
|
parameter HDL_ADDR_WIDTH = 10,
|
||||||
|
parameter BURSTCOUNT_WIDTH = 1,
|
||||||
|
|
||||||
|
parameter PIPELINE_COMMAND = 1,
|
||||||
|
parameter PIPELINE_RESPONSE = 1,
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Derived parameters
|
||||||
|
// --------------------------------------
|
||||||
|
parameter BYTEEN_WIDTH = DATA_WIDTH / SYMBOL_WIDTH
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
output s0_waitrequest,
|
||||||
|
output [DATA_WIDTH-1:0] s0_readdata,
|
||||||
|
output s0_readdatavalid,
|
||||||
|
output [RESPONSE_WIDTH-1:0] s0_response,
|
||||||
|
input [BURSTCOUNT_WIDTH-1:0] s0_burstcount,
|
||||||
|
input [DATA_WIDTH-1:0] s0_writedata,
|
||||||
|
input [HDL_ADDR_WIDTH-1:0] s0_address,
|
||||||
|
input s0_write,
|
||||||
|
input s0_read,
|
||||||
|
input [BYTEEN_WIDTH-1:0] s0_byteenable,
|
||||||
|
input s0_debugaccess,
|
||||||
|
|
||||||
|
input m0_waitrequest,
|
||||||
|
input [DATA_WIDTH-1:0] m0_readdata,
|
||||||
|
input m0_readdatavalid,
|
||||||
|
input [RESPONSE_WIDTH-1:0] m0_response,
|
||||||
|
output [BURSTCOUNT_WIDTH-1:0] m0_burstcount,
|
||||||
|
output [DATA_WIDTH-1:0] m0_writedata,
|
||||||
|
output [HDL_ADDR_WIDTH-1:0] m0_address,
|
||||||
|
output m0_write,
|
||||||
|
output m0_read,
|
||||||
|
output [BYTEEN_WIDTH-1:0] m0_byteenable,
|
||||||
|
output m0_debugaccess
|
||||||
|
);
|
||||||
|
// --------------------------------------
|
||||||
|
// Registers & signals
|
||||||
|
// --------------------------------------
|
||||||
|
reg [BURSTCOUNT_WIDTH-1:0] cmd_burstcount;
|
||||||
|
reg [DATA_WIDTH-1:0] cmd_writedata;
|
||||||
|
reg [HDL_ADDR_WIDTH-1:0] cmd_address;
|
||||||
|
reg cmd_write;
|
||||||
|
reg cmd_read;
|
||||||
|
reg [BYTEEN_WIDTH-1:0] cmd_byteenable;
|
||||||
|
wire cmd_waitrequest;
|
||||||
|
reg cmd_debugaccess;
|
||||||
|
|
||||||
|
reg [BURSTCOUNT_WIDTH-1:0] wr_burstcount;
|
||||||
|
reg [DATA_WIDTH-1:0] wr_writedata;
|
||||||
|
reg [HDL_ADDR_WIDTH-1:0] wr_address;
|
||||||
|
reg wr_write;
|
||||||
|
reg wr_read;
|
||||||
|
reg [BYTEEN_WIDTH-1:0] wr_byteenable;
|
||||||
|
reg wr_debugaccess;
|
||||||
|
|
||||||
|
reg [BURSTCOUNT_WIDTH-1:0] wr_reg_burstcount;
|
||||||
|
reg [DATA_WIDTH-1:0] wr_reg_writedata;
|
||||||
|
reg [HDL_ADDR_WIDTH-1:0] wr_reg_address;
|
||||||
|
reg wr_reg_write;
|
||||||
|
reg wr_reg_read;
|
||||||
|
reg [BYTEEN_WIDTH-1:0] wr_reg_byteenable;
|
||||||
|
reg wr_reg_waitrequest;
|
||||||
|
reg wr_reg_debugaccess;
|
||||||
|
|
||||||
|
reg use_reg;
|
||||||
|
wire wait_rise;
|
||||||
|
|
||||||
|
reg [DATA_WIDTH-1:0] rsp_readdata;
|
||||||
|
reg rsp_readdatavalid;
|
||||||
|
reg [RESPONSE_WIDTH-1:0] rsp_response;
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Command pipeline
|
||||||
|
//
|
||||||
|
// Registers all command signals, including waitrequest
|
||||||
|
// --------------------------------------
|
||||||
|
generate if (PIPELINE_COMMAND == 1) begin
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Waitrequest Pipeline Stage
|
||||||
|
//
|
||||||
|
// Output waitrequest is delayed by one cycle, which means
|
||||||
|
// that a master will see waitrequest assertions one cycle
|
||||||
|
// too late.
|
||||||
|
//
|
||||||
|
// Solution: buffer the command when waitrequest transitions
|
||||||
|
// from low->high. As an optimization, we can safely assume
|
||||||
|
// waitrequest is low by default because downstream logic
|
||||||
|
// in the bridge ensures this.
|
||||||
|
//
|
||||||
|
// Note: this implementation buffers idle cycles should
|
||||||
|
// waitrequest transition on such cycles. This is a potential
|
||||||
|
// cause for throughput loss, but ye olde pipeline bridge did
|
||||||
|
// the same for years and no one complained. Not buffering idle
|
||||||
|
// cycles costs logic on the waitrequest path.
|
||||||
|
// --------------------------------------
|
||||||
|
assign s0_waitrequest = wr_reg_waitrequest;
|
||||||
|
assign wait_rise = ~wr_reg_waitrequest & cmd_waitrequest;
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
wr_reg_waitrequest <= 1'b1;
|
||||||
|
// --------------------------------------
|
||||||
|
// Bit of trickiness here, deserving of a long comment.
|
||||||
|
//
|
||||||
|
// On the first cycle after reset, the pass-through
|
||||||
|
// must not be used or downstream logic may sample
|
||||||
|
// the same command twice because of the delay in
|
||||||
|
// transmitting a falling waitrequest.
|
||||||
|
//
|
||||||
|
// Using the registered command works on the condition
|
||||||
|
// that downstream logic deasserts waitrequest
|
||||||
|
// immediately after reset, which is true of the
|
||||||
|
// next stage in this bridge.
|
||||||
|
// --------------------------------------
|
||||||
|
use_reg <= 1'b1;
|
||||||
|
|
||||||
|
wr_reg_burstcount <= 1'b1;
|
||||||
|
wr_reg_writedata <= 0;
|
||||||
|
wr_reg_byteenable <= {BYTEEN_WIDTH{1'b1}};
|
||||||
|
wr_reg_address <= 0;
|
||||||
|
wr_reg_write <= 1'b0;
|
||||||
|
wr_reg_read <= 1'b0;
|
||||||
|
wr_reg_debugaccess <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
wr_reg_waitrequest <= cmd_waitrequest;
|
||||||
|
|
||||||
|
if (wait_rise) begin
|
||||||
|
wr_reg_writedata <= s0_writedata;
|
||||||
|
wr_reg_byteenable <= s0_byteenable;
|
||||||
|
wr_reg_address <= s0_address;
|
||||||
|
wr_reg_write <= s0_write;
|
||||||
|
wr_reg_read <= s0_read;
|
||||||
|
wr_reg_burstcount <= s0_burstcount;
|
||||||
|
wr_reg_debugaccess <= s0_debugaccess;
|
||||||
|
end
|
||||||
|
|
||||||
|
// stop using the buffer when waitrequest is low
|
||||||
|
if (~cmd_waitrequest)
|
||||||
|
use_reg <= 1'b0;
|
||||||
|
else if (wait_rise) begin
|
||||||
|
use_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
wr_burstcount = s0_burstcount;
|
||||||
|
wr_writedata = s0_writedata;
|
||||||
|
wr_address = s0_address;
|
||||||
|
wr_write = s0_write;
|
||||||
|
wr_read = s0_read;
|
||||||
|
wr_byteenable = s0_byteenable;
|
||||||
|
wr_debugaccess = s0_debugaccess;
|
||||||
|
|
||||||
|
if (use_reg) begin
|
||||||
|
wr_burstcount = wr_reg_burstcount;
|
||||||
|
wr_writedata = wr_reg_writedata;
|
||||||
|
wr_address = wr_reg_address;
|
||||||
|
wr_write = wr_reg_write;
|
||||||
|
wr_read = wr_reg_read;
|
||||||
|
wr_byteenable = wr_reg_byteenable;
|
||||||
|
wr_debugaccess = wr_reg_debugaccess;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Master-Slave Signal Pipeline Stage
|
||||||
|
//
|
||||||
|
// One notable detail is that cmd_waitrequest is deasserted
|
||||||
|
// when this stage is idle. This allows us to make logic
|
||||||
|
// optimizations in the waitrequest pipeline stage.
|
||||||
|
//
|
||||||
|
// Also note that cmd_waitrequest is deasserted during reset,
|
||||||
|
// which is not spec-compliant, but is ok for an internal
|
||||||
|
// signal.
|
||||||
|
// --------------------------------------
|
||||||
|
wire no_command;
|
||||||
|
assign no_command = ~(cmd_read || cmd_write);
|
||||||
|
assign cmd_waitrequest = m0_waitrequest & ~no_command;
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
cmd_burstcount <= 1'b1;
|
||||||
|
cmd_writedata <= 0;
|
||||||
|
cmd_byteenable <= {BYTEEN_WIDTH{1'b1}};
|
||||||
|
cmd_address <= 0;
|
||||||
|
cmd_write <= 1'b0;
|
||||||
|
cmd_read <= 1'b0;
|
||||||
|
cmd_debugaccess <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (~cmd_waitrequest) begin
|
||||||
|
cmd_writedata <= wr_writedata;
|
||||||
|
cmd_byteenable <= wr_byteenable;
|
||||||
|
cmd_address <= wr_address;
|
||||||
|
cmd_write <= wr_write;
|
||||||
|
cmd_read <= wr_read;
|
||||||
|
cmd_burstcount <= wr_burstcount;
|
||||||
|
cmd_debugaccess <= wr_debugaccess;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end // conditional command pipeline
|
||||||
|
else begin
|
||||||
|
|
||||||
|
assign s0_waitrequest = m0_waitrequest;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
cmd_burstcount = s0_burstcount;
|
||||||
|
cmd_writedata = s0_writedata;
|
||||||
|
cmd_address = s0_address;
|
||||||
|
cmd_write = s0_write;
|
||||||
|
cmd_read = s0_read;
|
||||||
|
cmd_byteenable = s0_byteenable;
|
||||||
|
cmd_debugaccess = s0_debugaccess;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign m0_burstcount = cmd_burstcount;
|
||||||
|
assign m0_writedata = cmd_writedata;
|
||||||
|
assign m0_address = cmd_address;
|
||||||
|
assign m0_write = cmd_write;
|
||||||
|
assign m0_read = cmd_read;
|
||||||
|
assign m0_byteenable = cmd_byteenable;
|
||||||
|
assign m0_debugaccess = cmd_debugaccess;
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Response pipeline
|
||||||
|
//
|
||||||
|
// Registers all response signals
|
||||||
|
// --------------------------------------
|
||||||
|
generate if (PIPELINE_RESPONSE == 1) begin
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
rsp_readdatavalid <= 1'b0;
|
||||||
|
rsp_readdata <= 0;
|
||||||
|
rsp_response <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
rsp_readdatavalid <= m0_readdatavalid;
|
||||||
|
rsp_readdata <= m0_readdata;
|
||||||
|
rsp_response <= m0_response;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end // conditional response pipeline
|
||||||
|
else begin
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
rsp_readdatavalid = m0_readdatavalid;
|
||||||
|
rsp_readdata = m0_readdata;
|
||||||
|
rsp_response = m0_response;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign s0_readdatavalid = rsp_readdatavalid;
|
||||||
|
assign s0_readdata = rsp_readdata;
|
||||||
|
assign s0_response = rsp_response;
|
||||||
|
|
||||||
|
endmodule
|
1240
ip/altera/ddr3/altera_avalon_packets_to_master.v
Normal file
1240
ip/altera/ddr3/altera_avalon_packets_to_master.v
Normal file
File diff suppressed because it is too large
Load Diff
915
ip/altera/ddr3/altera_avalon_sc_fifo.v
Normal file
915
ip/altera/ddr3/altera_avalon_sc_fifo.v
Normal file
@ -0,0 +1,915 @@
|
|||||||
|
// -----------------------------------------------------------
|
||||||
|
// Legal Notice: (C)2007 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 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 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.
|
||||||
|
//
|
||||||
|
// Description: Single clock Avalon-ST FIFO.
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
|
||||||
|
//altera message_off 10036
|
||||||
|
module altera_avalon_sc_fifo
|
||||||
|
#(
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Parameters
|
||||||
|
// --------------------------------------------------
|
||||||
|
parameter SYMBOLS_PER_BEAT = 1,
|
||||||
|
parameter BITS_PER_SYMBOL = 8,
|
||||||
|
parameter FIFO_DEPTH = 16,
|
||||||
|
parameter CHANNEL_WIDTH = 0,
|
||||||
|
parameter ERROR_WIDTH = 0,
|
||||||
|
parameter USE_PACKETS = 0,
|
||||||
|
parameter USE_FILL_LEVEL = 0,
|
||||||
|
parameter USE_STORE_FORWARD = 0,
|
||||||
|
parameter USE_ALMOST_FULL_IF = 0,
|
||||||
|
parameter USE_ALMOST_EMPTY_IF = 0,
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Empty latency is defined as the number of cycles
|
||||||
|
// required for a write to deassert the empty flag.
|
||||||
|
// For example, a latency of 1 means that the empty
|
||||||
|
// flag is deasserted on the cycle after a write.
|
||||||
|
//
|
||||||
|
// Another way to think of it is the latency for a
|
||||||
|
// write to propagate to the output.
|
||||||
|
//
|
||||||
|
// An empty latency of 0 implies lookahead, which is
|
||||||
|
// only implemented for the register-based FIFO.
|
||||||
|
// --------------------------------------------------
|
||||||
|
parameter EMPTY_LATENCY = 3,
|
||||||
|
parameter USE_MEMORY_BLOCKS = 1,
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Internal Parameters
|
||||||
|
// --------------------------------------------------
|
||||||
|
parameter DATA_WIDTH = SYMBOLS_PER_BEAT * BITS_PER_SYMBOL,
|
||||||
|
parameter EMPTY_WIDTH = log2ceil(SYMBOLS_PER_BEAT)
|
||||||
|
)
|
||||||
|
(
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Ports
|
||||||
|
// --------------------------------------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
input [DATA_WIDTH-1: 0] in_data,
|
||||||
|
input in_valid,
|
||||||
|
input in_startofpacket,
|
||||||
|
input in_endofpacket,
|
||||||
|
input [((EMPTY_WIDTH>0) ? (EMPTY_WIDTH-1):0) : 0] in_empty,
|
||||||
|
input [((ERROR_WIDTH>0) ? (ERROR_WIDTH-1):0) : 0] in_error,
|
||||||
|
input [((CHANNEL_WIDTH>0) ? (CHANNEL_WIDTH-1):0): 0] in_channel,
|
||||||
|
output in_ready,
|
||||||
|
|
||||||
|
output [DATA_WIDTH-1 : 0] out_data,
|
||||||
|
output reg out_valid,
|
||||||
|
output out_startofpacket,
|
||||||
|
output out_endofpacket,
|
||||||
|
output [((EMPTY_WIDTH>0) ? (EMPTY_WIDTH-1):0) : 0] out_empty,
|
||||||
|
output [((ERROR_WIDTH>0) ? (ERROR_WIDTH-1):0) : 0] out_error,
|
||||||
|
output [((CHANNEL_WIDTH>0) ? (CHANNEL_WIDTH-1):0): 0] out_channel,
|
||||||
|
input out_ready,
|
||||||
|
|
||||||
|
input [(USE_STORE_FORWARD ? 2 : 1) : 0] csr_address,
|
||||||
|
input csr_write,
|
||||||
|
input csr_read,
|
||||||
|
input [31 : 0] csr_writedata,
|
||||||
|
output reg [31 : 0] csr_readdata,
|
||||||
|
|
||||||
|
output wire almost_full_data,
|
||||||
|
output wire almost_empty_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Local Parameters
|
||||||
|
// --------------------------------------------------
|
||||||
|
localparam ADDR_WIDTH = log2ceil(FIFO_DEPTH);
|
||||||
|
localparam DEPTH = FIFO_DEPTH;
|
||||||
|
localparam PKT_SIGNALS_WIDTH = 2 + EMPTY_WIDTH;
|
||||||
|
localparam PAYLOAD_WIDTH = (USE_PACKETS == 1) ?
|
||||||
|
2 + EMPTY_WIDTH + DATA_WIDTH + ERROR_WIDTH + CHANNEL_WIDTH:
|
||||||
|
DATA_WIDTH + ERROR_WIDTH + CHANNEL_WIDTH;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Internal Signals
|
||||||
|
// --------------------------------------------------
|
||||||
|
genvar i;
|
||||||
|
|
||||||
|
reg [PAYLOAD_WIDTH-1 : 0] mem [DEPTH-1 : 0];
|
||||||
|
reg [ADDR_WIDTH-1 : 0] wr_ptr;
|
||||||
|
reg [ADDR_WIDTH-1 : 0] rd_ptr;
|
||||||
|
reg [DEPTH-1 : 0] mem_used;
|
||||||
|
|
||||||
|
wire [ADDR_WIDTH-1 : 0] next_wr_ptr;
|
||||||
|
wire [ADDR_WIDTH-1 : 0] next_rd_ptr;
|
||||||
|
wire [ADDR_WIDTH-1 : 0] incremented_wr_ptr;
|
||||||
|
wire [ADDR_WIDTH-1 : 0] incremented_rd_ptr;
|
||||||
|
|
||||||
|
wire [ADDR_WIDTH-1 : 0] mem_rd_ptr;
|
||||||
|
|
||||||
|
wire read;
|
||||||
|
wire write;
|
||||||
|
|
||||||
|
reg empty;
|
||||||
|
reg next_empty;
|
||||||
|
reg full;
|
||||||
|
reg next_full;
|
||||||
|
|
||||||
|
wire [PKT_SIGNALS_WIDTH-1 : 0] in_packet_signals;
|
||||||
|
wire [PKT_SIGNALS_WIDTH-1 : 0] out_packet_signals;
|
||||||
|
wire [PAYLOAD_WIDTH-1 : 0] in_payload;
|
||||||
|
reg [PAYLOAD_WIDTH-1 : 0] internal_out_payload;
|
||||||
|
reg [PAYLOAD_WIDTH-1 : 0] out_payload;
|
||||||
|
|
||||||
|
reg internal_out_valid;
|
||||||
|
wire internal_out_ready;
|
||||||
|
|
||||||
|
reg [ADDR_WIDTH : 0] fifo_fill_level;
|
||||||
|
reg [ADDR_WIDTH : 0] fill_level;
|
||||||
|
|
||||||
|
reg [ADDR_WIDTH-1 : 0] sop_ptr = 0;
|
||||||
|
wire [ADDR_WIDTH-1 : 0] curr_sop_ptr;
|
||||||
|
reg [23:0] almost_full_threshold;
|
||||||
|
reg [23:0] almost_empty_threshold;
|
||||||
|
reg [23:0] cut_through_threshold;
|
||||||
|
reg [15:0] pkt_cnt;
|
||||||
|
reg drop_on_error_en;
|
||||||
|
reg error_in_pkt;
|
||||||
|
reg pkt_has_started;
|
||||||
|
reg sop_has_left_fifo;
|
||||||
|
reg fifo_too_small_r;
|
||||||
|
reg pkt_cnt_eq_zero;
|
||||||
|
reg pkt_cnt_eq_one;
|
||||||
|
|
||||||
|
wire wait_for_threshold;
|
||||||
|
reg pkt_mode;
|
||||||
|
wire wait_for_pkt;
|
||||||
|
wire ok_to_forward;
|
||||||
|
wire in_pkt_eop_arrive;
|
||||||
|
wire out_pkt_leave;
|
||||||
|
wire in_pkt_start;
|
||||||
|
wire in_pkt_error;
|
||||||
|
wire drop_on_error;
|
||||||
|
wire fifo_too_small;
|
||||||
|
wire out_pkt_sop_leave;
|
||||||
|
wire [31:0] max_fifo_size;
|
||||||
|
reg fifo_fill_level_lt_cut_through_threshold;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Define Payload
|
||||||
|
//
|
||||||
|
// Icky part where we decide which signals form the
|
||||||
|
// payload to the FIFO with generate blocks.
|
||||||
|
// --------------------------------------------------
|
||||||
|
generate
|
||||||
|
if (EMPTY_WIDTH > 0) begin : gen_blk1
|
||||||
|
assign in_packet_signals = {in_startofpacket, in_endofpacket, in_empty};
|
||||||
|
assign {out_startofpacket, out_endofpacket, out_empty} = out_packet_signals;
|
||||||
|
end
|
||||||
|
else begin : gen_blk1_else
|
||||||
|
assign out_empty = in_error;
|
||||||
|
assign in_packet_signals = {in_startofpacket, in_endofpacket};
|
||||||
|
assign {out_startofpacket, out_endofpacket} = out_packet_signals;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (USE_PACKETS) begin : gen_blk2
|
||||||
|
if (ERROR_WIDTH > 0) begin : gen_blk3
|
||||||
|
if (CHANNEL_WIDTH > 0) begin : gen_blk4
|
||||||
|
assign in_payload = {in_packet_signals, in_data, in_error, in_channel};
|
||||||
|
assign {out_packet_signals, out_data, out_error, out_channel} = out_payload;
|
||||||
|
end
|
||||||
|
else begin : gen_blk4_else
|
||||||
|
assign out_channel = in_channel;
|
||||||
|
assign in_payload = {in_packet_signals, in_data, in_error};
|
||||||
|
assign {out_packet_signals, out_data, out_error} = out_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : gen_blk3_else
|
||||||
|
assign out_error = in_error;
|
||||||
|
if (CHANNEL_WIDTH > 0) begin : gen_blk5
|
||||||
|
assign in_payload = {in_packet_signals, in_data, in_channel};
|
||||||
|
assign {out_packet_signals, out_data, out_channel} = out_payload;
|
||||||
|
end
|
||||||
|
else begin : gen_blk5_else
|
||||||
|
assign out_channel = in_channel;
|
||||||
|
assign in_payload = {in_packet_signals, in_data};
|
||||||
|
assign {out_packet_signals, out_data} = out_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : gen_blk2_else
|
||||||
|
assign out_packet_signals = 0;
|
||||||
|
if (ERROR_WIDTH > 0) begin : gen_blk6
|
||||||
|
if (CHANNEL_WIDTH > 0) begin : gen_blk7
|
||||||
|
assign in_payload = {in_data, in_error, in_channel};
|
||||||
|
assign {out_data, out_error, out_channel} = out_payload;
|
||||||
|
end
|
||||||
|
else begin : gen_blk7_else
|
||||||
|
assign out_channel = in_channel;
|
||||||
|
assign in_payload = {in_data, in_error};
|
||||||
|
assign {out_data, out_error} = out_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : gen_blk6_else
|
||||||
|
assign out_error = in_error;
|
||||||
|
if (CHANNEL_WIDTH > 0) begin : gen_blk8
|
||||||
|
assign in_payload = {in_data, in_channel};
|
||||||
|
assign {out_data, out_channel} = out_payload;
|
||||||
|
end
|
||||||
|
else begin : gen_blk8_else
|
||||||
|
assign out_channel = in_channel;
|
||||||
|
assign in_payload = in_data;
|
||||||
|
assign out_data = out_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Memory-based FIFO storage
|
||||||
|
//
|
||||||
|
// To allow a ready latency of 0, the read index is
|
||||||
|
// obtained from the next read pointer and memory
|
||||||
|
// outputs are unregistered.
|
||||||
|
//
|
||||||
|
// If the empty latency is 1, we infer bypass logic
|
||||||
|
// around the memory so writes propagate to the
|
||||||
|
// outputs on the next cycle.
|
||||||
|
//
|
||||||
|
// Do not change the way this is coded: Quartus needs
|
||||||
|
// a perfect match to the template, and any attempt to
|
||||||
|
// refactor the two always blocks into one will break
|
||||||
|
// memory inference.
|
||||||
|
// --------------------------------------------------
|
||||||
|
generate if (USE_MEMORY_BLOCKS == 1) begin : gen_blk9
|
||||||
|
|
||||||
|
if (EMPTY_LATENCY == 1) begin : gen_blk10
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (in_valid && in_ready)
|
||||||
|
mem[wr_ptr] = in_payload;
|
||||||
|
|
||||||
|
internal_out_payload = mem[mem_rd_ptr];
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin : gen_blk10_else
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (in_valid && in_ready)
|
||||||
|
mem[wr_ptr] <= in_payload;
|
||||||
|
|
||||||
|
internal_out_payload <= mem[mem_rd_ptr];
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
assign mem_rd_ptr = next_rd_ptr;
|
||||||
|
|
||||||
|
end else begin : gen_blk9_else
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Register-based FIFO storage
|
||||||
|
//
|
||||||
|
// Uses a shift register as the storage element. Each
|
||||||
|
// shift register slot has a bit which indicates if
|
||||||
|
// the slot is occupied (credit to Sam H for the idea).
|
||||||
|
// The occupancy bits are contiguous and start from the
|
||||||
|
// lsb, so 0000, 0001, 0011, 0111, 1111 for a 4-deep
|
||||||
|
// FIFO.
|
||||||
|
//
|
||||||
|
// Each slot is enabled during a read or when it
|
||||||
|
// is unoccupied. New data is always written to every
|
||||||
|
// going-to-be-empty slot (we keep track of which ones
|
||||||
|
// are actually useful with the occupancy bits). On a
|
||||||
|
// read we shift occupied slots.
|
||||||
|
//
|
||||||
|
// The exception is the last slot, which always gets
|
||||||
|
// new data when it is unoccupied.
|
||||||
|
// --------------------------------------------------
|
||||||
|
for (i = 0; i < DEPTH-1; i = i + 1) begin : shift_reg
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
mem[i] <= 0;
|
||||||
|
end
|
||||||
|
else if (read || !mem_used[i]) begin
|
||||||
|
if (!mem_used[i+1])
|
||||||
|
mem[i] <= in_payload;
|
||||||
|
else
|
||||||
|
mem[i] <= mem[i+1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
mem[DEPTH-1] <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (DEPTH == 1) begin
|
||||||
|
if (write)
|
||||||
|
mem[DEPTH-1] <= in_payload;
|
||||||
|
end
|
||||||
|
else if (!mem_used[DEPTH-1])
|
||||||
|
mem[DEPTH-1] <= in_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign read = internal_out_ready && internal_out_valid && ok_to_forward;
|
||||||
|
assign write = in_ready && in_valid;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Pointer Management
|
||||||
|
// --------------------------------------------------
|
||||||
|
generate if (USE_MEMORY_BLOCKS == 1) begin : gen_blk11
|
||||||
|
|
||||||
|
assign incremented_wr_ptr = wr_ptr + 1'b1;
|
||||||
|
assign incremented_rd_ptr = rd_ptr + 1'b1;
|
||||||
|
assign next_wr_ptr = drop_on_error ? curr_sop_ptr : write ? incremented_wr_ptr : wr_ptr;
|
||||||
|
assign next_rd_ptr = (read) ? incremented_rd_ptr : rd_ptr;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
wr_ptr <= 0;
|
||||||
|
rd_ptr <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
wr_ptr <= next_wr_ptr;
|
||||||
|
rd_ptr <= next_rd_ptr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin : gen_blk11_else
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Shift Register Occupancy Bits
|
||||||
|
//
|
||||||
|
// Consider a 4-deep FIFO with 2 entries: 0011
|
||||||
|
// On a read and write, do not modify the bits.
|
||||||
|
// On a write, left-shift the bits to get 0111.
|
||||||
|
// On a read, right-shift the bits to get 0001.
|
||||||
|
//
|
||||||
|
// Also, on a write we set bit0 (the head), while
|
||||||
|
// clearing the tail on a read.
|
||||||
|
// --------------------------------------------------
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
mem_used[0] <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (write ^ read) begin
|
||||||
|
if (write)
|
||||||
|
mem_used[0] <= 1;
|
||||||
|
else if (read) begin
|
||||||
|
if (DEPTH > 1)
|
||||||
|
mem_used[0] <= mem_used[1];
|
||||||
|
else
|
||||||
|
mem_used[0] <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (DEPTH > 1) begin : gen_blk12
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
mem_used[DEPTH-1] <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (write ^ read) begin
|
||||||
|
mem_used[DEPTH-1] <= 0;
|
||||||
|
if (write)
|
||||||
|
mem_used[DEPTH-1] <= mem_used[DEPTH-2];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for (i = 1; i < DEPTH-1; i = i + 1) begin : storage_logic
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
mem_used[i] <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (write ^ read) begin
|
||||||
|
if (write)
|
||||||
|
mem_used[i] <= mem_used[i-1];
|
||||||
|
else if (read)
|
||||||
|
mem_used[i] <= mem_used[i+1];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Memory FIFO Status Management
|
||||||
|
//
|
||||||
|
// Generates the full and empty signals from the
|
||||||
|
// pointers. The FIFO is full when the next write
|
||||||
|
// pointer will be equal to the read pointer after
|
||||||
|
// a write. Reading from a FIFO clears full.
|
||||||
|
//
|
||||||
|
// The FIFO is empty when the next read pointer will
|
||||||
|
// be equal to the write pointer after a read. Writing
|
||||||
|
// to a FIFO clears empty.
|
||||||
|
//
|
||||||
|
// A simultaneous read and write must not change any of
|
||||||
|
// the empty or full flags unless there is a drop on error event.
|
||||||
|
// --------------------------------------------------
|
||||||
|
generate if (USE_MEMORY_BLOCKS == 1) begin : gen_blk13
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
next_full = full;
|
||||||
|
next_empty = empty;
|
||||||
|
|
||||||
|
if (read && !write) begin
|
||||||
|
next_full = 1'b0;
|
||||||
|
|
||||||
|
if (incremented_rd_ptr == wr_ptr)
|
||||||
|
next_empty = 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (write && !read) begin
|
||||||
|
if (!drop_on_error)
|
||||||
|
next_empty = 1'b0;
|
||||||
|
else if (curr_sop_ptr == rd_ptr) // drop on error and only 1 pkt in fifo
|
||||||
|
next_empty = 1'b1;
|
||||||
|
|
||||||
|
if (incremented_wr_ptr == rd_ptr && !drop_on_error)
|
||||||
|
next_full = 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (write && read && drop_on_error) begin
|
||||||
|
if (curr_sop_ptr == next_rd_ptr)
|
||||||
|
next_empty = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
empty <= 1;
|
||||||
|
full <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
empty <= next_empty;
|
||||||
|
full <= next_full;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin : gen_blk13_else
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Register FIFO Status Management
|
||||||
|
//
|
||||||
|
// Full when the tail occupancy bit is 1. Empty when
|
||||||
|
// the head occupancy bit is 0.
|
||||||
|
// --------------------------------------------------
|
||||||
|
always @* begin
|
||||||
|
full = mem_used[DEPTH-1];
|
||||||
|
empty = !mem_used[0];
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// For a single slot FIFO, reading clears the
|
||||||
|
// full status immediately.
|
||||||
|
// ------------------------------------------
|
||||||
|
if (DEPTH == 1)
|
||||||
|
full = mem_used[0] && !read;
|
||||||
|
|
||||||
|
internal_out_payload = mem[0];
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Writes clear empty immediately for lookahead modes.
|
||||||
|
// Note that we use in_valid instead of write to avoid
|
||||||
|
// combinational loops (in lookahead mode, qualifying
|
||||||
|
// with in_ready is meaningless).
|
||||||
|
//
|
||||||
|
// In a 1-deep FIFO, a possible combinational loop runs
|
||||||
|
// from write -> out_valid -> out_ready -> write
|
||||||
|
// ------------------------------------------
|
||||||
|
if (EMPTY_LATENCY == 0) begin
|
||||||
|
empty = !mem_used[0] && !in_valid;
|
||||||
|
|
||||||
|
if (!mem_used[0] && in_valid)
|
||||||
|
internal_out_payload = in_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Avalon-ST Signals
|
||||||
|
//
|
||||||
|
// The in_ready signal is straightforward.
|
||||||
|
//
|
||||||
|
// To match memory latency when empty latency > 1,
|
||||||
|
// out_valid assertions must be delayed by one clock
|
||||||
|
// cycle.
|
||||||
|
//
|
||||||
|
// Note: out_valid deassertions must not be delayed or
|
||||||
|
// the FIFO will underflow.
|
||||||
|
// --------------------------------------------------
|
||||||
|
assign in_ready = !full;
|
||||||
|
assign internal_out_ready = out_ready || !out_valid;
|
||||||
|
|
||||||
|
generate if (EMPTY_LATENCY > 1) begin : gen_blk14
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
internal_out_valid <= 0;
|
||||||
|
else begin
|
||||||
|
internal_out_valid <= !empty & ok_to_forward & ~drop_on_error;
|
||||||
|
|
||||||
|
if (read) begin
|
||||||
|
if (incremented_rd_ptr == wr_ptr)
|
||||||
|
internal_out_valid <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin : gen_blk14_else
|
||||||
|
always @* begin
|
||||||
|
internal_out_valid = !empty & ok_to_forward;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Single Output Pipeline Stage
|
||||||
|
//
|
||||||
|
// This output pipeline stage is enabled if the FIFO's
|
||||||
|
// empty latency is set to 3 (default). It is disabled
|
||||||
|
// for all other allowed latencies.
|
||||||
|
//
|
||||||
|
// Reason: The memory outputs are unregistered, so we have to
|
||||||
|
// register the output or fmax will drop if combinatorial
|
||||||
|
// logic is present on the output datapath.
|
||||||
|
//
|
||||||
|
// Q: The Avalon-ST spec says that I have to register my outputs
|
||||||
|
// But isn't the memory counted as a register?
|
||||||
|
// A: The path from the address lookup to the memory output is
|
||||||
|
// slow. Registering the memory outputs is a good idea.
|
||||||
|
//
|
||||||
|
// The registers get packed into the memory by the fitter
|
||||||
|
// which means minimal resources are consumed (the result
|
||||||
|
// is a altsyncram with registered outputs, available on
|
||||||
|
// all modern Altera devices).
|
||||||
|
//
|
||||||
|
// This output stage acts as an extra slot in the FIFO,
|
||||||
|
// and complicates the fill level.
|
||||||
|
// --------------------------------------------------
|
||||||
|
generate if (EMPTY_LATENCY == 3) begin : gen_blk15
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
out_valid <= 0;
|
||||||
|
out_payload <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (internal_out_ready) begin
|
||||||
|
out_valid <= internal_out_valid & ok_to_forward;
|
||||||
|
out_payload <= internal_out_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : gen_blk15_else
|
||||||
|
always @* begin
|
||||||
|
out_valid = internal_out_valid;
|
||||||
|
out_payload = internal_out_payload;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Fill Level
|
||||||
|
//
|
||||||
|
// The fill level is calculated from the next write
|
||||||
|
// and read pointers to avoid unnecessary latency
|
||||||
|
// and logic.
|
||||||
|
//
|
||||||
|
// However, if the store-and-forward mode of the FIFO
|
||||||
|
// is enabled, the fill level is an up-down counter
|
||||||
|
// for fmax optimization reasons.
|
||||||
|
//
|
||||||
|
// If the output pipeline is enabled, the fill level
|
||||||
|
// must account for it, or we'll always be off by one.
|
||||||
|
// This may, or may not be important depending on the
|
||||||
|
// application.
|
||||||
|
//
|
||||||
|
// For now, we'll always calculate the exact fill level
|
||||||
|
// at the cost of an extra adder when the output stage
|
||||||
|
// is enabled.
|
||||||
|
// --------------------------------------------------
|
||||||
|
generate if (USE_FILL_LEVEL) begin : gen_blk16
|
||||||
|
wire [31:0] depth32;
|
||||||
|
assign depth32 = DEPTH;
|
||||||
|
|
||||||
|
if (USE_STORE_FORWARD) begin
|
||||||
|
|
||||||
|
reg [ADDR_WIDTH : 0] curr_packet_len_less_one;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// We only drop on endofpacket. As long as we don't add to the fill
|
||||||
|
// level on the dropped endofpacket cycle, we can simply subtract
|
||||||
|
// (packet length - 1) from the fill level for dropped packets.
|
||||||
|
// --------------------------------------------------
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
curr_packet_len_less_one <= 0;
|
||||||
|
end else begin
|
||||||
|
if (write) begin
|
||||||
|
curr_packet_len_less_one <= curr_packet_len_less_one + 1'b1;
|
||||||
|
if (in_endofpacket)
|
||||||
|
curr_packet_len_less_one <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
fifo_fill_level <= 0;
|
||||||
|
end else if (drop_on_error) begin
|
||||||
|
fifo_fill_level <= fifo_fill_level - curr_packet_len_less_one;
|
||||||
|
if (read)
|
||||||
|
fifo_fill_level <= fifo_fill_level - curr_packet_len_less_one - 1'b1;
|
||||||
|
end else if (write && !read) begin
|
||||||
|
fifo_fill_level <= fifo_fill_level + 1'b1;
|
||||||
|
end else if (read && !write) begin
|
||||||
|
fifo_fill_level <= fifo_fill_level - 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
fifo_fill_level <= 0;
|
||||||
|
else if (next_full & !drop_on_error)
|
||||||
|
fifo_fill_level <= depth32[ADDR_WIDTH:0];
|
||||||
|
else begin
|
||||||
|
fifo_fill_level[ADDR_WIDTH] <= 1'b0;
|
||||||
|
fifo_fill_level[ADDR_WIDTH-1 : 0] <= next_wr_ptr - next_rd_ptr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
fill_level = fifo_fill_level;
|
||||||
|
|
||||||
|
if (EMPTY_LATENCY == 3)
|
||||||
|
fill_level = fifo_fill_level + {{ADDR_WIDTH{1'b0}}, out_valid};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : gen_blk16_else
|
||||||
|
always @* begin
|
||||||
|
fill_level = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate if (USE_ALMOST_FULL_IF) begin : gen_blk17
|
||||||
|
assign almost_full_data = (fill_level >= almost_full_threshold);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
assign almost_full_data = 0;
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate if (USE_ALMOST_EMPTY_IF) begin : gen_blk18
|
||||||
|
assign almost_empty_data = (fill_level <= almost_empty_threshold);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
assign almost_empty_data = 0;
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Avalon-MM Status & Control Connection Point
|
||||||
|
//
|
||||||
|
// Register map:
|
||||||
|
//
|
||||||
|
// | Addr | RW | 31 - 0 |
|
||||||
|
// | 0 | R | Fill level |
|
||||||
|
//
|
||||||
|
// The registering of this connection point means
|
||||||
|
// that there is a cycle of latency between
|
||||||
|
// reads/writes and the updating of the fill level.
|
||||||
|
// --------------------------------------------------
|
||||||
|
generate if (USE_STORE_FORWARD) begin : gen_blk19
|
||||||
|
assign max_fifo_size = FIFO_DEPTH - 1;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
almost_full_threshold <= max_fifo_size[23 : 0];
|
||||||
|
almost_empty_threshold <= 0;
|
||||||
|
cut_through_threshold <= 0;
|
||||||
|
drop_on_error_en <= 0;
|
||||||
|
csr_readdata <= 0;
|
||||||
|
pkt_mode <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (csr_read) begin
|
||||||
|
csr_readdata <= 32'b0;
|
||||||
|
if (csr_address == 5)
|
||||||
|
csr_readdata <= {31'b0, drop_on_error_en};
|
||||||
|
else if (csr_address == 4)
|
||||||
|
csr_readdata <= {8'b0, cut_through_threshold};
|
||||||
|
else if (csr_address == 3)
|
||||||
|
csr_readdata <= {8'b0, almost_empty_threshold};
|
||||||
|
else if (csr_address == 2)
|
||||||
|
csr_readdata <= {8'b0, almost_full_threshold};
|
||||||
|
else if (csr_address == 0)
|
||||||
|
csr_readdata <= {{(31 - ADDR_WIDTH){1'b0}}, fill_level};
|
||||||
|
end
|
||||||
|
else if (csr_write) begin
|
||||||
|
if(csr_address == 3'b101)
|
||||||
|
drop_on_error_en <= csr_writedata[0];
|
||||||
|
else if(csr_address == 3'b100) begin
|
||||||
|
cut_through_threshold <= csr_writedata[23:0];
|
||||||
|
pkt_mode <= (csr_writedata[23:0] == 0);
|
||||||
|
end
|
||||||
|
else if(csr_address == 3'b011)
|
||||||
|
almost_empty_threshold <= csr_writedata[23:0];
|
||||||
|
else if(csr_address == 3'b010)
|
||||||
|
almost_full_threshold <= csr_writedata[23:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if (USE_ALMOST_FULL_IF || USE_ALMOST_EMPTY_IF) begin : gen_blk19_else1
|
||||||
|
assign max_fifo_size = FIFO_DEPTH - 1;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
almost_full_threshold <= max_fifo_size[23 : 0];
|
||||||
|
almost_empty_threshold <= 0;
|
||||||
|
csr_readdata <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (csr_read) begin
|
||||||
|
csr_readdata <= 32'b0;
|
||||||
|
if (csr_address == 3)
|
||||||
|
csr_readdata <= {8'b0, almost_empty_threshold};
|
||||||
|
else if (csr_address == 2)
|
||||||
|
csr_readdata <= {8'b0, almost_full_threshold};
|
||||||
|
else if (csr_address == 0)
|
||||||
|
csr_readdata <= {{(31 - ADDR_WIDTH){1'b0}}, fill_level};
|
||||||
|
end
|
||||||
|
else if (csr_write) begin
|
||||||
|
if(csr_address == 3'b011)
|
||||||
|
almost_empty_threshold <= csr_writedata[23:0];
|
||||||
|
else if(csr_address == 3'b010)
|
||||||
|
almost_full_threshold <= csr_writedata[23:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : gen_blk19_else2
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
csr_readdata <= 0;
|
||||||
|
end
|
||||||
|
else if (csr_read) begin
|
||||||
|
csr_readdata <= 0;
|
||||||
|
|
||||||
|
if (csr_address == 0)
|
||||||
|
csr_readdata <= {{(31 - ADDR_WIDTH){1'b0}}, fill_level};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Store and forward logic
|
||||||
|
// --------------------------------------------------
|
||||||
|
// if the fifo gets full before the entire packet or the
|
||||||
|
// cut-threshold condition is met then start sending out
|
||||||
|
// data in order to avoid dead-lock situation
|
||||||
|
|
||||||
|
generate if (USE_STORE_FORWARD) begin : gen_blk20
|
||||||
|
assign wait_for_threshold = (fifo_fill_level_lt_cut_through_threshold) & wait_for_pkt ;
|
||||||
|
assign wait_for_pkt = pkt_cnt_eq_zero | (pkt_cnt_eq_one & out_pkt_leave);
|
||||||
|
assign ok_to_forward = (pkt_mode ? (~wait_for_pkt | ~pkt_has_started) :
|
||||||
|
~wait_for_threshold) | fifo_too_small_r;
|
||||||
|
assign in_pkt_eop_arrive = in_valid & in_ready & in_endofpacket;
|
||||||
|
assign in_pkt_start = in_valid & in_ready & in_startofpacket;
|
||||||
|
assign in_pkt_error = in_valid & in_ready & |in_error;
|
||||||
|
assign out_pkt_sop_leave = out_valid & out_ready & out_startofpacket;
|
||||||
|
assign out_pkt_leave = out_valid & out_ready & out_endofpacket;
|
||||||
|
assign fifo_too_small = (pkt_mode ? wait_for_pkt : wait_for_threshold) & full & out_ready;
|
||||||
|
|
||||||
|
// count packets coming and going into the fifo
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
pkt_cnt <= 0;
|
||||||
|
pkt_has_started <= 0;
|
||||||
|
sop_has_left_fifo <= 0;
|
||||||
|
fifo_too_small_r <= 0;
|
||||||
|
pkt_cnt_eq_zero <= 1'b1;
|
||||||
|
pkt_cnt_eq_one <= 1'b0;
|
||||||
|
fifo_fill_level_lt_cut_through_threshold <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
fifo_fill_level_lt_cut_through_threshold <= fifo_fill_level < cut_through_threshold;
|
||||||
|
fifo_too_small_r <= fifo_too_small;
|
||||||
|
|
||||||
|
if( in_pkt_eop_arrive )
|
||||||
|
sop_has_left_fifo <= 1'b0;
|
||||||
|
else if (out_pkt_sop_leave & pkt_cnt_eq_zero )
|
||||||
|
sop_has_left_fifo <= 1'b1;
|
||||||
|
|
||||||
|
if (in_pkt_eop_arrive & ~out_pkt_leave & ~drop_on_error ) begin
|
||||||
|
pkt_cnt <= pkt_cnt + 1'b1;
|
||||||
|
pkt_cnt_eq_zero <= 0;
|
||||||
|
if (pkt_cnt == 0)
|
||||||
|
pkt_cnt_eq_one <= 1'b1;
|
||||||
|
else
|
||||||
|
pkt_cnt_eq_one <= 1'b0;
|
||||||
|
end
|
||||||
|
else if((~in_pkt_eop_arrive | drop_on_error) & out_pkt_leave) begin
|
||||||
|
pkt_cnt <= pkt_cnt - 1'b1;
|
||||||
|
if (pkt_cnt == 1)
|
||||||
|
pkt_cnt_eq_zero <= 1'b1;
|
||||||
|
else
|
||||||
|
pkt_cnt_eq_zero <= 1'b0;
|
||||||
|
if (pkt_cnt == 2)
|
||||||
|
pkt_cnt_eq_one <= 1'b1;
|
||||||
|
else
|
||||||
|
pkt_cnt_eq_one <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (in_pkt_start)
|
||||||
|
pkt_has_started <= 1'b1;
|
||||||
|
else if (in_pkt_eop_arrive)
|
||||||
|
pkt_has_started <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// drop on error logic
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
sop_ptr <= 0;
|
||||||
|
error_in_pkt <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
// save the location of the SOP
|
||||||
|
if ( in_pkt_start )
|
||||||
|
sop_ptr <= wr_ptr;
|
||||||
|
|
||||||
|
// remember if error in pkt
|
||||||
|
// log error only if packet has already started
|
||||||
|
if (in_pkt_eop_arrive)
|
||||||
|
error_in_pkt <= 1'b0;
|
||||||
|
else if ( in_pkt_error & (pkt_has_started | in_pkt_start))
|
||||||
|
error_in_pkt <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign drop_on_error = drop_on_error_en & (error_in_pkt | in_pkt_error) & in_pkt_eop_arrive &
|
||||||
|
~sop_has_left_fifo & ~(out_pkt_sop_leave & pkt_cnt_eq_zero);
|
||||||
|
|
||||||
|
assign curr_sop_ptr = (write && in_startofpacket && in_endofpacket) ? wr_ptr : sop_ptr;
|
||||||
|
|
||||||
|
end
|
||||||
|
else begin : gen_blk20_else
|
||||||
|
assign ok_to_forward = 1'b1;
|
||||||
|
assign drop_on_error = 1'b0;
|
||||||
|
if (ADDR_WIDTH <= 1)
|
||||||
|
assign curr_sop_ptr = 1'b0;
|
||||||
|
else
|
||||||
|
assign curr_sop_ptr = {ADDR_WIDTH - 1 { 1'b0 }};
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Calculates the log2ceil of the input value
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input integer val;
|
||||||
|
reg[31:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i[30:0] << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
210
ip/altera/ddr3/altera_avalon_st_bytes_to_packets.v
Normal file
210
ip/altera/ddr3/altera_avalon_st_bytes_to_packets.v
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon ST Bytes to Packet
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
module altera_avalon_st_bytes_to_packets
|
||||||
|
//if ENCODING ==0, CHANNEL_WIDTH must be 8
|
||||||
|
//else CHANNEL_WIDTH can be from 0 to 127
|
||||||
|
#( parameter CHANNEL_WIDTH = 8,
|
||||||
|
parameter ENCODING = 0 )
|
||||||
|
(
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
input reset_n,
|
||||||
|
// Interface: ST out with packets
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [7: 0] out_data,
|
||||||
|
output reg [CHANNEL_WIDTH-1: 0] out_channel,
|
||||||
|
output reg out_startofpacket,
|
||||||
|
output reg out_endofpacket,
|
||||||
|
|
||||||
|
// Interface: ST in
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [7: 0] in_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Signal Declarations
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
reg received_esc, received_channel, received_varchannel;
|
||||||
|
wire escape_char, sop_char, eop_char, channel_char, varchannelesc_char;
|
||||||
|
|
||||||
|
// data out mux.
|
||||||
|
// we need it twice (data & channel out), so use a wire here
|
||||||
|
wire [7:0] data_out;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Thingofamagick
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
assign sop_char = (in_data == 8'h7a);
|
||||||
|
assign eop_char = (in_data == 8'h7b);
|
||||||
|
assign channel_char = (in_data == 8'h7c);
|
||||||
|
assign escape_char = (in_data == 8'h7d);
|
||||||
|
|
||||||
|
assign data_out = received_esc ? (in_data ^ 8'h20) : in_data;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (CHANNEL_WIDTH == 0) begin
|
||||||
|
// Synchorous block -- reset and registers
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
received_esc <= 0;
|
||||||
|
out_startofpacket <= 0;
|
||||||
|
out_endofpacket <= 0;
|
||||||
|
end else begin
|
||||||
|
// we take data when in_valid and in_ready
|
||||||
|
if (in_valid & in_ready) begin
|
||||||
|
if (received_esc) begin
|
||||||
|
//if we got esc char, after next byte is consumed, quit esc mode
|
||||||
|
if (out_ready) received_esc <= 0;
|
||||||
|
end else begin
|
||||||
|
if (escape_char) received_esc <= 1;
|
||||||
|
if (sop_char) out_startofpacket <= 1;
|
||||||
|
if (eop_char) out_endofpacket <= 1;
|
||||||
|
end
|
||||||
|
if (out_ready & out_valid) begin
|
||||||
|
out_startofpacket <= 0;
|
||||||
|
out_endofpacket <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Combinational block for in_ready and out_valid
|
||||||
|
always @* begin
|
||||||
|
//we choose not to pipeline here. We can process special characters when
|
||||||
|
//in_ready, but in a chain of microcores, backpressure path is usually
|
||||||
|
//time critical, so we keep it simple here.
|
||||||
|
in_ready = out_ready;
|
||||||
|
|
||||||
|
//out_valid when in_valid, except when we are processing the special
|
||||||
|
//characters. However, if we are in escape received mode, then we are
|
||||||
|
//valid
|
||||||
|
out_valid = 0;
|
||||||
|
if ((out_ready | ~out_valid) && in_valid) begin
|
||||||
|
out_valid = 1;
|
||||||
|
if (sop_char | eop_char | escape_char | channel_char) out_valid = 0;
|
||||||
|
end
|
||||||
|
out_data = data_out;
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
assign varchannelesc_char = in_data[7];
|
||||||
|
// Synchorous block -- reset and registers
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
received_esc <= 0;
|
||||||
|
received_channel <= 0;
|
||||||
|
received_varchannel <= 0;
|
||||||
|
out_startofpacket <= 0;
|
||||||
|
out_endofpacket <= 0;
|
||||||
|
end else begin
|
||||||
|
// we take data when in_valid and in_ready
|
||||||
|
if (in_valid & in_ready) begin
|
||||||
|
if (received_esc) begin
|
||||||
|
//if we got esc char, after next byte is consumed, quit esc mode
|
||||||
|
if (out_ready | received_channel | received_varchannel) received_esc <= 0;
|
||||||
|
end else begin
|
||||||
|
if (escape_char) received_esc <= 1;
|
||||||
|
if (sop_char) out_startofpacket <= 1;
|
||||||
|
if (eop_char) out_endofpacket <= 1;
|
||||||
|
if (channel_char & ENCODING ) received_varchannel <= 1;
|
||||||
|
if (channel_char & ~ENCODING) received_channel <= 1;
|
||||||
|
end
|
||||||
|
if (received_channel & (received_esc | (~sop_char & ~eop_char & ~escape_char & ~channel_char ))) begin
|
||||||
|
received_channel <= 0;
|
||||||
|
end
|
||||||
|
if (received_varchannel & ~varchannelesc_char & (received_esc | (~sop_char & ~eop_char & ~escape_char & ~channel_char))) begin
|
||||||
|
received_varchannel <= 0;
|
||||||
|
end
|
||||||
|
if (out_ready & out_valid) begin
|
||||||
|
out_startofpacket <= 0;
|
||||||
|
out_endofpacket <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Combinational block for in_ready and out_valid
|
||||||
|
always @* begin
|
||||||
|
in_ready = out_ready;
|
||||||
|
out_valid = 0;
|
||||||
|
if ((out_ready | ~out_valid) && in_valid) begin
|
||||||
|
out_valid = 1;
|
||||||
|
if (received_esc) begin
|
||||||
|
if (received_channel | received_varchannel) out_valid = 0;
|
||||||
|
end else begin
|
||||||
|
if (sop_char | eop_char | escape_char | channel_char | received_channel | received_varchannel) out_valid = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
out_data = data_out;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// Channel block
|
||||||
|
generate
|
||||||
|
if (CHANNEL_WIDTH == 0) begin
|
||||||
|
always @(posedge clk) begin
|
||||||
|
out_channel <= 'h0;
|
||||||
|
end
|
||||||
|
|
||||||
|
end else if (CHANNEL_WIDTH < 8) begin
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
out_channel <= 'h0;
|
||||||
|
end else begin
|
||||||
|
if (in_ready & in_valid) begin
|
||||||
|
if ((channel_char & ENCODING) & (~received_esc & ~sop_char & ~eop_char & ~escape_char )) begin
|
||||||
|
out_channel <= 'h0;
|
||||||
|
end else if (received_varchannel & (received_esc | (~sop_char & ~eop_char & ~escape_char & ~channel_char & ~received_channel))) begin
|
||||||
|
// Shifting out only the required bits
|
||||||
|
out_channel[CHANNEL_WIDTH-1:0] <= data_out[CHANNEL_WIDTH-1:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
out_channel <= 'h0;
|
||||||
|
end else begin
|
||||||
|
if (in_ready & in_valid) begin
|
||||||
|
if (received_channel & (received_esc | (~sop_char & ~eop_char & ~escape_char & ~channel_char))) begin
|
||||||
|
out_channel <= data_out;
|
||||||
|
end else if ((channel_char & ENCODING) & (~received_esc & ~sop_char & ~eop_char & ~escape_char )) begin
|
||||||
|
// Variable Channel Encoding always setting to 0 before begin to shift the channel in
|
||||||
|
out_channel <= 'h0;
|
||||||
|
end else if (received_varchannel & (received_esc | (~sop_char & ~eop_char & ~escape_char & ~channel_char & ~received_channel))) begin
|
||||||
|
// Shifting out the lower 7 bits
|
||||||
|
out_channel <= out_channel <<7;
|
||||||
|
out_channel[6:0] <= data_out[6:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
141
ip/altera/ddr3/altera_avalon_st_clock_crosser.v
Normal file
141
ip/altera/ddr3/altera_avalon_st_clock_crosser.v
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $File: //acds/rel/15.1/ip/avalon_st/altera_avalon_st_handshake_clock_crosser/altera_avalon_st_clock_crosser.v $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 1ns
|
||||||
|
|
||||||
|
module altera_avalon_st_clock_crosser(
|
||||||
|
in_clk,
|
||||||
|
in_reset,
|
||||||
|
in_ready,
|
||||||
|
in_valid,
|
||||||
|
in_data,
|
||||||
|
out_clk,
|
||||||
|
out_reset,
|
||||||
|
out_ready,
|
||||||
|
out_valid,
|
||||||
|
out_data
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter SYMBOLS_PER_BEAT = 1;
|
||||||
|
parameter BITS_PER_SYMBOL = 8;
|
||||||
|
parameter FORWARD_SYNC_DEPTH = 2;
|
||||||
|
parameter BACKWARD_SYNC_DEPTH = 2;
|
||||||
|
parameter USE_OUTPUT_PIPELINE = 1;
|
||||||
|
|
||||||
|
localparam DATA_WIDTH = SYMBOLS_PER_BEAT * BITS_PER_SYMBOL;
|
||||||
|
|
||||||
|
input in_clk;
|
||||||
|
input in_reset;
|
||||||
|
output in_ready;
|
||||||
|
input in_valid;
|
||||||
|
input [DATA_WIDTH-1:0] in_data;
|
||||||
|
|
||||||
|
input out_clk;
|
||||||
|
input out_reset;
|
||||||
|
input out_ready;
|
||||||
|
output out_valid;
|
||||||
|
output [DATA_WIDTH-1:0] out_data;
|
||||||
|
|
||||||
|
// Data is guaranteed valid by control signal clock crossing. Cut data
|
||||||
|
// buffer false path.
|
||||||
|
(* altera_attribute = {"-name SUPPRESS_DA_RULE_INTERNAL \"D101,D102\""} *) reg [DATA_WIDTH-1:0] in_data_buffer;
|
||||||
|
reg [DATA_WIDTH-1:0] out_data_buffer;
|
||||||
|
|
||||||
|
reg in_data_toggle;
|
||||||
|
wire in_data_toggle_returned;
|
||||||
|
wire out_data_toggle;
|
||||||
|
reg out_data_toggle_flopped;
|
||||||
|
|
||||||
|
wire take_in_data;
|
||||||
|
wire out_data_taken;
|
||||||
|
|
||||||
|
wire out_valid_internal;
|
||||||
|
wire out_ready_internal;
|
||||||
|
|
||||||
|
assign in_ready = ~(in_data_toggle_returned ^ in_data_toggle);
|
||||||
|
assign take_in_data = in_valid & in_ready;
|
||||||
|
assign out_valid_internal = out_data_toggle ^ out_data_toggle_flopped;
|
||||||
|
assign out_data_taken = out_ready_internal & out_valid_internal;
|
||||||
|
|
||||||
|
always @(posedge in_clk or posedge in_reset) begin
|
||||||
|
if (in_reset) begin
|
||||||
|
in_data_buffer <= {DATA_WIDTH{1'b0}};
|
||||||
|
in_data_toggle <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (take_in_data) begin
|
||||||
|
in_data_toggle <= ~in_data_toggle;
|
||||||
|
in_data_buffer <= in_data;
|
||||||
|
end
|
||||||
|
end //in_reset
|
||||||
|
end //in_clk always block
|
||||||
|
|
||||||
|
always @(posedge out_clk or posedge out_reset) begin
|
||||||
|
if (out_reset) begin
|
||||||
|
out_data_toggle_flopped <= 1'b0;
|
||||||
|
out_data_buffer <= {DATA_WIDTH{1'b0}};
|
||||||
|
end else begin
|
||||||
|
out_data_buffer <= in_data_buffer;
|
||||||
|
if (out_data_taken) begin
|
||||||
|
out_data_toggle_flopped <= out_data_toggle;
|
||||||
|
end
|
||||||
|
end //end if
|
||||||
|
end //out_clk always block
|
||||||
|
|
||||||
|
altera_std_synchronizer_nocut #(.depth(FORWARD_SYNC_DEPTH)) in_to_out_synchronizer (
|
||||||
|
.clk(out_clk),
|
||||||
|
.reset_n(~out_reset),
|
||||||
|
.din(in_data_toggle),
|
||||||
|
.dout(out_data_toggle)
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_std_synchronizer_nocut #(.depth(BACKWARD_SYNC_DEPTH)) out_to_in_synchronizer (
|
||||||
|
.clk(in_clk),
|
||||||
|
.reset_n(~in_reset),
|
||||||
|
.din(out_data_toggle_flopped),
|
||||||
|
.dout(in_data_toggle_returned)
|
||||||
|
);
|
||||||
|
|
||||||
|
generate if (USE_OUTPUT_PIPELINE == 1) begin
|
||||||
|
|
||||||
|
altera_avalon_st_pipeline_base
|
||||||
|
#(
|
||||||
|
.BITS_PER_SYMBOL(BITS_PER_SYMBOL),
|
||||||
|
.SYMBOLS_PER_BEAT(SYMBOLS_PER_BEAT)
|
||||||
|
) output_stage (
|
||||||
|
.clk(out_clk),
|
||||||
|
.reset(out_reset),
|
||||||
|
.in_ready(out_ready_internal),
|
||||||
|
.in_valid(out_valid_internal),
|
||||||
|
.in_data(out_data_buffer),
|
||||||
|
.out_ready(out_ready),
|
||||||
|
.out_valid(out_valid),
|
||||||
|
.out_data(out_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
assign out_valid = out_valid_internal;
|
||||||
|
assign out_ready_internal = out_ready;
|
||||||
|
assign out_data = out_data_buffer;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
72
ip/altera/ddr3/altera_avalon_st_idle_inserter.v
Normal file
72
ip/altera/ddr3/altera_avalon_st_idle_inserter.v
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon ST Idle Inserter
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
module altera_avalon_st_idle_inserter (
|
||||||
|
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
input reset_n,
|
||||||
|
// Interface: ST in
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [7: 0] in_data,
|
||||||
|
|
||||||
|
// Interface: ST out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [7: 0] out_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Signal Declarations
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
reg received_esc;
|
||||||
|
wire escape_char, idle_char;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Thingofamagick
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
assign idle_char = (in_data == 8'h4a);
|
||||||
|
assign escape_char = (in_data == 8'h4d);
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
received_esc <= 0;
|
||||||
|
end else begin
|
||||||
|
if (in_valid & out_ready) begin
|
||||||
|
if ((idle_char | escape_char) & ~received_esc & out_ready) begin
|
||||||
|
received_esc <= 1;
|
||||||
|
end else begin
|
||||||
|
received_esc <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
//we are always valid
|
||||||
|
out_valid = 1'b1;
|
||||||
|
in_ready = out_ready & (~in_valid | ((~idle_char & ~escape_char) | received_esc));
|
||||||
|
out_data = (~in_valid) ? 8'h4a : //if input is not valid, insert idle
|
||||||
|
(received_esc) ? in_data ^ 8'h20 : //escaped once, send data XOR'd
|
||||||
|
(idle_char | escape_char) ? 8'h4d : //input needs escaping, send escape_char
|
||||||
|
in_data; //send data
|
||||||
|
end
|
||||||
|
endmodule
|
70
ip/altera/ddr3/altera_avalon_st_idle_remover.v
Normal file
70
ip/altera/ddr3/altera_avalon_st_idle_remover.v
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon ST Idle Remover
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
module altera_avalon_st_idle_remover (
|
||||||
|
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
input reset_n,
|
||||||
|
// Interface: ST in
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [7: 0] in_data,
|
||||||
|
|
||||||
|
// Interface: ST out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [7: 0] out_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Signal Declarations
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
reg received_esc;
|
||||||
|
wire escape_char, idle_char;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Thingofamagick
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
assign idle_char = (in_data == 8'h4a);
|
||||||
|
assign escape_char = (in_data == 8'h4d);
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
received_esc <= 0;
|
||||||
|
end else begin
|
||||||
|
if (in_valid & in_ready) begin
|
||||||
|
if (escape_char & ~received_esc) begin
|
||||||
|
received_esc <= 1;
|
||||||
|
end else if (out_valid) begin
|
||||||
|
received_esc <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
in_ready = out_ready;
|
||||||
|
//out valid when in_valid. Except when we get idle or escape
|
||||||
|
//however, if we have received an escape character, then we are valid
|
||||||
|
out_valid = in_valid & ~idle_char & (received_esc | ~escape_char);
|
||||||
|
out_data = received_esc ? (in_data ^ 8'h20) : in_data;
|
||||||
|
end
|
||||||
|
endmodule
|
14
ip/altera/ddr3/altera_avalon_st_jtag_interface.sdc
Normal file
14
ip/altera/ddr3/altera_avalon_st_jtag_interface.sdc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
set_false_path -from [get_registers *altera_jtag_src_crosser:*|sink_data_buffer*] -to [get_registers *altera_jtag_src_crosser:*|src_data*]
|
224
ip/altera/ddr3/altera_avalon_st_jtag_interface.v
Normal file
224
ip/altera/ddr3/altera_avalon_st_jtag_interface.v
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// This top level module chooses between the original Altera-ST JTAG Interface
|
||||||
|
// component in ACDS version 8.1 and before, and the new one with the PLI
|
||||||
|
// Simulation mode turned on, which adds a wrapper over the original component.
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_avalon_st_jtag_interface #(
|
||||||
|
parameter PURPOSE = 0, // for discovery of services behind this JTAG Phy - 0
|
||||||
|
// for JTAG Phy, 1 for Packets to Master
|
||||||
|
parameter UPSTREAM_FIFO_SIZE = 0,
|
||||||
|
parameter DOWNSTREAM_FIFO_SIZE = 0,
|
||||||
|
parameter MGMT_CHANNEL_WIDTH = -1,
|
||||||
|
parameter EXPORT_JTAG = 0,
|
||||||
|
parameter USE_PLI = 0, // set to 1 enable PLI Simulation Mode
|
||||||
|
parameter PLI_PORT = 50000 // PLI Simulation Port
|
||||||
|
) (
|
||||||
|
input wire jtag_tck,
|
||||||
|
input wire jtag_tms,
|
||||||
|
input wire jtag_tdi,
|
||||||
|
output wire jtag_tdo,
|
||||||
|
input wire jtag_ena,
|
||||||
|
input wire jtag_usr1,
|
||||||
|
input wire jtag_clr,
|
||||||
|
input wire jtag_clrn,
|
||||||
|
input wire jtag_state_tlr,
|
||||||
|
input wire jtag_state_rti,
|
||||||
|
input wire jtag_state_sdrs,
|
||||||
|
input wire jtag_state_cdr,
|
||||||
|
input wire jtag_state_sdr,
|
||||||
|
input wire jtag_state_e1dr,
|
||||||
|
input wire jtag_state_pdr,
|
||||||
|
input wire jtag_state_e2dr,
|
||||||
|
input wire jtag_state_udr,
|
||||||
|
input wire jtag_state_sirs,
|
||||||
|
input wire jtag_state_cir,
|
||||||
|
input wire jtag_state_sir,
|
||||||
|
input wire jtag_state_e1ir,
|
||||||
|
input wire jtag_state_pir,
|
||||||
|
input wire jtag_state_e2ir,
|
||||||
|
input wire jtag_state_uir,
|
||||||
|
input wire [2:0] jtag_ir_in,
|
||||||
|
output wire jtag_irq,
|
||||||
|
output wire [2:0] jtag_ir_out,
|
||||||
|
input wire clk,
|
||||||
|
input wire reset_n,
|
||||||
|
input wire source_ready,
|
||||||
|
output wire [7:0] source_data,
|
||||||
|
output wire source_valid,
|
||||||
|
input wire [7:0] sink_data,
|
||||||
|
input wire sink_valid,
|
||||||
|
output wire sink_ready,
|
||||||
|
output wire resetrequest,
|
||||||
|
output wire debug_reset,
|
||||||
|
output wire mgmt_valid,
|
||||||
|
output wire [(MGMT_CHANNEL_WIDTH>0?MGMT_CHANNEL_WIDTH:1)-1:0] mgmt_channel,
|
||||||
|
output wire mgmt_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// Signals in the JTAG clock domain
|
||||||
|
wire tck;
|
||||||
|
wire tdi;
|
||||||
|
wire tdo;
|
||||||
|
wire [2:0] ir_in;
|
||||||
|
wire virtual_state_cdr;
|
||||||
|
wire virtual_state_sdr;
|
||||||
|
wire virtual_state_udr;
|
||||||
|
|
||||||
|
assign jtag_irq = 1'b0;
|
||||||
|
assign jtag_ir_out = 3'b000;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (EXPORT_JTAG == 0) begin
|
||||||
|
// SLD node instantiation
|
||||||
|
altera_jtag_sld_node node (
|
||||||
|
.tck (tck),
|
||||||
|
.tdi (tdi),
|
||||||
|
.tdo (tdo),
|
||||||
|
.ir_out (1'b0),
|
||||||
|
.ir_in (ir_in),
|
||||||
|
.virtual_state_cdr (virtual_state_cdr),
|
||||||
|
.virtual_state_cir (),
|
||||||
|
.virtual_state_e1dr (),
|
||||||
|
.virtual_state_e2dr (),
|
||||||
|
.virtual_state_pdr (),
|
||||||
|
.virtual_state_sdr (virtual_state_sdr),
|
||||||
|
.virtual_state_udr (virtual_state_udr),
|
||||||
|
.virtual_state_uir ()
|
||||||
|
);
|
||||||
|
|
||||||
|
assign jtag_tdo = 1'b0;
|
||||||
|
end else begin
|
||||||
|
assign tck = jtag_tck;
|
||||||
|
assign tdi = jtag_tdi;
|
||||||
|
assign jtag_tdo = tdo;
|
||||||
|
assign ir_in = jtag_ir_in;
|
||||||
|
assign virtual_state_cdr = jtag_ena && !jtag_usr1 && jtag_state_cdr;
|
||||||
|
assign virtual_state_sdr = jtag_ena && !jtag_usr1 && jtag_state_sdr;
|
||||||
|
assign virtual_state_udr = jtag_ena && !jtag_usr1 && jtag_state_udr;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (USE_PLI == 0)
|
||||||
|
begin : normal
|
||||||
|
altera_jtag_dc_streaming #(
|
||||||
|
.PURPOSE(PURPOSE),
|
||||||
|
.UPSTREAM_FIFO_SIZE(UPSTREAM_FIFO_SIZE),
|
||||||
|
.DOWNSTREAM_FIFO_SIZE(DOWNSTREAM_FIFO_SIZE),
|
||||||
|
.MGMT_CHANNEL_WIDTH(MGMT_CHANNEL_WIDTH)
|
||||||
|
) jtag_dc_streaming (
|
||||||
|
.tck (tck),
|
||||||
|
.tdi (tdi),
|
||||||
|
.tdo (tdo),
|
||||||
|
.ir_in (ir_in),
|
||||||
|
.virtual_state_cdr(virtual_state_cdr),
|
||||||
|
.virtual_state_sdr(virtual_state_sdr),
|
||||||
|
.virtual_state_udr(virtual_state_udr),
|
||||||
|
.clk(clk),
|
||||||
|
.reset_n(reset_n),
|
||||||
|
.source_data(source_data),
|
||||||
|
.source_valid(source_valid),
|
||||||
|
.sink_data(sink_data),
|
||||||
|
.sink_valid(sink_valid),
|
||||||
|
.sink_ready(sink_ready),
|
||||||
|
.resetrequest(resetrequest),
|
||||||
|
.debug_reset(debug_reset),
|
||||||
|
.mgmt_valid(mgmt_valid),
|
||||||
|
.mgmt_channel(mgmt_channel),
|
||||||
|
.mgmt_data(mgmt_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin : pli_mode
|
||||||
|
|
||||||
|
//synthesis translate_off
|
||||||
|
reg pli_out_valid;
|
||||||
|
reg pli_in_ready;
|
||||||
|
reg [7 : 0] pli_out_data;
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
pli_out_valid <= 0;
|
||||||
|
pli_out_data <= 'b0;
|
||||||
|
pli_in_ready <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
`ifdef MODEL_TECH
|
||||||
|
$do_transaction(
|
||||||
|
PLI_PORT,
|
||||||
|
pli_out_valid,
|
||||||
|
source_ready,
|
||||||
|
pli_out_data,
|
||||||
|
sink_valid,
|
||||||
|
pli_in_ready,
|
||||||
|
sink_data
|
||||||
|
);
|
||||||
|
`endif
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//synthesis translate_on
|
||||||
|
wire [7:0] jtag_source_data;
|
||||||
|
wire jtag_source_valid;
|
||||||
|
wire jtag_sink_ready;
|
||||||
|
wire jtag_resetrequest;
|
||||||
|
|
||||||
|
altera_jtag_dc_streaming #(
|
||||||
|
.PURPOSE(PURPOSE),
|
||||||
|
.UPSTREAM_FIFO_SIZE(UPSTREAM_FIFO_SIZE),
|
||||||
|
.DOWNSTREAM_FIFO_SIZE(DOWNSTREAM_FIFO_SIZE),
|
||||||
|
.MGMT_CHANNEL_WIDTH(MGMT_CHANNEL_WIDTH)
|
||||||
|
) jtag_dc_streaming (
|
||||||
|
.tck (tck),
|
||||||
|
.tdi (tdi),
|
||||||
|
.tdo (tdo),
|
||||||
|
.ir_in (ir_in),
|
||||||
|
.virtual_state_cdr(virtual_state_cdr),
|
||||||
|
.virtual_state_sdr(virtual_state_sdr),
|
||||||
|
.virtual_state_udr(virtual_state_udr),
|
||||||
|
.clk(clk),
|
||||||
|
.reset_n(reset_n),
|
||||||
|
.source_data(jtag_source_data),
|
||||||
|
.source_valid(jtag_source_valid),
|
||||||
|
.sink_data(sink_data),
|
||||||
|
.sink_valid(sink_valid),
|
||||||
|
.sink_ready(jtag_sink_ready),
|
||||||
|
.resetrequest(jtag_resetrequest)//,
|
||||||
|
//.debug_reset(debug_reset),
|
||||||
|
//.mgmt_valid(mgmt_valid),
|
||||||
|
//.mgmt_channel(mgmt_channel),
|
||||||
|
//.mgmt_data(mgmt_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
// synthesis read_comments_as_HDL on
|
||||||
|
// assign source_valid = jtag_source_valid;
|
||||||
|
// assign source_data = jtag_source_data;
|
||||||
|
// assign sink_ready = jtag_sink_ready;
|
||||||
|
// assign resetrequest = jtag_resetrequest;
|
||||||
|
// synthesis read_comments_as_HDL off
|
||||||
|
|
||||||
|
//synthesis translate_off
|
||||||
|
assign source_valid = pli_out_valid;
|
||||||
|
assign source_data = pli_out_data;
|
||||||
|
assign sink_ready = pli_in_ready;
|
||||||
|
assign resetrequest = 1'b0;
|
||||||
|
//synthesis translate_on
|
||||||
|
assign jtag_tdo = 1'b0;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
253
ip/altera/ddr3/altera_avalon_st_packets_to_bytes.v
Normal file
253
ip/altera/ddr3/altera_avalon_st_packets_to_bytes.v
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon ST Packets to Bytes Component
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
module altera_avalon_st_packets_to_bytes
|
||||||
|
//if ENCODING ==0, CHANNEL_WIDTH must be 8
|
||||||
|
//else CHANNEL_WIDTH can be from 0 to 127
|
||||||
|
#( parameter CHANNEL_WIDTH = 8,
|
||||||
|
parameter ENCODING = 0)
|
||||||
|
(
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
input reset_n,
|
||||||
|
// Interface: ST in with packets
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [7: 0] in_data,
|
||||||
|
input [CHANNEL_WIDTH-1: 0] in_channel,
|
||||||
|
input in_startofpacket,
|
||||||
|
input in_endofpacket,
|
||||||
|
|
||||||
|
// Interface: ST out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [7: 0] out_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Signal Declarations
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
localparam CHN_COUNT = (CHANNEL_WIDTH-1)/7;
|
||||||
|
localparam CHN_EFFECTIVE = CHANNEL_WIDTH-1;
|
||||||
|
reg sent_esc, sent_sop, sent_eop;
|
||||||
|
reg sent_channel_char, channel_escaped, sent_channel;
|
||||||
|
reg [CHANNEL_WIDTH:0] stored_channel;
|
||||||
|
reg [4:0] channel_count;
|
||||||
|
reg [((CHN_EFFECTIVE/7+1)*7)-1:0] stored_varchannel;
|
||||||
|
reg channel_needs_esc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
wire need_sop, need_eop, need_esc, need_channel;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Thingofamagick
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
assign need_esc = (in_data === 8'h7a |
|
||||||
|
in_data === 8'h7b |
|
||||||
|
in_data === 8'h7c |
|
||||||
|
in_data === 8'h7d );
|
||||||
|
assign need_eop = (in_endofpacket);
|
||||||
|
assign need_sop = (in_startofpacket);
|
||||||
|
|
||||||
|
|
||||||
|
generate
|
||||||
|
if( CHANNEL_WIDTH > 0) begin
|
||||||
|
wire channel_changed;
|
||||||
|
assign channel_changed = (in_channel != stored_channel);
|
||||||
|
assign need_channel = (need_sop | channel_changed);
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
sent_esc <= 0;
|
||||||
|
sent_sop <= 0;
|
||||||
|
sent_eop <= 0;
|
||||||
|
sent_channel <= 0;
|
||||||
|
channel_escaped <= 0;
|
||||||
|
sent_channel_char <= 0;
|
||||||
|
out_data <= 0;
|
||||||
|
out_valid <= 0;
|
||||||
|
channel_count <= 0;
|
||||||
|
channel_needs_esc <= 0;
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
if (out_ready )
|
||||||
|
out_valid <= 0;
|
||||||
|
|
||||||
|
if ((out_ready | ~out_valid) && in_valid )
|
||||||
|
out_valid <= 1;
|
||||||
|
|
||||||
|
if ((out_ready | ~out_valid) && in_valid) begin
|
||||||
|
if (need_channel & ~sent_channel) begin
|
||||||
|
if (~sent_channel_char) begin
|
||||||
|
sent_channel_char <= 1;
|
||||||
|
out_data <= 8'h7c;
|
||||||
|
channel_count <= CHN_COUNT[4:0];
|
||||||
|
stored_varchannel <= in_channel;
|
||||||
|
if ((ENCODING == 0) | (CHANNEL_WIDTH == 7)) begin
|
||||||
|
channel_needs_esc <= (in_channel == 8'h7a |
|
||||||
|
in_channel == 8'h7b |
|
||||||
|
in_channel == 8'h7c |
|
||||||
|
in_channel == 8'h7d );
|
||||||
|
end
|
||||||
|
end else if (channel_needs_esc & ~channel_escaped) begin
|
||||||
|
out_data <= 8'h7d;
|
||||||
|
channel_escaped <= 1;
|
||||||
|
end else if (~sent_channel) begin
|
||||||
|
if (ENCODING) begin
|
||||||
|
// Sending out MSB=1, while not last 7 bits of Channel
|
||||||
|
if (channel_count > 0) begin
|
||||||
|
if (channel_needs_esc) out_data <= {1'b1, stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-1:((CHN_EFFECTIVE/7+1)*7)-7]} ^ 8'h20;
|
||||||
|
else out_data <= {1'b1, stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-1:((CHN_EFFECTIVE/7+1)*7)-7]};
|
||||||
|
stored_varchannel <= stored_varchannel<<7;
|
||||||
|
|
||||||
|
channel_count <= channel_count - 1'b1;
|
||||||
|
// check whether the last 7 bits need escape or not
|
||||||
|
if (channel_count ==1 & CHANNEL_WIDTH > 7) begin
|
||||||
|
channel_needs_esc <=
|
||||||
|
((stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-8:((CHN_EFFECTIVE/7+1)*7)-14] == 7'h7a)|
|
||||||
|
(stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-8:((CHN_EFFECTIVE/7+1)*7)-14] == 7'h7b) |
|
||||||
|
(stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-8:((CHN_EFFECTIVE/7+1)*7)-14] == 7'h7c) |
|
||||||
|
(stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-8:((CHN_EFFECTIVE/7+1)*7)-14] == 7'h7d) );
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
// Sending out MSB=0, last 7 bits of Channel
|
||||||
|
if (channel_needs_esc) begin
|
||||||
|
channel_needs_esc <= 0;
|
||||||
|
out_data <= {1'b0, stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-1:((CHN_EFFECTIVE/7+1)*7)-7]} ^ 8'h20;
|
||||||
|
end else out_data <= {1'b0, stored_varchannel[((CHN_EFFECTIVE/7+1)*7)-1:((CHN_EFFECTIVE/7+1)*7)-7]};
|
||||||
|
sent_channel <= 1;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
if (channel_needs_esc) begin
|
||||||
|
channel_needs_esc <= 0;
|
||||||
|
out_data <= in_channel ^ 8'h20;
|
||||||
|
end else out_data <= in_channel;
|
||||||
|
sent_channel <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else if (need_sop & ~sent_sop) begin
|
||||||
|
sent_sop <= 1;
|
||||||
|
out_data <= 8'h7a;
|
||||||
|
|
||||||
|
end else if (need_eop & ~sent_eop) begin
|
||||||
|
sent_eop <= 1;
|
||||||
|
out_data <= 8'h7b;
|
||||||
|
|
||||||
|
end else if (need_esc & ~sent_esc) begin
|
||||||
|
sent_esc <= 1;
|
||||||
|
out_data <= 8'h7d;
|
||||||
|
end else begin
|
||||||
|
if (sent_esc) out_data <= in_data ^ 8'h20;
|
||||||
|
else out_data <= in_data;
|
||||||
|
sent_esc <= 0;
|
||||||
|
sent_sop <= 0;
|
||||||
|
sent_eop <= 0;
|
||||||
|
sent_channel <= 0;
|
||||||
|
channel_escaped <= 0;
|
||||||
|
sent_channel_char <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//channel related signals
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
//extra bit in stored_channel to force reset
|
||||||
|
stored_channel <= {CHANNEL_WIDTH{1'b1}};
|
||||||
|
end else begin
|
||||||
|
//update stored_channel only when it is sent out
|
||||||
|
if (sent_channel) stored_channel <= in_channel;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
always @* begin
|
||||||
|
|
||||||
|
// in_ready. Low when:
|
||||||
|
// back pressured, or when
|
||||||
|
// we are outputting a control character, which means that one of
|
||||||
|
// {escape_char, start of packet, end of packet, channel}
|
||||||
|
// needs to be, but has not yet, been handled.
|
||||||
|
in_ready = (out_ready | !out_valid) & in_valid & (~need_esc | sent_esc)
|
||||||
|
& (~need_sop | sent_sop)
|
||||||
|
& (~need_eop | sent_eop)
|
||||||
|
& (~need_channel | sent_channel);
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
assign need_channel = (need_sop);
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (!reset_n) begin
|
||||||
|
sent_esc <= 0;
|
||||||
|
sent_sop <= 0;
|
||||||
|
sent_eop <= 0;
|
||||||
|
out_data <= 0;
|
||||||
|
out_valid <= 0;
|
||||||
|
sent_channel <= 0;
|
||||||
|
sent_channel_char <= 0;
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
if (out_ready )
|
||||||
|
out_valid <= 0;
|
||||||
|
|
||||||
|
if ((out_ready | ~out_valid) && in_valid )
|
||||||
|
out_valid <= 1;
|
||||||
|
|
||||||
|
if ((out_ready | ~out_valid) && in_valid) begin
|
||||||
|
if (need_channel & ~sent_channel) begin
|
||||||
|
if (~sent_channel_char) begin //Added sent channel 0 before the 1st SOP
|
||||||
|
sent_channel_char <= 1;
|
||||||
|
out_data <= 8'h7c;
|
||||||
|
end else if (~sent_channel) begin
|
||||||
|
out_data <= 'h0;
|
||||||
|
sent_channel <= 1;
|
||||||
|
end
|
||||||
|
end else if (need_sop & ~sent_sop) begin
|
||||||
|
sent_sop <= 1;
|
||||||
|
out_data <= 8'h7a;
|
||||||
|
end else if (need_eop & ~sent_eop) begin
|
||||||
|
sent_eop <= 1;
|
||||||
|
out_data <= 8'h7b;
|
||||||
|
end else if (need_esc & ~sent_esc) begin
|
||||||
|
sent_esc <= 1;
|
||||||
|
out_data <= 8'h7d;
|
||||||
|
end else begin
|
||||||
|
if (sent_esc) out_data <= in_data ^ 8'h20;
|
||||||
|
else out_data <= in_data;
|
||||||
|
sent_esc <= 0;
|
||||||
|
sent_sop <= 0;
|
||||||
|
sent_eop <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
in_ready = (out_ready | !out_valid) & in_valid & (~need_esc | sent_esc)
|
||||||
|
& (~need_sop | sent_sop)
|
||||||
|
& (~need_eop | sent_eop)
|
||||||
|
& (~need_channel | sent_channel);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
139
ip/altera/ddr3/altera_avalon_st_pipeline_base.v
Normal file
139
ip/altera/ddr3/altera_avalon_st_pipeline_base.v
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $File: //acds/rel/15.1/ip/avalon_st/altera_avalon_st_pipeline_stage/altera_avalon_st_pipeline_base.v $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 1ns
|
||||||
|
|
||||||
|
module altera_avalon_st_pipeline_base (
|
||||||
|
clk,
|
||||||
|
reset,
|
||||||
|
in_ready,
|
||||||
|
in_valid,
|
||||||
|
in_data,
|
||||||
|
out_ready,
|
||||||
|
out_valid,
|
||||||
|
out_data
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter SYMBOLS_PER_BEAT = 1;
|
||||||
|
parameter BITS_PER_SYMBOL = 8;
|
||||||
|
parameter PIPELINE_READY = 1;
|
||||||
|
localparam DATA_WIDTH = SYMBOLS_PER_BEAT * BITS_PER_SYMBOL;
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input reset;
|
||||||
|
|
||||||
|
output in_ready;
|
||||||
|
input in_valid;
|
||||||
|
input [DATA_WIDTH-1:0] in_data;
|
||||||
|
|
||||||
|
input out_ready;
|
||||||
|
output out_valid;
|
||||||
|
output [DATA_WIDTH-1:0] out_data;
|
||||||
|
|
||||||
|
reg full0;
|
||||||
|
reg full1;
|
||||||
|
reg [DATA_WIDTH-1:0] data0;
|
||||||
|
reg [DATA_WIDTH-1:0] data1;
|
||||||
|
|
||||||
|
assign out_valid = full1;
|
||||||
|
assign out_data = data1;
|
||||||
|
|
||||||
|
generate if (PIPELINE_READY == 1)
|
||||||
|
begin : REGISTERED_READY_PLINE
|
||||||
|
|
||||||
|
assign in_ready = !full0;
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
data0 <= {DATA_WIDTH{1'b0}};
|
||||||
|
data1 <= {DATA_WIDTH{1'b0}};
|
||||||
|
end else begin
|
||||||
|
// ----------------------------
|
||||||
|
// always load the second slot if we can
|
||||||
|
// ----------------------------
|
||||||
|
if (~full0)
|
||||||
|
data0 <= in_data;
|
||||||
|
// ----------------------------
|
||||||
|
// first slot is loaded either from the second,
|
||||||
|
// or with new data
|
||||||
|
// ----------------------------
|
||||||
|
if (~full1 || (out_ready && out_valid)) begin
|
||||||
|
if (full0)
|
||||||
|
data1 <= data0;
|
||||||
|
else
|
||||||
|
data1 <= in_data;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
full0 <= 1'b0;
|
||||||
|
full1 <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
// no data in pipeline
|
||||||
|
if (~full0 & ~full1) begin
|
||||||
|
if (in_valid) begin
|
||||||
|
full1 <= 1'b1;
|
||||||
|
end
|
||||||
|
end // ~f1 & ~f0
|
||||||
|
|
||||||
|
// one datum in pipeline
|
||||||
|
if (full1 & ~full0) begin
|
||||||
|
if (in_valid & ~out_ready) begin
|
||||||
|
full0 <= 1'b1;
|
||||||
|
end
|
||||||
|
// back to empty
|
||||||
|
if (~in_valid & out_ready) begin
|
||||||
|
full1 <= 1'b0;
|
||||||
|
end
|
||||||
|
end // f1 & ~f0
|
||||||
|
|
||||||
|
// two data in pipeline
|
||||||
|
if (full1 & full0) begin
|
||||||
|
// go back to one datum state
|
||||||
|
if (out_ready) begin
|
||||||
|
full0 <= 1'b0;
|
||||||
|
end
|
||||||
|
end // end go back to one datum stage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin : UNREGISTERED_READY_PLINE
|
||||||
|
|
||||||
|
// in_ready will be a pass through of the out_ready signal as it is not registered
|
||||||
|
assign in_ready = (~full1) | out_ready;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
data1 <= 'b0;
|
||||||
|
full1 <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (in_ready) begin
|
||||||
|
data1 <= in_data;
|
||||||
|
full1 <= in_valid;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
166
ip/altera/ddr3/altera_avalon_st_pipeline_stage.sv
Normal file
166
ip/altera/ddr3/altera_avalon_st_pipeline_stage.sv
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $File: //acds/rel/15.1/ip/avalon_st/altera_avalon_st_pipeline_stage/altera_avalon_st_pipeline_stage.sv $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 1ns
|
||||||
|
|
||||||
|
module altera_avalon_st_pipeline_stage #(
|
||||||
|
parameter
|
||||||
|
SYMBOLS_PER_BEAT = 1,
|
||||||
|
BITS_PER_SYMBOL = 8,
|
||||||
|
USE_PACKETS = 0,
|
||||||
|
USE_EMPTY = 0,
|
||||||
|
PIPELINE_READY = 1,
|
||||||
|
|
||||||
|
// Optional ST signal widths. Value "0" means no such port.
|
||||||
|
CHANNEL_WIDTH = 0,
|
||||||
|
ERROR_WIDTH = 0,
|
||||||
|
|
||||||
|
// Derived parameters
|
||||||
|
DATA_WIDTH = SYMBOLS_PER_BEAT * BITS_PER_SYMBOL,
|
||||||
|
PACKET_WIDTH = 0,
|
||||||
|
EMPTY_WIDTH = 0
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
output in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [DATA_WIDTH - 1 : 0] in_data,
|
||||||
|
input [(CHANNEL_WIDTH ? (CHANNEL_WIDTH - 1) : 0) : 0] in_channel,
|
||||||
|
input [(ERROR_WIDTH ? (ERROR_WIDTH - 1) : 0) : 0] in_error,
|
||||||
|
input in_startofpacket,
|
||||||
|
input in_endofpacket,
|
||||||
|
input [(EMPTY_WIDTH ? (EMPTY_WIDTH - 1) : 0) : 0] in_empty,
|
||||||
|
|
||||||
|
input out_ready,
|
||||||
|
output out_valid,
|
||||||
|
output [DATA_WIDTH - 1 : 0] out_data,
|
||||||
|
output [(CHANNEL_WIDTH ? (CHANNEL_WIDTH - 1) : 0) : 0] out_channel,
|
||||||
|
output [(ERROR_WIDTH ? (ERROR_WIDTH - 1) : 0) : 0] out_error,
|
||||||
|
output out_startofpacket,
|
||||||
|
output out_endofpacket,
|
||||||
|
output [(EMPTY_WIDTH ? (EMPTY_WIDTH - 1) : 0) : 0] out_empty
|
||||||
|
);
|
||||||
|
localparam
|
||||||
|
PAYLOAD_WIDTH =
|
||||||
|
DATA_WIDTH +
|
||||||
|
PACKET_WIDTH +
|
||||||
|
CHANNEL_WIDTH +
|
||||||
|
EMPTY_WIDTH +
|
||||||
|
ERROR_WIDTH;
|
||||||
|
|
||||||
|
wire [PAYLOAD_WIDTH - 1: 0] in_payload;
|
||||||
|
wire [PAYLOAD_WIDTH - 1: 0] out_payload;
|
||||||
|
|
||||||
|
// Assign in_data and other optional in_* interface signals to in_payload.
|
||||||
|
assign in_payload[DATA_WIDTH - 1 : 0] = in_data;
|
||||||
|
generate
|
||||||
|
// optional packet inputs
|
||||||
|
if (PACKET_WIDTH) begin
|
||||||
|
assign in_payload[
|
||||||
|
DATA_WIDTH + PACKET_WIDTH - 1 :
|
||||||
|
DATA_WIDTH
|
||||||
|
] = {in_startofpacket, in_endofpacket};
|
||||||
|
end
|
||||||
|
// optional channel input
|
||||||
|
if (CHANNEL_WIDTH) begin
|
||||||
|
assign in_payload[
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH - 1 :
|
||||||
|
DATA_WIDTH + PACKET_WIDTH
|
||||||
|
] = in_channel;
|
||||||
|
end
|
||||||
|
// optional empty input
|
||||||
|
if (EMPTY_WIDTH) begin
|
||||||
|
assign in_payload[
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH + EMPTY_WIDTH - 1 :
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH
|
||||||
|
] = in_empty;
|
||||||
|
end
|
||||||
|
// optional error input
|
||||||
|
if (ERROR_WIDTH) begin
|
||||||
|
assign in_payload[
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH + EMPTY_WIDTH + ERROR_WIDTH - 1 :
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH + EMPTY_WIDTH
|
||||||
|
] = in_error;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
altera_avalon_st_pipeline_base #(
|
||||||
|
.SYMBOLS_PER_BEAT (PAYLOAD_WIDTH),
|
||||||
|
.BITS_PER_SYMBOL (1),
|
||||||
|
.PIPELINE_READY (PIPELINE_READY)
|
||||||
|
) core (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.in_ready (in_ready),
|
||||||
|
.in_valid (in_valid),
|
||||||
|
.in_data (in_payload),
|
||||||
|
.out_ready (out_ready),
|
||||||
|
.out_valid (out_valid),
|
||||||
|
.out_data (out_payload)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Assign out_data and other optional out_* interface signals from out_payload.
|
||||||
|
assign out_data = out_payload[DATA_WIDTH - 1 : 0];
|
||||||
|
generate
|
||||||
|
// optional packet outputs
|
||||||
|
if (PACKET_WIDTH) begin
|
||||||
|
assign {out_startofpacket, out_endofpacket} =
|
||||||
|
out_payload[DATA_WIDTH + PACKET_WIDTH - 1 : DATA_WIDTH];
|
||||||
|
end else begin
|
||||||
|
// Avoid a "has no driver" warning.
|
||||||
|
assign {out_startofpacket, out_endofpacket} = 2'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// optional channel output
|
||||||
|
if (CHANNEL_WIDTH) begin
|
||||||
|
assign out_channel = out_payload[
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH - 1 :
|
||||||
|
DATA_WIDTH + PACKET_WIDTH
|
||||||
|
];
|
||||||
|
end else begin
|
||||||
|
// Avoid a "has no driver" warning.
|
||||||
|
assign out_channel = 1'b0;
|
||||||
|
end
|
||||||
|
// optional empty output
|
||||||
|
if (EMPTY_WIDTH) begin
|
||||||
|
assign out_empty = out_payload[
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH + EMPTY_WIDTH - 1 :
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH
|
||||||
|
];
|
||||||
|
end else begin
|
||||||
|
// Avoid a "has no driver" warning.
|
||||||
|
assign out_empty = 1'b0;
|
||||||
|
end
|
||||||
|
// optional error output
|
||||||
|
if (ERROR_WIDTH) begin
|
||||||
|
assign out_error = out_payload[
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH + EMPTY_WIDTH + ERROR_WIDTH - 1 :
|
||||||
|
DATA_WIDTH + PACKET_WIDTH + CHANNEL_WIDTH + EMPTY_WIDTH
|
||||||
|
];
|
||||||
|
end else begin
|
||||||
|
// Avoid a "has no driver" warning.
|
||||||
|
assign out_error = 1'b0;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
189
ip/altera/ddr3/altera_default_burst_converter.sv
Normal file
189
ip/altera/ddr3/altera_default_burst_converter.sv
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_burst_adapter/new_source/altera_default_burst_converter.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// --------------------------------------------
|
||||||
|
// Default Burst Converter
|
||||||
|
// Notes:
|
||||||
|
// 1) If burst type FIXED and slave is AXI,
|
||||||
|
// passthrough the transaction.
|
||||||
|
// 2) Else, converts burst into non-bursting
|
||||||
|
// transactions (length of 1).
|
||||||
|
// --------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_default_burst_converter
|
||||||
|
#(
|
||||||
|
parameter PKT_BURST_TYPE_W = 2,
|
||||||
|
parameter PKT_BURSTWRAP_W = 5,
|
||||||
|
parameter PKT_ADDR_W = 12,
|
||||||
|
parameter PKT_BURST_SIZE_W = 3,
|
||||||
|
parameter IS_AXI_SLAVE = 0,
|
||||||
|
parameter LEN_W = 2
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
input enable,
|
||||||
|
|
||||||
|
input [PKT_BURST_TYPE_W - 1 : 0] in_bursttype,
|
||||||
|
input [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap_reg,
|
||||||
|
input [PKT_BURSTWRAP_W - 1 : 0] in_burstwrap_value,
|
||||||
|
input [PKT_ADDR_W - 1 : 0] in_addr,
|
||||||
|
input [PKT_ADDR_W - 1 : 0] in_addr_reg,
|
||||||
|
input [LEN_W - 1 : 0] in_len,
|
||||||
|
input [PKT_BURST_SIZE_W - 1 : 0] in_size_value,
|
||||||
|
|
||||||
|
input in_is_write,
|
||||||
|
|
||||||
|
output reg [PKT_ADDR_W - 1 : 0] out_addr,
|
||||||
|
output reg [LEN_W - 1 : 0] out_len,
|
||||||
|
|
||||||
|
output reg new_burst
|
||||||
|
);
|
||||||
|
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// AXI Burst Type Encoding
|
||||||
|
// ---------------------------------------------------
|
||||||
|
typedef enum bit [1:0]
|
||||||
|
{
|
||||||
|
FIXED = 2'b00,
|
||||||
|
INCR = 2'b01,
|
||||||
|
WRAP = 2'b10,
|
||||||
|
RESERVED = 2'b11
|
||||||
|
} AxiBurstType;
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// Internal Signals
|
||||||
|
// -------------------------------------------
|
||||||
|
wire [LEN_W - 1 : 0] unit_len = {{LEN_W - 1 {1'b0}}, 1'b1};
|
||||||
|
reg [LEN_W - 1 : 0] next_len;
|
||||||
|
reg [LEN_W - 1 : 0] remaining_len;
|
||||||
|
reg [PKT_ADDR_W - 1 : 0] next_incr_addr;
|
||||||
|
reg [PKT_ADDR_W - 1 : 0] incr_wrapped_addr;
|
||||||
|
reg [PKT_ADDR_W - 1 : 0] extended_burstwrap_value;
|
||||||
|
reg [PKT_ADDR_W - 1 : 0] addr_incr_variable_size_value;
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// Byte Count Converter
|
||||||
|
// -------------------------------------------
|
||||||
|
// Avalon Slave: Read/Write, the out_len is always 1 (unit_len).
|
||||||
|
// AXI Slave: Read/Write, the out_len is always the in_len (pass through) of a given cycle.
|
||||||
|
// If bursttype RESERVED, out_len is always 1 (unit_len).
|
||||||
|
generate if (IS_AXI_SLAVE == 1)
|
||||||
|
begin : axi_slave_out_len
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
out_len <= {LEN_W{1'b0}};
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
out_len <= (in_bursttype == FIXED) ? in_len : unit_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else // IS_AXI_SLAVE == 0
|
||||||
|
begin : non_axi_slave_out_len
|
||||||
|
always_comb begin
|
||||||
|
out_len = unit_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
|
||||||
|
always_comb begin : proc_extend_burstwrap
|
||||||
|
extended_burstwrap_value = {{(PKT_ADDR_W - PKT_BURSTWRAP_W){in_burstwrap_reg[PKT_BURSTWRAP_W - 1]}}, in_burstwrap_value};
|
||||||
|
addr_incr_variable_size_value = {{(PKT_ADDR_W - 1){1'b0}}, 1'b1} << in_size_value;
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// Address Converter
|
||||||
|
// -------------------------------------------
|
||||||
|
// Write: out_addr = in_addr at every cycle (pass through).
|
||||||
|
// Read: out_addr = in_addr at every new_burst. Subsequent addresses calculated by converter.
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
next_incr_addr <= {PKT_ADDR_W{1'b0}};
|
||||||
|
out_addr <= {PKT_ADDR_W{1'b0}};
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
next_incr_addr <= next_incr_addr + addr_incr_variable_size_value;
|
||||||
|
if (new_burst) begin
|
||||||
|
next_incr_addr <= in_addr + addr_incr_variable_size_value;
|
||||||
|
end
|
||||||
|
out_addr <= incr_wrapped_addr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
incr_wrapped_addr = in_addr;
|
||||||
|
if (!new_burst) begin
|
||||||
|
// This formula calculates addresses of WRAP bursts and works perfectly fine for other burst types too.
|
||||||
|
incr_wrapped_addr = (in_addr_reg & ~extended_burstwrap_value) | (next_incr_addr & extended_burstwrap_value);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// Control Signals
|
||||||
|
// -------------------------------------------
|
||||||
|
|
||||||
|
// Determine the min_len.
|
||||||
|
// 1) FIXED read to AXI slave: One-time passthrough, therefore the min_len == in_len.
|
||||||
|
// 2) FIXED write to AXI slave: min_len == 1.
|
||||||
|
// 3) FIXED read/write to Avalon slave: min_len == 1.
|
||||||
|
// 4) RESERVED read/write to AXI/Avalon slave: min_len == 1.
|
||||||
|
wire [LEN_W - 1 : 0] min_len;
|
||||||
|
generate if (IS_AXI_SLAVE == 1)
|
||||||
|
begin : axi_slave_min_len
|
||||||
|
assign min_len = (!in_is_write && (in_bursttype == FIXED)) ? in_len : unit_len;
|
||||||
|
end
|
||||||
|
else // IS_AXI_SLAVE == 0
|
||||||
|
begin : non_axi_slave_min_len
|
||||||
|
assign min_len = unit_len;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// last_beat calculation.
|
||||||
|
wire last_beat = (remaining_len == min_len);
|
||||||
|
|
||||||
|
// next_len calculation.
|
||||||
|
always_comb begin
|
||||||
|
remaining_len = in_len;
|
||||||
|
if (!new_burst) remaining_len = next_len;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
next_len <= 1'b0;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
next_len <= remaining_len - unit_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// new_burst calculation.
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
new_burst <= 1'b1;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
new_burst <= last_beat;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
310
ip/altera/ddr3/altera_incr_burst_converter.sv
Normal file
310
ip/altera/ddr3/altera_incr_burst_converter.sv
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_burst_adapter/new_source/altera_incr_burst_converter.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
// This component is used for INCR Avalon slave
|
||||||
|
// (slave which only supports INCR) or AXI slave.
|
||||||
|
// It converts burst length of input packet
|
||||||
|
// to match slave burst.
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_incr_burst_converter
|
||||||
|
#(
|
||||||
|
parameter
|
||||||
|
// ----------------------------------------
|
||||||
|
// Burst length Parameters
|
||||||
|
// (real burst length value, not bytecount)
|
||||||
|
// ----------------------------------------
|
||||||
|
MAX_IN_LEN = 16,
|
||||||
|
MAX_OUT_LEN = 4,
|
||||||
|
NUM_SYMBOLS = 4,
|
||||||
|
ADDR_WIDTH = 12,
|
||||||
|
BNDRY_WIDTH = 12,
|
||||||
|
BURSTSIZE_WIDTH = 3,
|
||||||
|
IN_NARROW_SIZE = 0,
|
||||||
|
PURELY_INCR_AVL_SYS = 0,
|
||||||
|
// ------------------
|
||||||
|
// Derived Parameters
|
||||||
|
// ------------------
|
||||||
|
LEN_WIDTH = log2ceil(MAX_IN_LEN) + 1,
|
||||||
|
OUT_LEN_WIDTH = log2ceil(MAX_OUT_LEN) + 1,
|
||||||
|
LOG2_NUMSYMBOLS = log2ceil(NUM_SYMBOLS)
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
input enable,
|
||||||
|
|
||||||
|
input is_write,
|
||||||
|
input [LEN_WIDTH - 1 : 0] in_len,
|
||||||
|
input in_sop,
|
||||||
|
|
||||||
|
input [ADDR_WIDTH - 1 : 0] in_addr,
|
||||||
|
input [ADDR_WIDTH - 1 : 0] in_addr_reg,
|
||||||
|
input [BNDRY_WIDTH - 1 : 0] in_burstwrap_reg,
|
||||||
|
input [BURSTSIZE_WIDTH - 1 : 0] in_size_t,
|
||||||
|
input [BURSTSIZE_WIDTH - 1 : 0] in_size_reg,
|
||||||
|
|
||||||
|
// converted output length
|
||||||
|
// out_len : compressed burst, read
|
||||||
|
// uncompressed_len: uncompressed, write
|
||||||
|
output reg [LEN_WIDTH - 1 : 0] out_len,
|
||||||
|
output reg [LEN_WIDTH - 1 : 0] uncompr_out_len,
|
||||||
|
// Compressed address output
|
||||||
|
output reg [ADDR_WIDTH - 1 : 0] out_addr,
|
||||||
|
output reg new_burst_export
|
||||||
|
);
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Signals for wrapping support
|
||||||
|
// ----------------------------------------
|
||||||
|
reg [LEN_WIDTH - 1 : 0] remaining_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_out_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_rem_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] uncompr_remaining_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_uncompr_remaining_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_uncompr_rem_len;
|
||||||
|
reg new_burst;
|
||||||
|
reg uncompr_sub_burst;
|
||||||
|
|
||||||
|
// Avoid QIS warning
|
||||||
|
wire [OUT_LEN_WIDTH - 1 : 0] max_out_length;
|
||||||
|
assign max_out_length = MAX_OUT_LEN[OUT_LEN_WIDTH - 1 : 0];
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
new_burst_export = new_burst;
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// length remaining calculation
|
||||||
|
// -------------------------------------------
|
||||||
|
|
||||||
|
always_comb begin : proc_uncompressed_remaining_len
|
||||||
|
if ((in_len <= max_out_length) && is_write) begin
|
||||||
|
uncompr_remaining_len = in_len;
|
||||||
|
end else begin
|
||||||
|
uncompr_remaining_len = max_out_length;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (uncompr_sub_burst)
|
||||||
|
uncompr_remaining_len = next_uncompr_rem_len;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
next_uncompr_rem_len <= 0;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
next_uncompr_rem_len <= uncompr_remaining_len - 1'b1; // in term of length, it just reduces 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin : proc_compressed_remaining_len
|
||||||
|
remaining_len = in_len;
|
||||||
|
if (!new_burst)
|
||||||
|
remaining_len = next_rem_len;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff@(posedge clk or posedge reset) begin : proc_next_uncompressed_remaining_len
|
||||||
|
if(reset) begin
|
||||||
|
next_uncompr_remaining_len <= '0;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
if (in_sop) begin
|
||||||
|
next_uncompr_remaining_len <= in_len - max_out_length;
|
||||||
|
end
|
||||||
|
else if (!uncompr_sub_burst)
|
||||||
|
next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
next_out_len = max_out_length;
|
||||||
|
if (remaining_len < max_out_length) begin
|
||||||
|
next_out_len = remaining_len;
|
||||||
|
end
|
||||||
|
end // always_comb
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Length remaining calculation : compressed
|
||||||
|
// --------------------------------------------------
|
||||||
|
// length remaining for compressed transaction
|
||||||
|
// for wrap, need special handling for first out length
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
next_rem_len <= 0;
|
||||||
|
else if (enable) begin
|
||||||
|
if (new_burst)
|
||||||
|
next_rem_len <= in_len - max_out_length;
|
||||||
|
else
|
||||||
|
next_rem_len <= next_rem_len - max_out_length;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
uncompr_sub_burst <= 0;
|
||||||
|
end
|
||||||
|
else if (enable && is_write) begin
|
||||||
|
uncompr_sub_burst <= (uncompr_remaining_len > 1'b1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Control signals
|
||||||
|
// --------------------------------------------------
|
||||||
|
wire end_compressed_sub_burst;
|
||||||
|
assign end_compressed_sub_burst = (remaining_len == next_out_len);
|
||||||
|
|
||||||
|
// new_burst:
|
||||||
|
// the converter takes in_len for new calculation
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
new_burst <= 1;
|
||||||
|
else if (enable)
|
||||||
|
new_burst <= end_compressed_sub_burst;
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Output length
|
||||||
|
// --------------------------------------------------
|
||||||
|
// register out_len for compressed trans
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
out_len <= 0;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
out_len <= next_out_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// register uncompr_out_len for uncompressed trans
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
uncompr_out_len <= '0;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
uncompr_out_len <= uncompr_remaining_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Address Calculation
|
||||||
|
// --------------------------------------------------
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] addr_incr_sel;
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] addr_incr_sel_reg;
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] addr_incr_full_size;
|
||||||
|
|
||||||
|
localparam [ADDR_WIDTH - 1 : 0] ADDR_INCR = MAX_OUT_LEN << LOG2_NUMSYMBOLS;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (IN_NARROW_SIZE) begin : narrow_addr_incr
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] addr_incr_variable_size;
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] addr_incr_variable_size_reg;
|
||||||
|
|
||||||
|
assign addr_incr_variable_size = MAX_OUT_LEN << in_size_t;
|
||||||
|
assign addr_incr_variable_size_reg = MAX_OUT_LEN << in_size_reg;
|
||||||
|
|
||||||
|
assign addr_incr_sel = addr_incr_variable_size;
|
||||||
|
assign addr_incr_sel_reg = addr_incr_variable_size_reg;
|
||||||
|
end
|
||||||
|
else begin : full_addr_incr
|
||||||
|
assign addr_incr_full_size = ADDR_INCR[ADDR_WIDTH - 1 : 0];
|
||||||
|
assign addr_incr_sel = addr_incr_full_size;
|
||||||
|
assign addr_incr_sel_reg = addr_incr_full_size;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] next_out_addr;
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] incremented_addr;
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
out_addr <= '0;
|
||||||
|
end else begin
|
||||||
|
if (enable) begin
|
||||||
|
out_addr <= (next_out_addr);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (!PURELY_INCR_AVL_SYS) begin : incremented_addr_normal
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
incremented_addr <= '0;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
incremented_addr <= (next_out_addr + addr_incr_sel_reg);
|
||||||
|
if (new_burst) begin
|
||||||
|
incremented_addr <= (next_out_addr + addr_incr_sel);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end // always_ff @
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
next_out_addr = in_addr;
|
||||||
|
if (!new_burst) begin
|
||||||
|
next_out_addr = incremented_addr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : incremented_addr_pure_av
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
incremented_addr <= '0;
|
||||||
|
end
|
||||||
|
else if (enable) begin
|
||||||
|
incremented_addr <= (next_out_addr + addr_incr_sel_reg);
|
||||||
|
end
|
||||||
|
end // always_ff @
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
next_out_addr = in_addr;
|
||||||
|
if (!new_burst) begin
|
||||||
|
next_out_addr = (incremented_addr);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Calculates the log2ceil of the input value
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input integer val;
|
||||||
|
reg[31:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i[30:0] << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
261
ip/altera/ddr3/altera_jtag_dc_streaming.v
Normal file
261
ip/altera/ddr3/altera_jtag_dc_streaming.v
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// This module is a simple clock crosser for control signals. It will take
|
||||||
|
// the asynchronous control signal and synchronize it to the clk domain
|
||||||
|
// attached to the clk input. It does so by passing the control signal
|
||||||
|
// through a pair of registers and then sensing the level transition from
|
||||||
|
// either hi-to-lo or lo-to-hi. *ATTENTION* This module makes the assumption
|
||||||
|
// that the control signal will always transition every time is asserted.
|
||||||
|
// i.e.:
|
||||||
|
// ____ ___________________
|
||||||
|
// -> ___| |___ and ___| |_____
|
||||||
|
//
|
||||||
|
// on the control signal will be seen as only one assertion of the control
|
||||||
|
// signal. In short, if your control could be asserted back-to-back, then
|
||||||
|
// don't use this module. You'll be losing data.
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_jtag_control_signal_crosser (
|
||||||
|
clk,
|
||||||
|
reset_n,
|
||||||
|
async_control_signal,
|
||||||
|
sense_pos_edge,
|
||||||
|
sync_control_signal
|
||||||
|
);
|
||||||
|
input clk;
|
||||||
|
input reset_n;
|
||||||
|
input async_control_signal;
|
||||||
|
input sense_pos_edge;
|
||||||
|
output sync_control_signal;
|
||||||
|
|
||||||
|
parameter SYNC_DEPTH = 3; // number of synchronizer stages for clock crossing
|
||||||
|
|
||||||
|
reg sync_control_signal;
|
||||||
|
|
||||||
|
wire synchronized_raw_signal;
|
||||||
|
reg edge_detector_register;
|
||||||
|
|
||||||
|
altera_std_synchronizer #(.depth(SYNC_DEPTH)) synchronizer (
|
||||||
|
.clk(clk),
|
||||||
|
.reset_n(reset_n),
|
||||||
|
.din(async_control_signal),
|
||||||
|
.dout(synchronized_raw_signal)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @ (posedge clk or negedge reset_n)
|
||||||
|
if (~reset_n)
|
||||||
|
edge_detector_register <= 1'b0;
|
||||||
|
else
|
||||||
|
edge_detector_register <= synchronized_raw_signal;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
if (sense_pos_edge)
|
||||||
|
sync_control_signal <= ~edge_detector_register & synchronized_raw_signal;
|
||||||
|
else
|
||||||
|
sync_control_signal <= edge_detector_register & ~synchronized_raw_signal;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// This module crosses the clock domain for a given source
|
||||||
|
module altera_jtag_src_crosser (
|
||||||
|
sink_clk,
|
||||||
|
sink_reset_n,
|
||||||
|
sink_valid,
|
||||||
|
sink_data,
|
||||||
|
src_clk,
|
||||||
|
src_reset_n,
|
||||||
|
src_valid,
|
||||||
|
src_data
|
||||||
|
);
|
||||||
|
parameter WIDTH = 8;
|
||||||
|
parameter SYNC_DEPTH = 3; // number of synchronizer stages for clock crossing
|
||||||
|
|
||||||
|
input sink_clk;
|
||||||
|
input sink_reset_n;
|
||||||
|
input sink_valid;
|
||||||
|
input [WIDTH-1:0] sink_data;
|
||||||
|
input src_clk;
|
||||||
|
input src_reset_n;
|
||||||
|
output src_valid;
|
||||||
|
output [WIDTH-1:0] src_data;
|
||||||
|
|
||||||
|
reg sink_valid_buffer;
|
||||||
|
reg [WIDTH-1:0] sink_data_buffer;
|
||||||
|
|
||||||
|
reg src_valid;
|
||||||
|
reg [WIDTH-1:0] src_data /* synthesis ALTERA_ATTRIBUTE = "PRESERVE_REGISTER=ON ; SUPPRESS_DA_RULE_INTERNAL=R101 ; {-from \"*\"} CUT=ON " */;
|
||||||
|
|
||||||
|
wire synchronized_valid;
|
||||||
|
|
||||||
|
altera_jtag_control_signal_crosser #(
|
||||||
|
.SYNC_DEPTH(SYNC_DEPTH)
|
||||||
|
) crosser (
|
||||||
|
.clk(src_clk),
|
||||||
|
.reset_n(src_reset_n),
|
||||||
|
.async_control_signal(sink_valid_buffer),
|
||||||
|
.sense_pos_edge(1'b1),
|
||||||
|
.sync_control_signal(synchronized_valid)
|
||||||
|
);
|
||||||
|
always @ (posedge sink_clk or negedge sink_reset_n) begin
|
||||||
|
if (~sink_reset_n) begin
|
||||||
|
sink_valid_buffer <= 1'b0;
|
||||||
|
sink_data_buffer <= 'b0;
|
||||||
|
end else begin
|
||||||
|
sink_valid_buffer <= sink_valid;
|
||||||
|
if (sink_valid) begin
|
||||||
|
sink_data_buffer <= sink_data;
|
||||||
|
end
|
||||||
|
end //end if
|
||||||
|
end //always sink_clk
|
||||||
|
|
||||||
|
always @ (posedge src_clk or negedge src_reset_n) begin
|
||||||
|
if (~src_reset_n) begin
|
||||||
|
src_valid <= 1'b0;
|
||||||
|
src_data <= {WIDTH{1'b0}};
|
||||||
|
end else begin
|
||||||
|
src_valid <= synchronized_valid;
|
||||||
|
src_data <= synchronized_valid ? sink_data_buffer : src_data;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module altera_jtag_dc_streaming #(
|
||||||
|
parameter PURPOSE = 0, // for discovery of services behind this JTAG Phy - 0
|
||||||
|
// for JTAG Phy, 1 for Packets to Master
|
||||||
|
parameter UPSTREAM_FIFO_SIZE = 0,
|
||||||
|
parameter DOWNSTREAM_FIFO_SIZE = 0,
|
||||||
|
parameter MGMT_CHANNEL_WIDTH = -1
|
||||||
|
) (
|
||||||
|
// Signals in the JTAG clock domain
|
||||||
|
input wire tck,
|
||||||
|
input wire tdi,
|
||||||
|
output wire tdo,
|
||||||
|
input wire [2:0] ir_in,
|
||||||
|
input wire virtual_state_cdr,
|
||||||
|
input wire virtual_state_sdr,
|
||||||
|
input wire virtual_state_udr,
|
||||||
|
|
||||||
|
input wire clk,
|
||||||
|
input wire reset_n,
|
||||||
|
output wire [7:0] source_data,
|
||||||
|
output wire source_valid,
|
||||||
|
input wire [7:0] sink_data,
|
||||||
|
input wire sink_valid,
|
||||||
|
output wire sink_ready,
|
||||||
|
output wire resetrequest,
|
||||||
|
output wire debug_reset,
|
||||||
|
output wire mgmt_valid,
|
||||||
|
output wire [(MGMT_CHANNEL_WIDTH>0?MGMT_CHANNEL_WIDTH:1)-1:0] mgmt_channel,
|
||||||
|
output wire mgmt_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// the tck to sysclk sync depth is fixed at 8
|
||||||
|
// 8 is the worst case scenario from our metastability analysis, and since
|
||||||
|
// using TCK serially is so slow we should have plenty of clock cycles.
|
||||||
|
localparam TCK_TO_SYSCLK_SYNC_DEPTH = 8;
|
||||||
|
// The clk to tck path is fixed at 3 deep for Synchronizer depth.
|
||||||
|
// Since the tck clock is so slow, no parameter is exposed.
|
||||||
|
localparam SYSCLK_TO_TCK_SYNC_DEPTH = 3;
|
||||||
|
|
||||||
|
wire jtag_clock_reset_n; // system reset is synchronized with tck
|
||||||
|
wire [7:0] jtag_source_data;
|
||||||
|
wire jtag_source_valid;
|
||||||
|
wire [7:0] jtag_sink_data;
|
||||||
|
wire jtag_sink_valid;
|
||||||
|
wire jtag_sink_ready;
|
||||||
|
|
||||||
|
/* Reset Synchronizer module.
|
||||||
|
*
|
||||||
|
* The SLD Node does not provide a reset for the TCK clock domain.
|
||||||
|
* Due to the handshaking nature of the Avalon-ST Clock Crosser,
|
||||||
|
* internal states need to be reset to 0 in order to guarantee proper
|
||||||
|
* functionality throughout resets.
|
||||||
|
*
|
||||||
|
* This reset block will asynchronously assert reset, and synchronously
|
||||||
|
* deassert reset for the tck clock domain.
|
||||||
|
*/
|
||||||
|
altera_std_synchronizer #(
|
||||||
|
.depth(SYSCLK_TO_TCK_SYNC_DEPTH)
|
||||||
|
) synchronizer (
|
||||||
|
.clk(tck),
|
||||||
|
.reset_n(reset_n),
|
||||||
|
.din(1'b1),
|
||||||
|
.dout(jtag_clock_reset_n)
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_jtag_streaming #(
|
||||||
|
.PURPOSE(PURPOSE),
|
||||||
|
.UPSTREAM_FIFO_SIZE(UPSTREAM_FIFO_SIZE),
|
||||||
|
.DOWNSTREAM_FIFO_SIZE(DOWNSTREAM_FIFO_SIZE),
|
||||||
|
.MGMT_CHANNEL_WIDTH(MGMT_CHANNEL_WIDTH)
|
||||||
|
) jtag_streaming (
|
||||||
|
.tck (tck),
|
||||||
|
.tdi (tdi),
|
||||||
|
.tdo (tdo),
|
||||||
|
.ir_in (ir_in),
|
||||||
|
.virtual_state_cdr(virtual_state_cdr),
|
||||||
|
.virtual_state_sdr(virtual_state_sdr),
|
||||||
|
.virtual_state_udr(virtual_state_udr),
|
||||||
|
|
||||||
|
.reset_n(jtag_clock_reset_n),
|
||||||
|
.source_data(jtag_source_data),
|
||||||
|
.source_valid(jtag_source_valid),
|
||||||
|
.sink_data(jtag_sink_data),
|
||||||
|
.sink_valid(jtag_sink_valid),
|
||||||
|
.sink_ready(jtag_sink_ready),
|
||||||
|
.clock_to_sample(clk),
|
||||||
|
.reset_to_sample(reset_n),
|
||||||
|
.resetrequest(resetrequest),
|
||||||
|
.debug_reset(debug_reset),
|
||||||
|
.mgmt_valid(mgmt_valid),
|
||||||
|
.mgmt_channel(mgmt_channel),
|
||||||
|
.mgmt_data(mgmt_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
// synchronization in both clock domain crossings takes place in the "clk" system clock domain!
|
||||||
|
|
||||||
|
altera_avalon_st_clock_crosser #(
|
||||||
|
.SYMBOLS_PER_BEAT(1),
|
||||||
|
.BITS_PER_SYMBOL(8),
|
||||||
|
.FORWARD_SYNC_DEPTH(SYSCLK_TO_TCK_SYNC_DEPTH),
|
||||||
|
.BACKWARD_SYNC_DEPTH(TCK_TO_SYSCLK_SYNC_DEPTH)
|
||||||
|
) sink_crosser (
|
||||||
|
.in_clk(clk),
|
||||||
|
.in_reset(~reset_n),
|
||||||
|
.in_data(sink_data),
|
||||||
|
.in_ready(sink_ready),
|
||||||
|
.in_valid(sink_valid),
|
||||||
|
.out_clk(tck),
|
||||||
|
.out_reset(~jtag_clock_reset_n),
|
||||||
|
.out_data(jtag_sink_data),
|
||||||
|
.out_ready(jtag_sink_ready),
|
||||||
|
.out_valid(jtag_sink_valid)
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_jtag_src_crosser #(
|
||||||
|
.SYNC_DEPTH(TCK_TO_SYSCLK_SYNC_DEPTH)
|
||||||
|
) source_crosser (
|
||||||
|
.sink_clk(tck),
|
||||||
|
.sink_reset_n(jtag_clock_reset_n),
|
||||||
|
.sink_valid(jtag_source_valid),
|
||||||
|
.sink_data(jtag_source_data),
|
||||||
|
.src_clk(clk),
|
||||||
|
.src_reset_n(reset_n),
|
||||||
|
.src_valid(source_valid),
|
||||||
|
.src_data(source_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
261
ip/altera/ddr3/altera_jtag_sld_node.v
Normal file
261
ip/altera/ddr3/altera_jtag_sld_node.v
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
// synopsys translate_on
|
||||||
|
module altera_jtag_sld_node (
|
||||||
|
ir_out,
|
||||||
|
tdo,
|
||||||
|
ir_in,
|
||||||
|
tck,
|
||||||
|
tdi,
|
||||||
|
virtual_state_cdr,
|
||||||
|
virtual_state_cir,
|
||||||
|
virtual_state_e1dr,
|
||||||
|
virtual_state_e2dr,
|
||||||
|
virtual_state_pdr,
|
||||||
|
virtual_state_sdr,
|
||||||
|
virtual_state_udr,
|
||||||
|
virtual_state_uir
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter TCK_FREQ_MHZ = 20;
|
||||||
|
localparam TCK_HALF_PERIOD_US = (1000/TCK_FREQ_MHZ)/2;
|
||||||
|
localparam IRWIDTH = 3;
|
||||||
|
|
||||||
|
input [IRWIDTH - 1:0] ir_out;
|
||||||
|
input tdo;
|
||||||
|
output reg [IRWIDTH - 1:0] ir_in;
|
||||||
|
output tck;
|
||||||
|
output reg tdi = 1'b0;
|
||||||
|
output virtual_state_cdr;
|
||||||
|
output virtual_state_cir;
|
||||||
|
output virtual_state_e1dr;
|
||||||
|
output virtual_state_e2dr;
|
||||||
|
output virtual_state_pdr;
|
||||||
|
output virtual_state_sdr;
|
||||||
|
output virtual_state_udr;
|
||||||
|
output virtual_state_uir;
|
||||||
|
|
||||||
|
// PHY Simulation signals
|
||||||
|
`ifndef ALTERA_RESERVED_QIS
|
||||||
|
reg simulation_clock;
|
||||||
|
reg sdrs;
|
||||||
|
reg cdr;
|
||||||
|
reg sdr;
|
||||||
|
reg e1dr;
|
||||||
|
reg udr;
|
||||||
|
reg [7:0] bit_index;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
||||||
|
// PHY Instantiation
|
||||||
|
`ifdef ALTERA_RESERVED_QIS
|
||||||
|
wire tdi_port;
|
||||||
|
wire [IRWIDTH - 1:0] ir_in_port;
|
||||||
|
always @(tdi_port)
|
||||||
|
tdi = tdi_port;
|
||||||
|
always @(ir_in_port)
|
||||||
|
ir_in = ir_in_port;
|
||||||
|
sld_virtual_jtag_basic sld_virtual_jtag_component (
|
||||||
|
.ir_out (ir_out),
|
||||||
|
.tdo (tdo),
|
||||||
|
.tdi (tdi_port),
|
||||||
|
.tck (tck),
|
||||||
|
.ir_in (ir_in_port),
|
||||||
|
.virtual_state_cir (virtual_state_cir),
|
||||||
|
.virtual_state_pdr (virtual_state_pdr),
|
||||||
|
.virtual_state_uir (virtual_state_uir),
|
||||||
|
.virtual_state_sdr (virtual_state_sdr),
|
||||||
|
.virtual_state_cdr (virtual_state_cdr),
|
||||||
|
.virtual_state_udr (virtual_state_udr),
|
||||||
|
.virtual_state_e1dr (virtual_state_e1dr),
|
||||||
|
.virtual_state_e2dr (virtual_state_e2dr)
|
||||||
|
// synopsys translate_off
|
||||||
|
,
|
||||||
|
.jtag_state_cdr (),
|
||||||
|
.jtag_state_cir (),
|
||||||
|
.jtag_state_e1dr (),
|
||||||
|
.jtag_state_e1ir (),
|
||||||
|
.jtag_state_e2dr (),
|
||||||
|
.jtag_state_e2ir (),
|
||||||
|
.jtag_state_pdr (),
|
||||||
|
.jtag_state_pir (),
|
||||||
|
.jtag_state_rti (),
|
||||||
|
.jtag_state_sdr (),
|
||||||
|
.jtag_state_sdrs (),
|
||||||
|
.jtag_state_sir (),
|
||||||
|
.jtag_state_sirs (),
|
||||||
|
.jtag_state_tlr (),
|
||||||
|
.jtag_state_udr (),
|
||||||
|
.jtag_state_uir (),
|
||||||
|
.tms ()
|
||||||
|
// synopsys translate_on
|
||||||
|
);
|
||||||
|
defparam
|
||||||
|
sld_virtual_jtag_component.sld_mfg_id = 110,
|
||||||
|
sld_virtual_jtag_component.sld_type_id = 132,
|
||||||
|
sld_virtual_jtag_component.sld_version = 1,
|
||||||
|
sld_virtual_jtag_component.sld_auto_instance_index = "YES",
|
||||||
|
sld_virtual_jtag_component.sld_instance_index = 0,
|
||||||
|
sld_virtual_jtag_component.sld_ir_width = IRWIDTH,
|
||||||
|
sld_virtual_jtag_component.sld_sim_action = "",
|
||||||
|
sld_virtual_jtag_component.sld_sim_n_scan = 0,
|
||||||
|
sld_virtual_jtag_component.sld_sim_total_length = 0;
|
||||||
|
`endif
|
||||||
|
|
||||||
|
// PHY Simulation
|
||||||
|
`ifndef ALTERA_RESERVED_QIS
|
||||||
|
|
||||||
|
localparam DATA = 0;
|
||||||
|
localparam LOOPBACK = 1;
|
||||||
|
localparam DEBUG = 2;
|
||||||
|
localparam INFO = 3;
|
||||||
|
localparam CONTROL = 4;
|
||||||
|
localparam MGMT = 5;
|
||||||
|
|
||||||
|
always
|
||||||
|
//#TCK_HALF_PERIOD_US simulation_clock = $random;
|
||||||
|
#TCK_HALF_PERIOD_US simulation_clock = ~simulation_clock;
|
||||||
|
|
||||||
|
assign tck = simulation_clock;
|
||||||
|
assign virtual_state_cdr = cdr;
|
||||||
|
assign virtual_state_sdr = sdr;
|
||||||
|
assign virtual_state_e1dr = e1dr;
|
||||||
|
assign virtual_state_udr = udr;
|
||||||
|
|
||||||
|
task reset_jtag_state;
|
||||||
|
begin
|
||||||
|
simulation_clock = 0;
|
||||||
|
enter_data_mode;
|
||||||
|
clear_states_async;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_data_mode;
|
||||||
|
begin
|
||||||
|
ir_in = DATA;
|
||||||
|
clear_states;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_loopback_mode;
|
||||||
|
begin
|
||||||
|
ir_in = LOOPBACK;
|
||||||
|
clear_states;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_debug_mode;
|
||||||
|
begin
|
||||||
|
ir_in = DEBUG;
|
||||||
|
clear_states;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_info_mode;
|
||||||
|
begin
|
||||||
|
ir_in = INFO;
|
||||||
|
clear_states;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_control_mode;
|
||||||
|
begin
|
||||||
|
ir_in = CONTROL;
|
||||||
|
clear_states;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_mgmt_mode;
|
||||||
|
begin
|
||||||
|
ir_in = MGMT;
|
||||||
|
clear_states;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_sdrs_state;
|
||||||
|
begin
|
||||||
|
{sdrs, cdr, sdr, e1dr, udr} = 5'b10000;
|
||||||
|
tdi = 1'b0;
|
||||||
|
@(posedge tck);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_cdr_state;
|
||||||
|
begin
|
||||||
|
{sdrs, cdr, sdr, e1dr, udr} = 5'b01000;
|
||||||
|
tdi = 1'b0;
|
||||||
|
@(posedge tck);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_e1dr_state;
|
||||||
|
begin
|
||||||
|
{sdrs, cdr, sdr, e1dr, udr} = 5'b00010;
|
||||||
|
tdi = 1'b0;
|
||||||
|
@(posedge tck);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task enter_udr_state;
|
||||||
|
begin
|
||||||
|
{sdrs, cdr, sdr, e1dr, udr} = 5'b00001;
|
||||||
|
tdi = 1'b0;
|
||||||
|
@(posedge tck);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task clear_states;
|
||||||
|
begin
|
||||||
|
clear_states_async;
|
||||||
|
@(posedge tck);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task clear_states_async;
|
||||||
|
begin
|
||||||
|
{cdr, sdr, e1dr, udr} = 4'b0000;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task shift_one_bit;
|
||||||
|
input bit_to_send;
|
||||||
|
output reg bit_received;
|
||||||
|
begin
|
||||||
|
{cdr, sdr, e1dr, udr} = 4'b0100;
|
||||||
|
tdi = bit_to_send;
|
||||||
|
@(posedge tck);
|
||||||
|
bit_received = tdo;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task shift_one_byte;
|
||||||
|
input [7:0] byte_to_send;
|
||||||
|
output reg [7:0] byte_received;
|
||||||
|
integer i;
|
||||||
|
reg bit_received;
|
||||||
|
begin
|
||||||
|
for (i=0; i<8; i=i+1)
|
||||||
|
begin
|
||||||
|
bit_index = i;
|
||||||
|
shift_one_bit(byte_to_send[i], bit_received);
|
||||||
|
byte_received[i] = bit_received;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
endmodule
|
634
ip/altera/ddr3/altera_jtag_streaming.v
Normal file
634
ip/altera/ddr3/altera_jtag_streaming.v
Normal file
@ -0,0 +1,634 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
// synopsys translate_on
|
||||||
|
|
||||||
|
module altera_jtag_streaming #(
|
||||||
|
parameter PURPOSE = 0,
|
||||||
|
parameter UPSTREAM_FIFO_SIZE = 0,
|
||||||
|
parameter DOWNSTREAM_FIFO_SIZE = 0,
|
||||||
|
parameter MGMT_CHANNEL_WIDTH = -1
|
||||||
|
) (
|
||||||
|
// JTAG Signals
|
||||||
|
input wire tck,
|
||||||
|
input wire tdi,
|
||||||
|
output reg tdo,
|
||||||
|
input wire [2:0] ir_in,
|
||||||
|
input wire virtual_state_cdr,
|
||||||
|
input wire virtual_state_sdr,
|
||||||
|
input wire virtual_state_udr,
|
||||||
|
|
||||||
|
input wire reset_n,
|
||||||
|
// Source Signals
|
||||||
|
output wire [7:0] source_data,
|
||||||
|
output wire source_valid,
|
||||||
|
// Sink Signals
|
||||||
|
input wire [7:0] sink_data,
|
||||||
|
input wire sink_valid,
|
||||||
|
output wire sink_ready,
|
||||||
|
// Clock Debug Signals
|
||||||
|
input wire clock_to_sample,
|
||||||
|
input wire reset_to_sample,
|
||||||
|
// Resetrequest signal
|
||||||
|
output reg resetrequest,
|
||||||
|
// Debug reset and management channel
|
||||||
|
output wire debug_reset,
|
||||||
|
output reg mgmt_valid,
|
||||||
|
output reg [(MGMT_CHANNEL_WIDTH>0?MGMT_CHANNEL_WIDTH:1)-1:0] mgmt_channel,
|
||||||
|
output reg mgmt_data
|
||||||
|
);
|
||||||
|
|
||||||
|
// function to calculate log2, floored.
|
||||||
|
function integer flog2;
|
||||||
|
input [31:0] Depth;
|
||||||
|
integer i;
|
||||||
|
begin
|
||||||
|
i = Depth;
|
||||||
|
if ( i <= 0 ) flog2 = 0;
|
||||||
|
else begin
|
||||||
|
for(flog2 = -1; i > 0; flog2 = flog2 + 1)
|
||||||
|
i = i >> 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction // flog2
|
||||||
|
|
||||||
|
localparam UPSTREAM_ENCODED_SIZE = flog2(UPSTREAM_FIFO_SIZE);
|
||||||
|
localparam DOWNSTREAM_ENCODED_SIZE = flog2(DOWNSTREAM_FIFO_SIZE);
|
||||||
|
|
||||||
|
localparam TCK_TO_SYSCLK_SYNC_DEPTH = 8;
|
||||||
|
localparam SYSCLK_TO_TCK_SYNC_DEPTH = 3;
|
||||||
|
|
||||||
|
// IR values determine the operating modes
|
||||||
|
localparam DATA = 0;
|
||||||
|
localparam LOOPBACK = 1;
|
||||||
|
localparam DEBUG = 2;
|
||||||
|
localparam INFO = 3;
|
||||||
|
localparam CONTROL = 4;
|
||||||
|
localparam MGMT = 5;
|
||||||
|
|
||||||
|
// Operating Modes:
|
||||||
|
// Data - To send data which its size and valid position are encoded in the header bytes of the data stream
|
||||||
|
// Loopback - To become a JTAG loopback with a bypass register
|
||||||
|
// Debug - To read the values of the clock sensing, clock sampling and reset sampling
|
||||||
|
// Info - To read the parameterized values that describe the components connected to JTAG Phy which is of great interest to the driver
|
||||||
|
// Control - To set the offset of bit-padding and to do a reset request
|
||||||
|
// Mgmt - Send management commands (resets mostly) to agents
|
||||||
|
|
||||||
|
localparam IRWIDTH = 3;
|
||||||
|
|
||||||
|
// State machine encoding for write_state
|
||||||
|
localparam ST_BYPASS = 'h0;
|
||||||
|
localparam ST_HEADER_1 = 'h1;
|
||||||
|
localparam ST_HEADER_2 = 'h2;
|
||||||
|
localparam ST_WRITE_DATA = 'h3;
|
||||||
|
|
||||||
|
// State machine encoding for read_state
|
||||||
|
localparam ST_HEADER = 'h0;
|
||||||
|
localparam ST_PADDED = 'h1;
|
||||||
|
localparam ST_READ_DATA = 'h2;
|
||||||
|
|
||||||
|
reg [1:0] write_state = ST_BYPASS;
|
||||||
|
reg [1:0] read_state = ST_HEADER;
|
||||||
|
|
||||||
|
reg [ 7:0] dr_data_in = 'b0;
|
||||||
|
reg [ 7:0] dr_data_out = 'b0;
|
||||||
|
reg dr_loopback = 'b0;
|
||||||
|
reg [ 2:0] dr_debug = 'b0;
|
||||||
|
reg [10:0] dr_info = 'b0;
|
||||||
|
reg [ 8:0] dr_control = 'b0;
|
||||||
|
reg [MGMT_CHANNEL_WIDTH+2:0] dr_mgmt = 'b0;
|
||||||
|
|
||||||
|
reg [ 8:0] padded_bit_counter = 'b0;
|
||||||
|
reg [ 7:0] bypass_bit_counter = 'b0;
|
||||||
|
reg [ 2:0] write_data_bit_counter = 'b0;
|
||||||
|
reg [ 2:0] read_data_bit_counter = 'b0;
|
||||||
|
reg [ 3:0] header_in_bit_counter = 'b0;
|
||||||
|
reg [ 3:0] header_out_bit_counter = 'b0;
|
||||||
|
reg [18:0] scan_length_byte_counter = 'b0;
|
||||||
|
reg [18:0] valid_write_data_length_byte_counter = 'b0;
|
||||||
|
|
||||||
|
reg write_data_valid = 'b0;
|
||||||
|
reg read_data_valid = 'b0;
|
||||||
|
reg read_data_all_valid = 'b0;
|
||||||
|
|
||||||
|
reg decode_header_1 = 'b0;
|
||||||
|
reg decode_header_2 = 'b0;
|
||||||
|
|
||||||
|
wire write_data_byte_aligned;
|
||||||
|
wire read_data_byte_aligned;
|
||||||
|
wire padded_bit_byte_aligned;
|
||||||
|
wire bytestream_end;
|
||||||
|
|
||||||
|
assign write_data_byte_aligned = (write_data_bit_counter == 1);
|
||||||
|
assign read_data_byte_aligned = (read_data_bit_counter == 1);
|
||||||
|
assign padded_bit_byte_aligned = (padded_bit_counter[2:0] == 'b0);
|
||||||
|
assign bytestream_end = (scan_length_byte_counter == 'b0);
|
||||||
|
|
||||||
|
reg [ 7:0] offset = 'b0;
|
||||||
|
reg [15:0] header_in = 'b0;
|
||||||
|
|
||||||
|
reg [9:0] scan_length = 'b0;
|
||||||
|
reg [2:0] read_data_length = 'b0;
|
||||||
|
reg [2:0] write_data_length = 'b0;
|
||||||
|
|
||||||
|
wire [7:0] idle_inserter_sink_data;
|
||||||
|
wire idle_inserter_sink_valid;
|
||||||
|
wire idle_inserter_sink_ready;
|
||||||
|
wire [7:0] idle_inserter_source_data;
|
||||||
|
reg idle_inserter_source_ready = 'b0;
|
||||||
|
reg [7:0] idle_remover_sink_data = 'b0;
|
||||||
|
reg idle_remover_sink_valid = 'b0;
|
||||||
|
wire [7:0] idle_remover_source_data;
|
||||||
|
wire idle_remover_source_valid;
|
||||||
|
|
||||||
|
assign source_data = idle_remover_source_data;
|
||||||
|
assign source_valid = idle_remover_source_valid;
|
||||||
|
assign sink_ready = idle_inserter_sink_ready;
|
||||||
|
assign idle_inserter_sink_data = sink_data;
|
||||||
|
assign idle_inserter_sink_valid = sink_valid;
|
||||||
|
|
||||||
|
reg clock_sensor = 'b0;
|
||||||
|
reg clock_to_sample_div2 = 'b0;
|
||||||
|
(* altera_attribute = {"-name GLOBAL_SIGNAL OFF"}*) reg clock_sense_reset_n = 'b1;
|
||||||
|
|
||||||
|
wire data_available;
|
||||||
|
|
||||||
|
assign data_available = sink_valid;
|
||||||
|
|
||||||
|
wire [18:0] decoded_scan_length;
|
||||||
|
wire [18:0] decoded_write_data_length;
|
||||||
|
wire [18:0] decoded_read_data_length;
|
||||||
|
|
||||||
|
assign decoded_scan_length = { scan_length, {8{1'b1}} };
|
||||||
|
// +-------------------+----------------+---------------------+
|
||||||
|
// | scan_length | Length (bytes) | decoded_scan_length |
|
||||||
|
// +-------------------+----------------+---------------------+
|
||||||
|
// | 0x0 | 256 | 0x0ff (255) |
|
||||||
|
// | 0x1 | 512 | 0x1ff (511) |
|
||||||
|
// | 0x2 | 768 | 0x2ff (767) |
|
||||||
|
// | . | . | . |
|
||||||
|
// | 0x3ff | 256k | 0x3ff (256k-1) |
|
||||||
|
// +-------------------+----------------+---------------------+
|
||||||
|
|
||||||
|
// TODO: use look up table to save LEs?
|
||||||
|
// Decoded value is correct except for 0x7
|
||||||
|
assign decoded_write_data_length = (write_data_length == 0) ? 19'h0 : (19'h00080 << write_data_length);
|
||||||
|
assign decoded_read_data_length = (read_data_length == 0) ? 19'h0 : (19'h00080 << read_data_length);
|
||||||
|
// +-------------------+---------------+---------------------------+
|
||||||
|
// | read_data_length | Length | decoded_read_data_length |
|
||||||
|
// | write_data_length | (bytes) | decoded_write_data_length |
|
||||||
|
// +-------------------+---------------+---------------------------+
|
||||||
|
// | 0x0 | 0 | 0x0000 (0) |
|
||||||
|
// | 0x1 | 256 | 0x0100 (256) |
|
||||||
|
// | 0x2 | 512 | 0x0200 (512) |
|
||||||
|
// | 0x3 | 1k | 0x0400 (1024) |
|
||||||
|
// | 0x4 | 2k | 0x0800 (2048) |
|
||||||
|
// | 0x5 | 4k | 0x1000 (4096) |
|
||||||
|
// | 0x6 | 8k | 0x2000 (8192) |
|
||||||
|
// | 0x7 | scan_length | invalid |
|
||||||
|
// +-------------------+---------------+---------------------------+
|
||||||
|
|
||||||
|
wire clock_sensor_sync;
|
||||||
|
wire reset_to_sample_sync;
|
||||||
|
wire clock_to_sample_div2_sync;
|
||||||
|
wire clock_sense_reset_n_sync;
|
||||||
|
|
||||||
|
|
||||||
|
altera_std_synchronizer #(.depth(SYSCLK_TO_TCK_SYNC_DEPTH)) clock_sensor_synchronizer (
|
||||||
|
.clk(tck),
|
||||||
|
.reset_n(1'b1),
|
||||||
|
.din(clock_sensor),
|
||||||
|
.dout(clock_sensor_sync));
|
||||||
|
|
||||||
|
altera_std_synchronizer #(.depth(SYSCLK_TO_TCK_SYNC_DEPTH)) reset_to_sample_synchronizer (
|
||||||
|
.clk(tck),
|
||||||
|
.reset_n(1'b1),
|
||||||
|
.din(reset_to_sample),
|
||||||
|
.dout(reset_to_sample_sync));
|
||||||
|
|
||||||
|
altera_std_synchronizer #(.depth(SYSCLK_TO_TCK_SYNC_DEPTH)) clock_to_sample_div2_synchronizer (
|
||||||
|
.clk(tck),
|
||||||
|
.reset_n(1'b1),
|
||||||
|
.din(clock_to_sample_div2),
|
||||||
|
.dout(clock_to_sample_div2_sync));
|
||||||
|
|
||||||
|
altera_std_synchronizer #(.depth(TCK_TO_SYSCLK_SYNC_DEPTH)) clock_sense_reset_n_synchronizer (
|
||||||
|
.clk(clock_to_sample),
|
||||||
|
.reset_n(clock_sense_reset_n),
|
||||||
|
.din(1'b1),
|
||||||
|
.dout(clock_sense_reset_n_sync));
|
||||||
|
|
||||||
|
always @ (posedge clock_to_sample or negedge clock_sense_reset_n_sync) begin
|
||||||
|
if (~clock_sense_reset_n_sync) begin
|
||||||
|
clock_sensor <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
clock_sensor <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge clock_to_sample) begin
|
||||||
|
clock_to_sample_div2 <= ~clock_to_sample_div2;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (posedge tck) begin
|
||||||
|
|
||||||
|
idle_remover_sink_valid <= 1'b0;
|
||||||
|
idle_inserter_source_ready <= 1'b0;
|
||||||
|
|
||||||
|
// Data mode sourcing (write)
|
||||||
|
|
||||||
|
// offset(rounded 8) m-i i 16 offset
|
||||||
|
// +------------+-----------+------------------+--------+------------+
|
||||||
|
// tdi -> | padded_bit | undefined | valid_write_data | header | bypass_bit |
|
||||||
|
// +------------+-----------+------------------+--------+------------+
|
||||||
|
// Data mode DR data stream write format (as seen by hardware)
|
||||||
|
//
|
||||||
|
if (ir_in == DATA) begin
|
||||||
|
|
||||||
|
|
||||||
|
if (virtual_state_cdr) begin
|
||||||
|
if (offset == 'b0) begin
|
||||||
|
write_state <= ST_HEADER_1;
|
||||||
|
end else begin
|
||||||
|
write_state <= ST_BYPASS;
|
||||||
|
end
|
||||||
|
// 8-bit bypass_bit_counter
|
||||||
|
bypass_bit_counter <= offset;
|
||||||
|
// 4-bit header_in_bit_counter
|
||||||
|
header_in_bit_counter <= 15;
|
||||||
|
// 3-bit write_data_bit_counter
|
||||||
|
write_data_bit_counter <= 0;
|
||||||
|
// Reset the registers
|
||||||
|
// TODO: not necessarily all, reduce LE
|
||||||
|
decode_header_1 <= 1'b0;
|
||||||
|
decode_header_2 <= 1'b0;
|
||||||
|
read_data_all_valid <= 1'b0;
|
||||||
|
valid_write_data_length_byte_counter <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
// Discard bypass bits, then decode the 16-bit header
|
||||||
|
// 3 3 10
|
||||||
|
// +-------------------+------------------+-------------+
|
||||||
|
// | write_data_length | read_data_length | scan_length |
|
||||||
|
// +-------------------+------------------+-------------+
|
||||||
|
// Header format
|
||||||
|
|
||||||
|
case (write_state)
|
||||||
|
ST_BYPASS: begin
|
||||||
|
// Discard the bypass bit
|
||||||
|
bypass_bit_counter <= bypass_bit_counter - 1'b1;
|
||||||
|
if (bypass_bit_counter == 1) begin
|
||||||
|
write_state <= ST_HEADER_1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// Shift the scan_length and read_data_length
|
||||||
|
ST_HEADER_1: begin
|
||||||
|
// TODO: header_in can be shorter
|
||||||
|
// Shift into header_in
|
||||||
|
header_in <= {tdi, header_in[15:1]};
|
||||||
|
header_in_bit_counter <= header_in_bit_counter - 1'b1;
|
||||||
|
if (header_in_bit_counter == 3) begin
|
||||||
|
read_data_length <= {tdi, header_in[15:14]};
|
||||||
|
scan_length <= header_in[13:4];
|
||||||
|
write_state <= ST_HEADER_2;
|
||||||
|
decode_header_1 <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// Shift the write_data_length
|
||||||
|
ST_HEADER_2: begin
|
||||||
|
// Shift into header_in
|
||||||
|
header_in <= {tdi, header_in[15:1]};
|
||||||
|
header_in_bit_counter <= header_in_bit_counter - 1'b1;
|
||||||
|
// Decode read_data_length and scan_length
|
||||||
|
if (decode_header_1) begin
|
||||||
|
decode_header_1 <= 1'b0;
|
||||||
|
// Set read_data_all_valid
|
||||||
|
if (read_data_length == 3'b111) begin
|
||||||
|
read_data_all_valid <= 1'b1;
|
||||||
|
end
|
||||||
|
// Load scan_length_byte_counter
|
||||||
|
scan_length_byte_counter <= decoded_scan_length;
|
||||||
|
end
|
||||||
|
if (header_in_bit_counter == 0) begin
|
||||||
|
write_data_length <= {tdi, header_in[15:14]};
|
||||||
|
write_state <= ST_WRITE_DATA;
|
||||||
|
decode_header_2 <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// Shift the valid_write_data
|
||||||
|
ST_WRITE_DATA: begin
|
||||||
|
// Shift into dr_data_in
|
||||||
|
dr_data_in <= {tdi, dr_data_in[7:1]};
|
||||||
|
// Decode write_data_length
|
||||||
|
if (decode_header_2) begin
|
||||||
|
decode_header_2 <= 1'b0;
|
||||||
|
// Load valid_write_data_length_byte_counter
|
||||||
|
case (write_data_length)
|
||||||
|
3'b111: valid_write_data_length_byte_counter <= decoded_scan_length + 1'b1;
|
||||||
|
3'b000: valid_write_data_length_byte_counter <= 'b0;
|
||||||
|
default: valid_write_data_length_byte_counter <= decoded_write_data_length;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
write_data_bit_counter <= write_data_bit_counter - 1'b1;
|
||||||
|
write_data_valid <= (valid_write_data_length_byte_counter != 0);
|
||||||
|
// Feed the data to the idle remover
|
||||||
|
if (write_data_byte_aligned && write_data_valid) begin
|
||||||
|
valid_write_data_length_byte_counter <= valid_write_data_length_byte_counter - 1'b1;
|
||||||
|
idle_remover_sink_valid <= 1'b1;
|
||||||
|
idle_remover_sink_data <= {tdi, dr_data_in[7:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// Data mode sinking (read)
|
||||||
|
|
||||||
|
// i m-i offset(rounded 8) 16
|
||||||
|
// +-----------------+-----------+------------+--------+
|
||||||
|
// | valid_read_data | undefined | padded_bit | header | -> tdo
|
||||||
|
// +-----------------+-----------+------------+--------+
|
||||||
|
// Data mode DR data stream read format (as seen by hardware)
|
||||||
|
//
|
||||||
|
if (ir_in == DATA) begin
|
||||||
|
|
||||||
|
if (virtual_state_cdr) begin
|
||||||
|
|
||||||
|
read_state <= ST_HEADER;
|
||||||
|
// Offset is rounded to nearest ceiling x8 to byte-align padded bits
|
||||||
|
// 9-bit padded_bit_counter
|
||||||
|
if (|offset[2:0]) begin
|
||||||
|
padded_bit_counter[8:3] <= offset[7:3] + 1'b1;
|
||||||
|
padded_bit_counter[2:0] <= 3'b0;
|
||||||
|
end else begin
|
||||||
|
padded_bit_counter <= {1'b0, offset};
|
||||||
|
end
|
||||||
|
// 4-bit header_out_bit_counter
|
||||||
|
header_out_bit_counter <= 0;
|
||||||
|
// 3-bit read_data_bit_counter
|
||||||
|
read_data_bit_counter <= 0;
|
||||||
|
// Load the data_available bit into header
|
||||||
|
dr_data_out <= {{7{1'b0}}, data_available};
|
||||||
|
read_data_valid <= 0;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
// 10 1
|
||||||
|
// +-----------------------------------+----------------+
|
||||||
|
// | reserved | data_available |
|
||||||
|
// +-----------------------------------+----------------+
|
||||||
|
// Header format
|
||||||
|
|
||||||
|
dr_data_out <= {1'b0, dr_data_out[7:1]};
|
||||||
|
case (read_state)
|
||||||
|
// Shift the scan_length and read_data_length
|
||||||
|
ST_HEADER: begin
|
||||||
|
header_out_bit_counter <= header_out_bit_counter - 1'b1;
|
||||||
|
// Retrieve data from idle inserter for the next shift if no paddded bits
|
||||||
|
if (header_out_bit_counter == 2) begin
|
||||||
|
if (padded_bit_counter == 0) begin
|
||||||
|
idle_inserter_source_ready <= read_data_all_valid;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if (header_out_bit_counter == 1) begin
|
||||||
|
if (padded_bit_counter == 0) begin
|
||||||
|
read_state <= ST_READ_DATA;
|
||||||
|
read_data_valid <= read_data_all_valid || (scan_length_byte_counter<=decoded_read_data_length+1);
|
||||||
|
dr_data_out <= read_data_all_valid ? idle_inserter_source_data : 8'h4a;
|
||||||
|
end else begin
|
||||||
|
read_state <= ST_PADDED;
|
||||||
|
padded_bit_counter <= padded_bit_counter - 1'b1;
|
||||||
|
idle_inserter_source_ready <= 1'b0;
|
||||||
|
dr_data_out <= 8'h4a;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ST_PADDED: begin
|
||||||
|
padded_bit_counter <= padded_bit_counter - 1'b1;
|
||||||
|
if (padded_bit_byte_aligned) begin
|
||||||
|
// Load idle character into data register
|
||||||
|
dr_data_out <= 8'h4a;
|
||||||
|
end
|
||||||
|
// Retrieve data from idle inserter for the next shift when padded bits finish
|
||||||
|
if (padded_bit_counter == 1) begin
|
||||||
|
idle_inserter_source_ready <= read_data_all_valid;
|
||||||
|
end
|
||||||
|
if (padded_bit_counter == 0) begin // TODO: might make use of (padded_bit_counter[8:3]&padded_bit_byte_aligned)
|
||||||
|
read_state <= ST_READ_DATA;
|
||||||
|
read_data_valid <= read_data_all_valid || (scan_length_byte_counter<=decoded_read_data_length+1);
|
||||||
|
dr_data_out <= read_data_all_valid ? idle_inserter_source_data : 8'h4a;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ST_READ_DATA: begin
|
||||||
|
read_data_bit_counter <= read_data_bit_counter - 1'b1;
|
||||||
|
// Retrieve data from idle inserter just before read_data_byte_aligned
|
||||||
|
if (read_data_bit_counter == 2) begin
|
||||||
|
// Assert ready to retrieve data from idle inserter only when the bytestream has not ended,
|
||||||
|
// data is valid (idle_inserter is always valid) and data is needed (read_data_valid)
|
||||||
|
idle_inserter_source_ready <= bytestream_end ? 1'b0 : read_data_valid;
|
||||||
|
end
|
||||||
|
if (read_data_byte_aligned) begin
|
||||||
|
// Note that bytestream_end is driven by scan_length_byte_counter
|
||||||
|
if (~bytestream_end) begin
|
||||||
|
scan_length_byte_counter <= scan_length_byte_counter - 1'b1;
|
||||||
|
end
|
||||||
|
read_data_valid <= read_data_all_valid || (scan_length_byte_counter<=decoded_read_data_length+1);
|
||||||
|
// Load idle character if bytestream has ended, else get data from the idle inserter
|
||||||
|
dr_data_out <= (read_data_valid & ~bytestream_end) ? idle_inserter_source_data : 8'h4a;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// Loopback mode
|
||||||
|
if (ir_in == LOOPBACK) begin
|
||||||
|
if (virtual_state_cdr) begin
|
||||||
|
dr_loopback <= 1'b0; // capture 0
|
||||||
|
end
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
// Shift dr_loopback
|
||||||
|
dr_loopback <= tdi;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Debug mode
|
||||||
|
if (ir_in == DEBUG) begin
|
||||||
|
if (virtual_state_cdr) begin
|
||||||
|
dr_debug <= {clock_sensor_sync, clock_to_sample_div2_sync, reset_to_sample_sync};
|
||||||
|
end
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
// Shift dr_debug
|
||||||
|
dr_debug <= {1'b0, dr_debug[2:1]}; // tdi is ignored
|
||||||
|
end
|
||||||
|
if (virtual_state_udr) begin
|
||||||
|
clock_sense_reset_n <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
clock_sense_reset_n <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Info mode
|
||||||
|
if (ir_in == INFO) begin
|
||||||
|
if (virtual_state_cdr) begin
|
||||||
|
dr_info <= {PURPOSE[2:0], UPSTREAM_ENCODED_SIZE[3:0], DOWNSTREAM_ENCODED_SIZE[3:0]};
|
||||||
|
end
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
// Shift dr_info
|
||||||
|
dr_info <= {1'b0, dr_info[10:1]}; // tdi is ignored
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Control mode
|
||||||
|
if (ir_in == CONTROL) begin
|
||||||
|
if (virtual_state_cdr) begin
|
||||||
|
dr_control <= 'b0; // capture 0
|
||||||
|
end
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
// Shift dr_control
|
||||||
|
dr_control <= {tdi, dr_control[8:1]};
|
||||||
|
end
|
||||||
|
if (virtual_state_udr) begin
|
||||||
|
// Update resetrequest and offset
|
||||||
|
{resetrequest, offset} <= dr_control;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ * begin
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
case (ir_in)
|
||||||
|
DATA: tdo <= dr_data_out[0];
|
||||||
|
LOOPBACK: tdo <= dr_loopback;
|
||||||
|
DEBUG: tdo <= dr_debug[0];
|
||||||
|
INFO: tdo <= dr_info[0];
|
||||||
|
CONTROL: tdo <= dr_control[0];
|
||||||
|
MGMT: tdo <= dr_mgmt[0];
|
||||||
|
default: tdo <= 1'b0;
|
||||||
|
endcase
|
||||||
|
end else begin
|
||||||
|
tdo <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Idle Remover
|
||||||
|
altera_avalon_st_idle_remover idle_remover (
|
||||||
|
// Interface: clk
|
||||||
|
.clk (tck),
|
||||||
|
.reset_n (reset_n),
|
||||||
|
|
||||||
|
// Interface: ST in
|
||||||
|
.in_ready (), // left disconnected
|
||||||
|
.in_valid (idle_remover_sink_valid),
|
||||||
|
.in_data (idle_remover_sink_data),
|
||||||
|
|
||||||
|
// Interface: ST out
|
||||||
|
.out_ready (1'b1), // downstream is expected to be always ready
|
||||||
|
.out_valid (idle_remover_source_valid),
|
||||||
|
.out_data (idle_remover_source_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Idle Inserter
|
||||||
|
altera_avalon_st_idle_inserter idle_inserter (
|
||||||
|
// Interface: clk
|
||||||
|
.clk (tck),
|
||||||
|
.reset_n (reset_n),
|
||||||
|
|
||||||
|
// Interface: ST in
|
||||||
|
.in_ready (idle_inserter_sink_ready),
|
||||||
|
.in_valid (idle_inserter_sink_valid),
|
||||||
|
.in_data (idle_inserter_sink_data),
|
||||||
|
|
||||||
|
// Interface: ST out
|
||||||
|
.out_ready (idle_inserter_source_ready),
|
||||||
|
.out_valid (),
|
||||||
|
.out_data (idle_inserter_source_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (MGMT_CHANNEL_WIDTH > 0)
|
||||||
|
begin : has_mgmt
|
||||||
|
reg [MGMT_CHANNEL_WIDTH+2:0] mgmt_out = 'b0;
|
||||||
|
reg mgmt_toggle = 1'b0;
|
||||||
|
wire mgmt_toggle_sync;
|
||||||
|
reg mgmt_toggle_prev;
|
||||||
|
always @ (posedge tck) begin
|
||||||
|
// Debug mode
|
||||||
|
if (ir_in == MGMT) begin
|
||||||
|
if (virtual_state_cdr) begin
|
||||||
|
dr_mgmt <= 'b0;
|
||||||
|
dr_mgmt[MGMT_CHANNEL_WIDTH+2] <= 1'b1;
|
||||||
|
end
|
||||||
|
if (virtual_state_sdr) begin
|
||||||
|
// Shift dr_debug
|
||||||
|
dr_mgmt <= {tdi, dr_mgmt[MGMT_CHANNEL_WIDTH+2:1]};
|
||||||
|
end
|
||||||
|
if (virtual_state_udr) begin
|
||||||
|
mgmt_out <= dr_mgmt;
|
||||||
|
mgmt_toggle <= mgmt_out[MGMT_CHANNEL_WIDTH+2] ? 1'b0 : ~mgmt_toggle;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
altera_std_synchronizer #(.depth(TCK_TO_SYSCLK_SYNC_DEPTH)) debug_reset_synchronizer (
|
||||||
|
.clk(clock_to_sample),
|
||||||
|
.reset_n(1'b1),
|
||||||
|
.din(mgmt_out[MGMT_CHANNEL_WIDTH+2]),
|
||||||
|
.dout(debug_reset));
|
||||||
|
|
||||||
|
altera_std_synchronizer #(.depth(TCK_TO_SYSCLK_SYNC_DEPTH)) mgmt_toggle_synchronizer (
|
||||||
|
.clk(clock_to_sample),
|
||||||
|
.reset_n(1'b1),
|
||||||
|
.din(mgmt_toggle),
|
||||||
|
.dout(mgmt_toggle_sync));
|
||||||
|
|
||||||
|
always @ (posedge clock_to_sample or posedge debug_reset) begin
|
||||||
|
if (debug_reset) begin
|
||||||
|
mgmt_valid <= 1'b0;
|
||||||
|
mgmt_toggle_prev <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if ((mgmt_toggle_sync ^ mgmt_toggle_prev) && mgmt_out[MGMT_CHANNEL_WIDTH+1]) begin
|
||||||
|
mgmt_valid <= 1'b1;
|
||||||
|
mgmt_channel <= mgmt_out[MGMT_CHANNEL_WIDTH:1];
|
||||||
|
mgmt_data <= mgmt_out[0];
|
||||||
|
end else begin
|
||||||
|
mgmt_valid <= 1'b0;
|
||||||
|
end
|
||||||
|
mgmt_toggle_prev <= mgmt_toggle_sync;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin : no_mgmt
|
||||||
|
always @ (posedge tck) begin
|
||||||
|
dr_mgmt[0] <= 1'b0;
|
||||||
|
end
|
||||||
|
assign debug_reset = 1'b0;
|
||||||
|
always @ (posedge clock_to_sample) begin
|
||||||
|
mgmt_valid <= 1'b0;
|
||||||
|
mgmt_data <= 'b0;
|
||||||
|
mgmt_channel <= 'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
83
ip/altera/ddr3/altera_mem_if_dll_cyclonev.sv
Normal file
83
ip/altera/ddr3/altera_mem_if_dll_cyclonev.sv
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// ********************************************************************************************************************************
|
||||||
|
// This file instantiates the DLL.
|
||||||
|
// ********************************************************************************************************************************
|
||||||
|
|
||||||
|
`timescale 1 ps / 1 ps
|
||||||
|
|
||||||
|
(* altera_attribute = "-name IP_TOOL_NAME altera_mem_if_dll; -name IP_TOOL_VERSION 15.1; -name FITTER_ADJUST_HC_SHORT_PATH_GUARDBAND 100; -name ALLOW_SYNCH_CTRL_USAGE OFF; -name AUTO_CLOCK_ENABLE_RECOGNITION OFF; -name AUTO_SHIFT_REGISTER_RECOGNITION OFF" *)
|
||||||
|
|
||||||
|
|
||||||
|
module altera_mem_if_dll_cyclonev (
|
||||||
|
clk,
|
||||||
|
|
||||||
|
|
||||||
|
dll_pll_locked,
|
||||||
|
dll_delayctrl
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
parameter DLL_DELAY_CTRL_WIDTH = 0;
|
||||||
|
parameter DELAY_BUFFER_MODE = "";
|
||||||
|
parameter DELAY_CHAIN_LENGTH = 0;
|
||||||
|
parameter DLL_INPUT_FREQUENCY_PS_STR = "";
|
||||||
|
parameter DLL_OFFSET_CTRL_WIDTH = 0;
|
||||||
|
|
||||||
|
|
||||||
|
input clk; // DLL input clock
|
||||||
|
input dll_pll_locked;
|
||||||
|
output [DLL_DELAY_CTRL_WIDTH-1:0] dll_delayctrl;
|
||||||
|
|
||||||
|
|
||||||
|
wire wire_dll_wys_m_offsetdelayctrlclkout;
|
||||||
|
wire [DLL_DELAY_CTRL_WIDTH-1:0] wire_dll_wys_m_offsetdelayctrlout;
|
||||||
|
wire dll_aload;
|
||||||
|
|
||||||
|
assign dll_aload = ~dll_pll_locked;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cyclonev_dll dll_wys_m(
|
||||||
|
.clk(clk),
|
||||||
|
.aload(dll_aload),
|
||||||
|
.delayctrlout(dll_delayctrl),
|
||||||
|
.dqsupdate(),
|
||||||
|
.locked(),
|
||||||
|
.upndnout(),
|
||||||
|
.dftcore()
|
||||||
|
`ifndef FORMAL_VERIFICATION
|
||||||
|
// synopsys translate_off
|
||||||
|
`endif
|
||||||
|
,
|
||||||
|
.upndnin(1'b1),
|
||||||
|
.upndninclkena(1'b1)
|
||||||
|
`ifndef FORMAL_VERIFICATION
|
||||||
|
// synopsys translate_on
|
||||||
|
`endif
|
||||||
|
// synopsys translate_off
|
||||||
|
,
|
||||||
|
.dffin()
|
||||||
|
// synopsys translate_on
|
||||||
|
);
|
||||||
|
defparam dll_wys_m.input_frequency = DLL_INPUT_FREQUENCY_PS_STR;
|
||||||
|
defparam dll_wys_m.jitter_reduction = "true";
|
||||||
|
defparam dll_wys_m.static_delay_ctrl = DELAY_CHAIN_LENGTH;
|
||||||
|
defparam dll_wys_m.lpm_type = "cyclonev_dll";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
1889
ip/altera/ddr3/altera_mem_if_hard_memory_controller_top_cyclonev.sv
Normal file
1889
ip/altera/ddr3/altera_mem_if_hard_memory_controller_top_cyclonev.sv
Normal file
File diff suppressed because it is too large
Load Diff
105
ip/altera/ddr3/altera_mem_if_oct_cyclonev.sv
Normal file
105
ip/altera/ddr3/altera_mem_if_oct_cyclonev.sv
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// ********************************************************************************************************************************
|
||||||
|
// This file instantiates the OCT block.
|
||||||
|
// ********************************************************************************************************************************
|
||||||
|
|
||||||
|
`timescale 1 ps / 1 ps
|
||||||
|
|
||||||
|
(* altera_attribute = "-name IP_TOOL_NAME altera_mem_if_oct; -name IP_TOOL_VERSION 15.1; -name FITTER_ADJUST_HC_SHORT_PATH_GUARDBAND 100; -name ALLOW_SYNCH_CTRL_USAGE OFF; -name AUTO_CLOCK_ENABLE_RECOGNITION OFF; -name AUTO_SHIFT_REGISTER_RECOGNITION OFF" *)
|
||||||
|
|
||||||
|
|
||||||
|
module altera_mem_if_oct_cyclonev (
|
||||||
|
oct_rzqin,
|
||||||
|
parallelterminationcontrol,
|
||||||
|
seriesterminationcontrol
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
parameter OCT_TERM_CONTROL_WIDTH = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// These should be connected to reference resistance pins on the board, via OCT control block if instantiated by user
|
||||||
|
input oct_rzqin;
|
||||||
|
|
||||||
|
// for OCT master, termination control signals will be available to top level
|
||||||
|
output [OCT_TERM_CONTROL_WIDTH-1:0] parallelterminationcontrol;
|
||||||
|
output [OCT_TERM_CONTROL_WIDTH-1:0] seriesterminationcontrol;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`ifndef ALTERA_RESERVED_QIS
|
||||||
|
// synopsys translate_off
|
||||||
|
`endif
|
||||||
|
tri0 oct_rzqin;
|
||||||
|
`ifndef ALTERA_RESERVED_QIS
|
||||||
|
// synopsys translate_on
|
||||||
|
`endif
|
||||||
|
|
||||||
|
wire [0:0] wire_sd1a_serdataout;
|
||||||
|
|
||||||
|
cyclonev_termination sd1a_0
|
||||||
|
(
|
||||||
|
.clkusrdftout(),
|
||||||
|
.compoutrdn(),
|
||||||
|
.compoutrup(),
|
||||||
|
.enserout(),
|
||||||
|
.rzqin(oct_rzqin),
|
||||||
|
.scanout(),
|
||||||
|
.serdataout(wire_sd1a_serdataout[0:0]),
|
||||||
|
.serdatatocore()
|
||||||
|
`ifndef FORMAL_VERIFICATION
|
||||||
|
// synopsys translate_off
|
||||||
|
`endif
|
||||||
|
,
|
||||||
|
.clkenusr(1'b0),
|
||||||
|
.clkusr(1'b0),
|
||||||
|
.enserusr(1'b0),
|
||||||
|
.nclrusr(1'b0),
|
||||||
|
.otherenser({10{1'b0}}),
|
||||||
|
.scanclk(1'b0),
|
||||||
|
.scanen(1'b0),
|
||||||
|
.scanin(1'b0),
|
||||||
|
.serdatafromcore(1'b0),
|
||||||
|
.serdatain(1'b0)
|
||||||
|
`ifndef FORMAL_VERIFICATION
|
||||||
|
// synopsys translate_on
|
||||||
|
`endif
|
||||||
|
);
|
||||||
|
|
||||||
|
cyclonev_termination_logic sd2a_0
|
||||||
|
(
|
||||||
|
.parallelterminationcontrol(parallelterminationcontrol),
|
||||||
|
.serdata(wire_sd1a_serdataout),
|
||||||
|
.seriesterminationcontrol(seriesterminationcontrol)
|
||||||
|
`ifndef FORMAL_VERIFICATION
|
||||||
|
// synopsys translate_off
|
||||||
|
`endif
|
||||||
|
,
|
||||||
|
.enser(1'b0),
|
||||||
|
.s2pload(1'b0),
|
||||||
|
.scanclk(1'b0),
|
||||||
|
.scanenable(1'b0)
|
||||||
|
`ifndef FORMAL_VERIFICATION
|
||||||
|
// synopsys translate_on
|
||||||
|
`endif
|
||||||
|
// synopsys translate_off
|
||||||
|
|
||||||
|
// synopsys translate_on
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
2616
ip/altera/ddr3/altera_mem_if_sequencer_cpu_cv_synth_cpu_inst.v
Normal file
2616
ip/altera/ddr3/altera_mem_if_sequencer_cpu_cv_synth_cpu_inst.v
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,718 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
//Legal Notice: (C)2012 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 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 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.
|
||||||
|
|
||||||
|
// synthesis translate_off
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
// synthesis translate_on
|
||||||
|
|
||||||
|
// turn off superfluous verilog processor warnings
|
||||||
|
// altera message_level Level1
|
||||||
|
// altera message_off 10034 10035 10036 10037 10230 10240 10030
|
||||||
|
|
||||||
|
module altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench (
|
||||||
|
// inputs:
|
||||||
|
D_iw,
|
||||||
|
D_iw_op,
|
||||||
|
D_iw_opx,
|
||||||
|
D_valid,
|
||||||
|
E_alu_result,
|
||||||
|
E_mem_byte_en,
|
||||||
|
E_st_data,
|
||||||
|
E_valid,
|
||||||
|
F_pcb,
|
||||||
|
F_valid,
|
||||||
|
R_ctrl_exception,
|
||||||
|
R_ctrl_ld,
|
||||||
|
R_ctrl_ld_non_io,
|
||||||
|
R_dst_regnum,
|
||||||
|
R_wr_dst_reg,
|
||||||
|
W_bstatus_reg,
|
||||||
|
W_cmp_result,
|
||||||
|
W_estatus_reg,
|
||||||
|
W_ienable_reg,
|
||||||
|
W_ipending_reg,
|
||||||
|
W_mem_baddr,
|
||||||
|
W_rf_wr_data,
|
||||||
|
W_status_reg,
|
||||||
|
W_valid,
|
||||||
|
W_vinst,
|
||||||
|
W_wr_data,
|
||||||
|
av_ld_data_aligned_unfiltered,
|
||||||
|
clk,
|
||||||
|
d_address,
|
||||||
|
d_byteenable,
|
||||||
|
d_read,
|
||||||
|
d_write_nxt,
|
||||||
|
i_address,
|
||||||
|
i_read,
|
||||||
|
i_readdata,
|
||||||
|
i_waitrequest,
|
||||||
|
reset_n,
|
||||||
|
|
||||||
|
// outputs:
|
||||||
|
av_ld_data_aligned_filtered,
|
||||||
|
d_write,
|
||||||
|
test_has_ended
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
output [ 31: 0] av_ld_data_aligned_filtered;
|
||||||
|
output d_write;
|
||||||
|
output test_has_ended;
|
||||||
|
input [ 31: 0] D_iw;
|
||||||
|
input [ 5: 0] D_iw_op;
|
||||||
|
input [ 5: 0] D_iw_opx;
|
||||||
|
input D_valid;
|
||||||
|
input [ 31: 0] E_alu_result;
|
||||||
|
input [ 3: 0] E_mem_byte_en;
|
||||||
|
input [ 31: 0] E_st_data;
|
||||||
|
input E_valid;
|
||||||
|
input [ 16: 0] F_pcb;
|
||||||
|
input F_valid;
|
||||||
|
input R_ctrl_exception;
|
||||||
|
input R_ctrl_ld;
|
||||||
|
input R_ctrl_ld_non_io;
|
||||||
|
input [ 4: 0] R_dst_regnum;
|
||||||
|
input R_wr_dst_reg;
|
||||||
|
input W_bstatus_reg;
|
||||||
|
input W_cmp_result;
|
||||||
|
input W_estatus_reg;
|
||||||
|
input [ 31: 0] W_ienable_reg;
|
||||||
|
input [ 31: 0] W_ipending_reg;
|
||||||
|
input [ 19: 0] W_mem_baddr;
|
||||||
|
input [ 31: 0] W_rf_wr_data;
|
||||||
|
input W_status_reg;
|
||||||
|
input W_valid;
|
||||||
|
input [ 55: 0] W_vinst;
|
||||||
|
input [ 31: 0] W_wr_data;
|
||||||
|
input [ 31: 0] av_ld_data_aligned_unfiltered;
|
||||||
|
input clk;
|
||||||
|
input [ 19: 0] d_address;
|
||||||
|
input [ 3: 0] d_byteenable;
|
||||||
|
input d_read;
|
||||||
|
input d_write_nxt;
|
||||||
|
input [ 16: 0] i_address;
|
||||||
|
input i_read;
|
||||||
|
input [ 31: 0] i_readdata;
|
||||||
|
input i_waitrequest;
|
||||||
|
input reset_n;
|
||||||
|
|
||||||
|
wire D_op_add;
|
||||||
|
wire D_op_addi;
|
||||||
|
wire D_op_and;
|
||||||
|
wire D_op_andhi;
|
||||||
|
wire D_op_andi;
|
||||||
|
wire D_op_beq;
|
||||||
|
wire D_op_bge;
|
||||||
|
wire D_op_bgeu;
|
||||||
|
wire D_op_blt;
|
||||||
|
wire D_op_bltu;
|
||||||
|
wire D_op_bne;
|
||||||
|
wire D_op_br;
|
||||||
|
wire D_op_break;
|
||||||
|
wire D_op_bret;
|
||||||
|
wire D_op_call;
|
||||||
|
wire D_op_callr;
|
||||||
|
wire D_op_cmpeq;
|
||||||
|
wire D_op_cmpeqi;
|
||||||
|
wire D_op_cmpge;
|
||||||
|
wire D_op_cmpgei;
|
||||||
|
wire D_op_cmpgeu;
|
||||||
|
wire D_op_cmpgeui;
|
||||||
|
wire D_op_cmplt;
|
||||||
|
wire D_op_cmplti;
|
||||||
|
wire D_op_cmpltu;
|
||||||
|
wire D_op_cmpltui;
|
||||||
|
wire D_op_cmpne;
|
||||||
|
wire D_op_cmpnei;
|
||||||
|
wire D_op_crst;
|
||||||
|
wire D_op_custom;
|
||||||
|
wire D_op_div;
|
||||||
|
wire D_op_divu;
|
||||||
|
wire D_op_eret;
|
||||||
|
wire D_op_flushd;
|
||||||
|
wire D_op_flushda;
|
||||||
|
wire D_op_flushi;
|
||||||
|
wire D_op_flushp;
|
||||||
|
wire D_op_hbreak;
|
||||||
|
wire D_op_initd;
|
||||||
|
wire D_op_initda;
|
||||||
|
wire D_op_initi;
|
||||||
|
wire D_op_intr;
|
||||||
|
wire D_op_jmp;
|
||||||
|
wire D_op_jmpi;
|
||||||
|
wire D_op_ldb;
|
||||||
|
wire D_op_ldbio;
|
||||||
|
wire D_op_ldbu;
|
||||||
|
wire D_op_ldbuio;
|
||||||
|
wire D_op_ldh;
|
||||||
|
wire D_op_ldhio;
|
||||||
|
wire D_op_ldhu;
|
||||||
|
wire D_op_ldhuio;
|
||||||
|
wire D_op_ldl;
|
||||||
|
wire D_op_ldw;
|
||||||
|
wire D_op_ldwio;
|
||||||
|
wire D_op_mul;
|
||||||
|
wire D_op_muli;
|
||||||
|
wire D_op_mulxss;
|
||||||
|
wire D_op_mulxsu;
|
||||||
|
wire D_op_mulxuu;
|
||||||
|
wire D_op_nextpc;
|
||||||
|
wire D_op_nor;
|
||||||
|
wire D_op_opx;
|
||||||
|
wire D_op_or;
|
||||||
|
wire D_op_orhi;
|
||||||
|
wire D_op_ori;
|
||||||
|
wire D_op_rdctl;
|
||||||
|
wire D_op_rdprs;
|
||||||
|
wire D_op_ret;
|
||||||
|
wire D_op_rol;
|
||||||
|
wire D_op_roli;
|
||||||
|
wire D_op_ror;
|
||||||
|
wire D_op_rsv02;
|
||||||
|
wire D_op_rsv09;
|
||||||
|
wire D_op_rsv10;
|
||||||
|
wire D_op_rsv17;
|
||||||
|
wire D_op_rsv18;
|
||||||
|
wire D_op_rsv25;
|
||||||
|
wire D_op_rsv26;
|
||||||
|
wire D_op_rsv33;
|
||||||
|
wire D_op_rsv34;
|
||||||
|
wire D_op_rsv41;
|
||||||
|
wire D_op_rsv42;
|
||||||
|
wire D_op_rsv49;
|
||||||
|
wire D_op_rsv57;
|
||||||
|
wire D_op_rsv61;
|
||||||
|
wire D_op_rsv62;
|
||||||
|
wire D_op_rsv63;
|
||||||
|
wire D_op_rsvx00;
|
||||||
|
wire D_op_rsvx10;
|
||||||
|
wire D_op_rsvx15;
|
||||||
|
wire D_op_rsvx17;
|
||||||
|
wire D_op_rsvx21;
|
||||||
|
wire D_op_rsvx25;
|
||||||
|
wire D_op_rsvx33;
|
||||||
|
wire D_op_rsvx34;
|
||||||
|
wire D_op_rsvx35;
|
||||||
|
wire D_op_rsvx42;
|
||||||
|
wire D_op_rsvx43;
|
||||||
|
wire D_op_rsvx44;
|
||||||
|
wire D_op_rsvx47;
|
||||||
|
wire D_op_rsvx50;
|
||||||
|
wire D_op_rsvx51;
|
||||||
|
wire D_op_rsvx55;
|
||||||
|
wire D_op_rsvx56;
|
||||||
|
wire D_op_rsvx60;
|
||||||
|
wire D_op_rsvx63;
|
||||||
|
wire D_op_sll;
|
||||||
|
wire D_op_slli;
|
||||||
|
wire D_op_sra;
|
||||||
|
wire D_op_srai;
|
||||||
|
wire D_op_srl;
|
||||||
|
wire D_op_srli;
|
||||||
|
wire D_op_stb;
|
||||||
|
wire D_op_stbio;
|
||||||
|
wire D_op_stc;
|
||||||
|
wire D_op_sth;
|
||||||
|
wire D_op_sthio;
|
||||||
|
wire D_op_stw;
|
||||||
|
wire D_op_stwio;
|
||||||
|
wire D_op_sub;
|
||||||
|
wire D_op_sync;
|
||||||
|
wire D_op_trap;
|
||||||
|
wire D_op_wrctl;
|
||||||
|
wire D_op_wrprs;
|
||||||
|
wire D_op_xor;
|
||||||
|
wire D_op_xorhi;
|
||||||
|
wire D_op_xori;
|
||||||
|
wire [ 31: 0] av_ld_data_aligned_filtered;
|
||||||
|
wire av_ld_data_aligned_unfiltered_0_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_10_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_11_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_12_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_13_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_14_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_15_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_16_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_17_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_18_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_19_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_1_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_20_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_21_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_22_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_23_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_24_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_25_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_26_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_27_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_28_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_29_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_2_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_30_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_31_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_3_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_4_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_5_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_6_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_7_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_8_is_x;
|
||||||
|
wire av_ld_data_aligned_unfiltered_9_is_x;
|
||||||
|
reg d_write;
|
||||||
|
wire test_has_ended;
|
||||||
|
assign D_op_call = D_iw_op == 0;
|
||||||
|
assign D_op_jmpi = D_iw_op == 1;
|
||||||
|
assign D_op_ldbu = D_iw_op == 3;
|
||||||
|
assign D_op_addi = D_iw_op == 4;
|
||||||
|
assign D_op_stb = D_iw_op == 5;
|
||||||
|
assign D_op_br = D_iw_op == 6;
|
||||||
|
assign D_op_ldb = D_iw_op == 7;
|
||||||
|
assign D_op_cmpgei = D_iw_op == 8;
|
||||||
|
assign D_op_ldhu = D_iw_op == 11;
|
||||||
|
assign D_op_andi = D_iw_op == 12;
|
||||||
|
assign D_op_sth = D_iw_op == 13;
|
||||||
|
assign D_op_bge = D_iw_op == 14;
|
||||||
|
assign D_op_ldh = D_iw_op == 15;
|
||||||
|
assign D_op_cmplti = D_iw_op == 16;
|
||||||
|
assign D_op_initda = D_iw_op == 19;
|
||||||
|
assign D_op_ori = D_iw_op == 20;
|
||||||
|
assign D_op_stw = D_iw_op == 21;
|
||||||
|
assign D_op_blt = D_iw_op == 22;
|
||||||
|
assign D_op_ldw = D_iw_op == 23;
|
||||||
|
assign D_op_cmpnei = D_iw_op == 24;
|
||||||
|
assign D_op_flushda = D_iw_op == 27;
|
||||||
|
assign D_op_xori = D_iw_op == 28;
|
||||||
|
assign D_op_stc = D_iw_op == 29;
|
||||||
|
assign D_op_bne = D_iw_op == 30;
|
||||||
|
assign D_op_ldl = D_iw_op == 31;
|
||||||
|
assign D_op_cmpeqi = D_iw_op == 32;
|
||||||
|
assign D_op_ldbuio = D_iw_op == 35;
|
||||||
|
assign D_op_muli = D_iw_op == 36;
|
||||||
|
assign D_op_stbio = D_iw_op == 37;
|
||||||
|
assign D_op_beq = D_iw_op == 38;
|
||||||
|
assign D_op_ldbio = D_iw_op == 39;
|
||||||
|
assign D_op_cmpgeui = D_iw_op == 40;
|
||||||
|
assign D_op_ldhuio = D_iw_op == 43;
|
||||||
|
assign D_op_andhi = D_iw_op == 44;
|
||||||
|
assign D_op_sthio = D_iw_op == 45;
|
||||||
|
assign D_op_bgeu = D_iw_op == 46;
|
||||||
|
assign D_op_ldhio = D_iw_op == 47;
|
||||||
|
assign D_op_cmpltui = D_iw_op == 48;
|
||||||
|
assign D_op_initd = D_iw_op == 51;
|
||||||
|
assign D_op_orhi = D_iw_op == 52;
|
||||||
|
assign D_op_stwio = D_iw_op == 53;
|
||||||
|
assign D_op_bltu = D_iw_op == 54;
|
||||||
|
assign D_op_ldwio = D_iw_op == 55;
|
||||||
|
assign D_op_rdprs = D_iw_op == 56;
|
||||||
|
assign D_op_flushd = D_iw_op == 59;
|
||||||
|
assign D_op_xorhi = D_iw_op == 60;
|
||||||
|
assign D_op_rsv02 = D_iw_op == 2;
|
||||||
|
assign D_op_rsv09 = D_iw_op == 9;
|
||||||
|
assign D_op_rsv10 = D_iw_op == 10;
|
||||||
|
assign D_op_rsv17 = D_iw_op == 17;
|
||||||
|
assign D_op_rsv18 = D_iw_op == 18;
|
||||||
|
assign D_op_rsv25 = D_iw_op == 25;
|
||||||
|
assign D_op_rsv26 = D_iw_op == 26;
|
||||||
|
assign D_op_rsv33 = D_iw_op == 33;
|
||||||
|
assign D_op_rsv34 = D_iw_op == 34;
|
||||||
|
assign D_op_rsv41 = D_iw_op == 41;
|
||||||
|
assign D_op_rsv42 = D_iw_op == 42;
|
||||||
|
assign D_op_rsv49 = D_iw_op == 49;
|
||||||
|
assign D_op_rsv57 = D_iw_op == 57;
|
||||||
|
assign D_op_rsv61 = D_iw_op == 61;
|
||||||
|
assign D_op_rsv62 = D_iw_op == 62;
|
||||||
|
assign D_op_rsv63 = D_iw_op == 63;
|
||||||
|
assign D_op_eret = D_op_opx & (D_iw_opx == 1);
|
||||||
|
assign D_op_roli = D_op_opx & (D_iw_opx == 2);
|
||||||
|
assign D_op_rol = D_op_opx & (D_iw_opx == 3);
|
||||||
|
assign D_op_flushp = D_op_opx & (D_iw_opx == 4);
|
||||||
|
assign D_op_ret = D_op_opx & (D_iw_opx == 5);
|
||||||
|
assign D_op_nor = D_op_opx & (D_iw_opx == 6);
|
||||||
|
assign D_op_mulxuu = D_op_opx & (D_iw_opx == 7);
|
||||||
|
assign D_op_cmpge = D_op_opx & (D_iw_opx == 8);
|
||||||
|
assign D_op_bret = D_op_opx & (D_iw_opx == 9);
|
||||||
|
assign D_op_ror = D_op_opx & (D_iw_opx == 11);
|
||||||
|
assign D_op_flushi = D_op_opx & (D_iw_opx == 12);
|
||||||
|
assign D_op_jmp = D_op_opx & (D_iw_opx == 13);
|
||||||
|
assign D_op_and = D_op_opx & (D_iw_opx == 14);
|
||||||
|
assign D_op_cmplt = D_op_opx & (D_iw_opx == 16);
|
||||||
|
assign D_op_slli = D_op_opx & (D_iw_opx == 18);
|
||||||
|
assign D_op_sll = D_op_opx & (D_iw_opx == 19);
|
||||||
|
assign D_op_wrprs = D_op_opx & (D_iw_opx == 20);
|
||||||
|
assign D_op_or = D_op_opx & (D_iw_opx == 22);
|
||||||
|
assign D_op_mulxsu = D_op_opx & (D_iw_opx == 23);
|
||||||
|
assign D_op_cmpne = D_op_opx & (D_iw_opx == 24);
|
||||||
|
assign D_op_srli = D_op_opx & (D_iw_opx == 26);
|
||||||
|
assign D_op_srl = D_op_opx & (D_iw_opx == 27);
|
||||||
|
assign D_op_nextpc = D_op_opx & (D_iw_opx == 28);
|
||||||
|
assign D_op_callr = D_op_opx & (D_iw_opx == 29);
|
||||||
|
assign D_op_xor = D_op_opx & (D_iw_opx == 30);
|
||||||
|
assign D_op_mulxss = D_op_opx & (D_iw_opx == 31);
|
||||||
|
assign D_op_cmpeq = D_op_opx & (D_iw_opx == 32);
|
||||||
|
assign D_op_divu = D_op_opx & (D_iw_opx == 36);
|
||||||
|
assign D_op_div = D_op_opx & (D_iw_opx == 37);
|
||||||
|
assign D_op_rdctl = D_op_opx & (D_iw_opx == 38);
|
||||||
|
assign D_op_mul = D_op_opx & (D_iw_opx == 39);
|
||||||
|
assign D_op_cmpgeu = D_op_opx & (D_iw_opx == 40);
|
||||||
|
assign D_op_initi = D_op_opx & (D_iw_opx == 41);
|
||||||
|
assign D_op_trap = D_op_opx & (D_iw_opx == 45);
|
||||||
|
assign D_op_wrctl = D_op_opx & (D_iw_opx == 46);
|
||||||
|
assign D_op_cmpltu = D_op_opx & (D_iw_opx == 48);
|
||||||
|
assign D_op_add = D_op_opx & (D_iw_opx == 49);
|
||||||
|
assign D_op_break = D_op_opx & (D_iw_opx == 52);
|
||||||
|
assign D_op_hbreak = D_op_opx & (D_iw_opx == 53);
|
||||||
|
assign D_op_sync = D_op_opx & (D_iw_opx == 54);
|
||||||
|
assign D_op_sub = D_op_opx & (D_iw_opx == 57);
|
||||||
|
assign D_op_srai = D_op_opx & (D_iw_opx == 58);
|
||||||
|
assign D_op_sra = D_op_opx & (D_iw_opx == 59);
|
||||||
|
assign D_op_intr = D_op_opx & (D_iw_opx == 61);
|
||||||
|
assign D_op_crst = D_op_opx & (D_iw_opx == 62);
|
||||||
|
assign D_op_rsvx00 = D_op_opx & (D_iw_opx == 0);
|
||||||
|
assign D_op_rsvx10 = D_op_opx & (D_iw_opx == 10);
|
||||||
|
assign D_op_rsvx15 = D_op_opx & (D_iw_opx == 15);
|
||||||
|
assign D_op_rsvx17 = D_op_opx & (D_iw_opx == 17);
|
||||||
|
assign D_op_rsvx21 = D_op_opx & (D_iw_opx == 21);
|
||||||
|
assign D_op_rsvx25 = D_op_opx & (D_iw_opx == 25);
|
||||||
|
assign D_op_rsvx33 = D_op_opx & (D_iw_opx == 33);
|
||||||
|
assign D_op_rsvx34 = D_op_opx & (D_iw_opx == 34);
|
||||||
|
assign D_op_rsvx35 = D_op_opx & (D_iw_opx == 35);
|
||||||
|
assign D_op_rsvx42 = D_op_opx & (D_iw_opx == 42);
|
||||||
|
assign D_op_rsvx43 = D_op_opx & (D_iw_opx == 43);
|
||||||
|
assign D_op_rsvx44 = D_op_opx & (D_iw_opx == 44);
|
||||||
|
assign D_op_rsvx47 = D_op_opx & (D_iw_opx == 47);
|
||||||
|
assign D_op_rsvx50 = D_op_opx & (D_iw_opx == 50);
|
||||||
|
assign D_op_rsvx51 = D_op_opx & (D_iw_opx == 51);
|
||||||
|
assign D_op_rsvx55 = D_op_opx & (D_iw_opx == 55);
|
||||||
|
assign D_op_rsvx56 = D_op_opx & (D_iw_opx == 56);
|
||||||
|
assign D_op_rsvx60 = D_op_opx & (D_iw_opx == 60);
|
||||||
|
assign D_op_rsvx63 = D_op_opx & (D_iw_opx == 63);
|
||||||
|
assign D_op_opx = D_iw_op == 58;
|
||||||
|
assign D_op_custom = D_iw_op == 50;
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
d_write <= 0;
|
||||||
|
else
|
||||||
|
d_write <= d_write_nxt;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
assign test_has_ended = 1'b0;
|
||||||
|
|
||||||
|
//synthesis translate_off
|
||||||
|
//////////////// SIMULATION-ONLY CONTENTS
|
||||||
|
//Clearing 'X' data bits
|
||||||
|
assign av_ld_data_aligned_unfiltered_0_is_x = ^(av_ld_data_aligned_unfiltered[0]) === 1'bx;
|
||||||
|
|
||||||
|
assign av_ld_data_aligned_filtered[0] = (av_ld_data_aligned_unfiltered_0_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[0];
|
||||||
|
assign av_ld_data_aligned_unfiltered_1_is_x = ^(av_ld_data_aligned_unfiltered[1]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[1] = (av_ld_data_aligned_unfiltered_1_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[1];
|
||||||
|
assign av_ld_data_aligned_unfiltered_2_is_x = ^(av_ld_data_aligned_unfiltered[2]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[2] = (av_ld_data_aligned_unfiltered_2_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[2];
|
||||||
|
assign av_ld_data_aligned_unfiltered_3_is_x = ^(av_ld_data_aligned_unfiltered[3]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[3] = (av_ld_data_aligned_unfiltered_3_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[3];
|
||||||
|
assign av_ld_data_aligned_unfiltered_4_is_x = ^(av_ld_data_aligned_unfiltered[4]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[4] = (av_ld_data_aligned_unfiltered_4_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[4];
|
||||||
|
assign av_ld_data_aligned_unfiltered_5_is_x = ^(av_ld_data_aligned_unfiltered[5]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[5] = (av_ld_data_aligned_unfiltered_5_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[5];
|
||||||
|
assign av_ld_data_aligned_unfiltered_6_is_x = ^(av_ld_data_aligned_unfiltered[6]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[6] = (av_ld_data_aligned_unfiltered_6_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[6];
|
||||||
|
assign av_ld_data_aligned_unfiltered_7_is_x = ^(av_ld_data_aligned_unfiltered[7]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[7] = (av_ld_data_aligned_unfiltered_7_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[7];
|
||||||
|
assign av_ld_data_aligned_unfiltered_8_is_x = ^(av_ld_data_aligned_unfiltered[8]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[8] = (av_ld_data_aligned_unfiltered_8_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[8];
|
||||||
|
assign av_ld_data_aligned_unfiltered_9_is_x = ^(av_ld_data_aligned_unfiltered[9]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[9] = (av_ld_data_aligned_unfiltered_9_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[9];
|
||||||
|
assign av_ld_data_aligned_unfiltered_10_is_x = ^(av_ld_data_aligned_unfiltered[10]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[10] = (av_ld_data_aligned_unfiltered_10_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[10];
|
||||||
|
assign av_ld_data_aligned_unfiltered_11_is_x = ^(av_ld_data_aligned_unfiltered[11]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[11] = (av_ld_data_aligned_unfiltered_11_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[11];
|
||||||
|
assign av_ld_data_aligned_unfiltered_12_is_x = ^(av_ld_data_aligned_unfiltered[12]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[12] = (av_ld_data_aligned_unfiltered_12_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[12];
|
||||||
|
assign av_ld_data_aligned_unfiltered_13_is_x = ^(av_ld_data_aligned_unfiltered[13]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[13] = (av_ld_data_aligned_unfiltered_13_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[13];
|
||||||
|
assign av_ld_data_aligned_unfiltered_14_is_x = ^(av_ld_data_aligned_unfiltered[14]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[14] = (av_ld_data_aligned_unfiltered_14_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[14];
|
||||||
|
assign av_ld_data_aligned_unfiltered_15_is_x = ^(av_ld_data_aligned_unfiltered[15]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[15] = (av_ld_data_aligned_unfiltered_15_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[15];
|
||||||
|
assign av_ld_data_aligned_unfiltered_16_is_x = ^(av_ld_data_aligned_unfiltered[16]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[16] = (av_ld_data_aligned_unfiltered_16_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[16];
|
||||||
|
assign av_ld_data_aligned_unfiltered_17_is_x = ^(av_ld_data_aligned_unfiltered[17]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[17] = (av_ld_data_aligned_unfiltered_17_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[17];
|
||||||
|
assign av_ld_data_aligned_unfiltered_18_is_x = ^(av_ld_data_aligned_unfiltered[18]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[18] = (av_ld_data_aligned_unfiltered_18_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[18];
|
||||||
|
assign av_ld_data_aligned_unfiltered_19_is_x = ^(av_ld_data_aligned_unfiltered[19]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[19] = (av_ld_data_aligned_unfiltered_19_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[19];
|
||||||
|
assign av_ld_data_aligned_unfiltered_20_is_x = ^(av_ld_data_aligned_unfiltered[20]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[20] = (av_ld_data_aligned_unfiltered_20_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[20];
|
||||||
|
assign av_ld_data_aligned_unfiltered_21_is_x = ^(av_ld_data_aligned_unfiltered[21]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[21] = (av_ld_data_aligned_unfiltered_21_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[21];
|
||||||
|
assign av_ld_data_aligned_unfiltered_22_is_x = ^(av_ld_data_aligned_unfiltered[22]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[22] = (av_ld_data_aligned_unfiltered_22_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[22];
|
||||||
|
assign av_ld_data_aligned_unfiltered_23_is_x = ^(av_ld_data_aligned_unfiltered[23]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[23] = (av_ld_data_aligned_unfiltered_23_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[23];
|
||||||
|
assign av_ld_data_aligned_unfiltered_24_is_x = ^(av_ld_data_aligned_unfiltered[24]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[24] = (av_ld_data_aligned_unfiltered_24_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[24];
|
||||||
|
assign av_ld_data_aligned_unfiltered_25_is_x = ^(av_ld_data_aligned_unfiltered[25]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[25] = (av_ld_data_aligned_unfiltered_25_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[25];
|
||||||
|
assign av_ld_data_aligned_unfiltered_26_is_x = ^(av_ld_data_aligned_unfiltered[26]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[26] = (av_ld_data_aligned_unfiltered_26_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[26];
|
||||||
|
assign av_ld_data_aligned_unfiltered_27_is_x = ^(av_ld_data_aligned_unfiltered[27]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[27] = (av_ld_data_aligned_unfiltered_27_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[27];
|
||||||
|
assign av_ld_data_aligned_unfiltered_28_is_x = ^(av_ld_data_aligned_unfiltered[28]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[28] = (av_ld_data_aligned_unfiltered_28_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[28];
|
||||||
|
assign av_ld_data_aligned_unfiltered_29_is_x = ^(av_ld_data_aligned_unfiltered[29]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[29] = (av_ld_data_aligned_unfiltered_29_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[29];
|
||||||
|
assign av_ld_data_aligned_unfiltered_30_is_x = ^(av_ld_data_aligned_unfiltered[30]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[30] = (av_ld_data_aligned_unfiltered_30_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[30];
|
||||||
|
assign av_ld_data_aligned_unfiltered_31_is_x = ^(av_ld_data_aligned_unfiltered[31]) === 1'bx;
|
||||||
|
assign av_ld_data_aligned_filtered[31] = (av_ld_data_aligned_unfiltered_31_is_x & (R_ctrl_ld_non_io)) ? 1'b0 : av_ld_data_aligned_unfiltered[31];
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset_n)
|
||||||
|
if (^(F_valid) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/F_valid is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset_n)
|
||||||
|
if (^(D_valid) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/D_valid is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset_n)
|
||||||
|
if (^(E_valid) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/E_valid is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset_n)
|
||||||
|
if (^(W_valid) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/W_valid is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (W_valid)
|
||||||
|
if (^(R_wr_dst_reg) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/R_wr_dst_reg is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (W_valid & R_wr_dst_reg)
|
||||||
|
if (^(W_wr_data) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/W_wr_data is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (W_valid & R_wr_dst_reg)
|
||||||
|
if (^(R_dst_regnum) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/R_dst_regnum is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset_n)
|
||||||
|
if (^(d_write) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/d_write is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (d_write)
|
||||||
|
if (^(d_byteenable) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/d_byteenable is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (d_write | d_read)
|
||||||
|
if (^(d_address) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/d_address is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset_n)
|
||||||
|
if (^(d_read) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/d_read is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset_n)
|
||||||
|
if (^(i_read) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/i_read is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (i_read)
|
||||||
|
if (^(i_address) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/i_address is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (i_read & ~i_waitrequest)
|
||||||
|
if (^(i_readdata) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: ERROR: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/i_readdata is 'x'\n", $time);
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (W_valid & R_ctrl_ld)
|
||||||
|
if (^(av_ld_data_aligned_unfiltered) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: WARNING: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/av_ld_data_aligned_unfiltered is 'x'\n", $time);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n)
|
||||||
|
begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
begin
|
||||||
|
end
|
||||||
|
else if (W_valid & R_wr_dst_reg)
|
||||||
|
if (^(W_wr_data) === 1'bx)
|
||||||
|
begin
|
||||||
|
$write("%0d ns: WARNING: altera_mem_if_sequencer_cpu_cv_synth_cpu_inst_test_bench/W_wr_data is 'x'\n", $time);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reg [31:0] trace_handle; // for $fopen
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
trace_handle = $fopen("altera_mem_if_sequencer_cpu_cv_synth_cpu_inst.tr");
|
||||||
|
$fwrite(trace_handle, "version 3\nnumThreads 1\n");
|
||||||
|
end
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if ((~reset_n || (W_valid)) && ~test_has_ended)
|
||||||
|
$fwrite(trace_handle, "%0d ns: %0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h,%0h\n", $time, ~reset_n, F_pcb, 0, D_op_intr, D_op_hbreak, D_iw, ~(D_op_intr | D_op_hbreak), R_wr_dst_reg, R_dst_regnum, 0, W_rf_wr_data, W_mem_baddr, E_st_data, E_mem_byte_en, W_cmp_result, E_alu_result, W_status_reg, W_estatus_reg, W_bstatus_reg, W_ienable_reg, W_ipending_reg, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R_ctrl_exception, 0, 0, 0, 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//////////////// END SIMULATION-ONLY CONTENTS
|
||||||
|
|
||||||
|
//synthesis translate_on
|
||||||
|
//synthesis read_comments_as_HDL on
|
||||||
|
//
|
||||||
|
// assign av_ld_data_aligned_filtered = av_ld_data_aligned_unfiltered;
|
||||||
|
//
|
||||||
|
//synthesis read_comments_as_HDL off
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,99 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// synthesis translate_off
|
||||||
|
`timescale 1ns / 1ps
|
||||||
|
// synthesis translate_on
|
||||||
|
|
||||||
|
// turn off superfluous verilog processor warnings
|
||||||
|
// altera message_level Level1
|
||||||
|
// altera message_off 10034 10035 10036 10037 10230 10240 10030
|
||||||
|
|
||||||
|
module altera_mem_if_sequencer_mem_no_ifdef_params (
|
||||||
|
clk1,
|
||||||
|
reset1,
|
||||||
|
clken1,
|
||||||
|
s1_address,
|
||||||
|
s1_be,
|
||||||
|
s1_chipselect,
|
||||||
|
s1_write,
|
||||||
|
s1_writedata,
|
||||||
|
s1_readdata
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter AVL_ADDR_WIDTH = 0;
|
||||||
|
parameter AVL_DATA_WIDTH = 0;
|
||||||
|
parameter AVL_SYMBOL_WIDTH = 0;
|
||||||
|
parameter AVL_NUM_SYMBOLS = 0;
|
||||||
|
parameter MEM_SIZE = 0;
|
||||||
|
parameter INIT_FILE = "";
|
||||||
|
parameter RAM_BLOCK_TYPE = "";
|
||||||
|
|
||||||
|
localparam NUM_WORDS = MEM_SIZE / AVL_NUM_SYMBOLS;
|
||||||
|
|
||||||
|
input clk1;
|
||||||
|
input reset1;
|
||||||
|
input clken1;
|
||||||
|
input [AVL_ADDR_WIDTH - 1:0] s1_address;
|
||||||
|
input [AVL_NUM_SYMBOLS - 1:0] s1_be;
|
||||||
|
input s1_chipselect;
|
||||||
|
input s1_write;
|
||||||
|
input [AVL_DATA_WIDTH - 1:0] s1_writedata;
|
||||||
|
output [AVL_DATA_WIDTH - 1:0] s1_readdata;
|
||||||
|
|
||||||
|
wire wren;
|
||||||
|
assign wren = s1_chipselect & s1_write;
|
||||||
|
|
||||||
|
altsyncram the_altsyncram
|
||||||
|
(
|
||||||
|
.address_a (s1_address),
|
||||||
|
.byteena_a (s1_be),
|
||||||
|
.clock0 (clk1),
|
||||||
|
.clocken0 (clken1),
|
||||||
|
.data_a (s1_writedata),
|
||||||
|
.q_a (s1_readdata),
|
||||||
|
.wren_a (wren),
|
||||||
|
.rden_a(),
|
||||||
|
.rden_b(),
|
||||||
|
.clocken2(),
|
||||||
|
.clocken3(),
|
||||||
|
.aclr0(),
|
||||||
|
.aclr1(),
|
||||||
|
.addressstall_a(),
|
||||||
|
.addressstall_b(),
|
||||||
|
.eccstatus(),
|
||||||
|
.address_b (),
|
||||||
|
.byteena_b (),
|
||||||
|
.clock1 (),
|
||||||
|
.clocken1 (),
|
||||||
|
.data_b (),
|
||||||
|
.q_b (),
|
||||||
|
.wren_b ()
|
||||||
|
);
|
||||||
|
defparam the_altsyncram.byte_size = AVL_SYMBOL_WIDTH;
|
||||||
|
defparam the_altsyncram.lpm_type = "altsyncram";
|
||||||
|
defparam the_altsyncram.maximum_depth = NUM_WORDS;
|
||||||
|
defparam the_altsyncram.numwords_a = NUM_WORDS;
|
||||||
|
defparam the_altsyncram.outdata_reg_a = "UNREGISTERED";
|
||||||
|
defparam the_altsyncram.ram_block_type = RAM_BLOCK_TYPE;
|
||||||
|
defparam the_altsyncram.read_during_write_mode_mixed_ports = "DONT_CARE";
|
||||||
|
defparam the_altsyncram.width_a = AVL_DATA_WIDTH;
|
||||||
|
defparam the_altsyncram.width_byteena_a = AVL_NUM_SYMBOLS;
|
||||||
|
defparam the_altsyncram.widthad_a = AVL_ADDR_WIDTH;
|
||||||
|
defparam the_altsyncram.init_file = INIT_FILE;
|
||||||
|
defparam the_altsyncram.operation_mode = "SINGLE_PORT";
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
117
ip/altera/ddr3/altera_mem_if_sequencer_rst.sv
Normal file
117
ip/altera/ddr3/altera_mem_if_sequencer_rst.sv
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// turn off superfluous verilog processor warnings
|
||||||
|
// altera message_level Level1
|
||||||
|
// altera message_off 10034 10035 10036 10037 10230 10240 10030
|
||||||
|
|
||||||
|
module altera_mem_if_sequencer_rst
|
||||||
|
(
|
||||||
|
clk,
|
||||||
|
rst,
|
||||||
|
clken_out,
|
||||||
|
reset_out
|
||||||
|
);
|
||||||
|
timeunit 1ns;
|
||||||
|
timeprecision 1ps;
|
||||||
|
|
||||||
|
parameter DEPTH = 2;
|
||||||
|
parameter CLKEN_LAGS_RESET = 0;
|
||||||
|
|
||||||
|
localparam EARLY_RST_TAP = (CLKEN_LAGS_RESET != 0) ? 0 : 1;
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input rst;
|
||||||
|
output clken_out;
|
||||||
|
output reset_out;
|
||||||
|
|
||||||
|
(*preserve*) reg [2: 0] altera_reset_synchronizer_int_chain;
|
||||||
|
|
||||||
|
wire w_sync_rst_input;
|
||||||
|
reg [(DEPTH-1): 0] r_sync_rst_chain;
|
||||||
|
|
||||||
|
reg r_sync_rst_dly;
|
||||||
|
reg r_sync_rst;
|
||||||
|
reg r_early_rst;
|
||||||
|
|
||||||
|
assign w_sync_rst_input = altera_reset_synchronizer_int_chain[2];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
assign clken_out =~r_early_rst;
|
||||||
|
assign reset_out = r_sync_rst;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
altera_reset_synchronizer_int_chain <= '1;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
altera_reset_synchronizer_int_chain[2:0]
|
||||||
|
<= {altera_reset_synchronizer_int_chain[1:0], ~rst};
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
r_sync_rst_chain <= {DEPTH{1'b1}};
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (w_sync_rst_input == 1'b1)
|
||||||
|
begin
|
||||||
|
r_sync_rst_chain <= {DEPTH{1'b1}};
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
r_sync_rst_chain <= {1'b0, r_sync_rst_chain[DEPTH-1:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
r_sync_rst_dly <= 1'b1;
|
||||||
|
r_sync_rst <= 1'b1;
|
||||||
|
r_early_rst <= 1'b1;
|
||||||
|
end
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
r_sync_rst_dly <= r_sync_rst_chain[DEPTH-1];
|
||||||
|
|
||||||
|
case ({r_sync_rst_dly, r_sync_rst_chain[1], r_sync_rst})
|
||||||
|
3'b000: r_sync_rst <= 1'b0;
|
||||||
|
3'b001: r_sync_rst <= 1'b0;
|
||||||
|
3'b010: r_sync_rst <= 1'b0;
|
||||||
|
3'b011: r_sync_rst <= 1'b1;
|
||||||
|
3'b100: r_sync_rst <= 1'b1;
|
||||||
|
3'b101: r_sync_rst <= 1'b1;
|
||||||
|
3'b110: r_sync_rst <= 1'b1;
|
||||||
|
3'b111: r_sync_rst <= 1'b1;
|
||||||
|
default: r_sync_rst <= 1'b1;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
case ({r_sync_rst_chain[DEPTH-1], r_sync_rst_chain[EARLY_RST_TAP]})
|
||||||
|
2'b00: r_early_rst <= 1'b0;
|
||||||
|
2'b01: r_early_rst <= 1'b1;
|
||||||
|
2'b10: r_early_rst <= 1'b0;
|
||||||
|
2'b11: r_early_rst <= 1'b1;
|
||||||
|
default: r_early_rst <= 1'b1;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
122
ip/altera/ddr3/altera_mem_if_simple_avalon_mm_bridge.sv
Normal file
122
ip/altera/ddr3/altera_mem_if_simple_avalon_mm_bridge.sv
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1ps/1ps
|
||||||
|
|
||||||
|
module altera_mem_if_simple_avalon_mm_bridge (
|
||||||
|
clk,
|
||||||
|
reset_n,
|
||||||
|
s0_address,
|
||||||
|
s0_read,
|
||||||
|
s0_readdata,
|
||||||
|
s0_write,
|
||||||
|
s0_writedata,
|
||||||
|
s0_waitrequest,
|
||||||
|
s0_waitrequest_n,
|
||||||
|
s0_byteenable,
|
||||||
|
s0_beginbursttransfer,
|
||||||
|
s0_burstcount,
|
||||||
|
s0_readdatavalid,
|
||||||
|
m0_address,
|
||||||
|
m0_read,
|
||||||
|
m0_readdata,
|
||||||
|
m0_write,
|
||||||
|
m0_writedata,
|
||||||
|
m0_waitrequest,
|
||||||
|
m0_byteenable,
|
||||||
|
m0_beginbursttransfer,
|
||||||
|
m0_burstcount,
|
||||||
|
m0_readdatavalid
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter DATA_WIDTH = 32;
|
||||||
|
parameter MASTER_DATA_WIDTH = 32;
|
||||||
|
parameter SLAVE_DATA_WIDTH = 32;
|
||||||
|
parameter SYMBOL_WIDTH = 8;
|
||||||
|
parameter ADDRESS_WIDTH = 10;
|
||||||
|
parameter BURSTCOUNT_WIDTH = 1;
|
||||||
|
parameter MASTER_ADDRESS_WIDTH = 10;
|
||||||
|
parameter SLAVE_ADDRESS_WIDTH = 10;
|
||||||
|
parameter WORKAROUND_HARD_PHY_ISSUE = 0;
|
||||||
|
|
||||||
|
localparam USE_DIFFERENT_MASTER_SLAVE_ADDR = (MASTER_ADDRESS_WIDTH != SLAVE_ADDRESS_WIDTH ? 1 : 0);
|
||||||
|
localparam S0_ADDR_WIDTH = (USE_DIFFERENT_MASTER_SLAVE_ADDR ? SLAVE_ADDRESS_WIDTH : ADDRESS_WIDTH);
|
||||||
|
localparam M0_ADDR_WIDTH = (USE_DIFFERENT_MASTER_SLAVE_ADDR ? MASTER_ADDRESS_WIDTH : ADDRESS_WIDTH);
|
||||||
|
localparam USE_DIFFERENT_MASTER_SLAVE_DATA = (MASTER_DATA_WIDTH != SLAVE_DATA_WIDTH ? 1 : 0);
|
||||||
|
localparam S0_DATA_WIDTH = (USE_DIFFERENT_MASTER_SLAVE_DATA ? SLAVE_DATA_WIDTH : DATA_WIDTH);
|
||||||
|
localparam M0_DATA_WIDTH = (USE_DIFFERENT_MASTER_SLAVE_DATA ? MASTER_DATA_WIDTH : DATA_WIDTH);
|
||||||
|
localparam S0_BYTEEN_WIDTH = S0_DATA_WIDTH / SYMBOL_WIDTH;
|
||||||
|
localparam M0_BYTEEN_WIDTH = M0_DATA_WIDTH / SYMBOL_WIDTH;
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input reset_n;
|
||||||
|
|
||||||
|
input [S0_ADDR_WIDTH-1:0] s0_address;
|
||||||
|
input s0_read;
|
||||||
|
output [S0_DATA_WIDTH-1:0] s0_readdata;
|
||||||
|
input s0_write;
|
||||||
|
input [S0_DATA_WIDTH-1:0] s0_writedata;
|
||||||
|
output s0_waitrequest;
|
||||||
|
output s0_waitrequest_n;
|
||||||
|
input [S0_BYTEEN_WIDTH-1:0] s0_byteenable;
|
||||||
|
output s0_readdatavalid;
|
||||||
|
input [BURSTCOUNT_WIDTH-1:0] s0_burstcount;
|
||||||
|
input s0_beginbursttransfer;
|
||||||
|
|
||||||
|
output [M0_ADDR_WIDTH-1:0] m0_address;
|
||||||
|
output m0_read;
|
||||||
|
input [M0_DATA_WIDTH-1:0] m0_readdata;
|
||||||
|
output m0_write;
|
||||||
|
output [M0_DATA_WIDTH-1:0] m0_writedata;
|
||||||
|
input m0_waitrequest;
|
||||||
|
output [M0_BYTEEN_WIDTH-1:0] m0_byteenable;
|
||||||
|
input m0_readdatavalid;
|
||||||
|
output [BURSTCOUNT_WIDTH-1:0] m0_burstcount;
|
||||||
|
output m0_beginbursttransfer;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (WORKAROUND_HARD_PHY_ISSUE)
|
||||||
|
begin
|
||||||
|
reg waitrequest_r = 0;
|
||||||
|
reg read_r = 0;
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
waitrequest_r <= s0_waitrequest;
|
||||||
|
read_r <= s0_read;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign m0_read = read_r & s0_read;
|
||||||
|
assign s0_waitrequest = m0_waitrequest | (s0_read & ~waitrequest_r);
|
||||||
|
assign s0_waitrequest_n = ~s0_waitrequest;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
assign m0_read = s0_read;
|
||||||
|
assign s0_waitrequest = m0_waitrequest;
|
||||||
|
assign s0_waitrequest_n = ~s0_waitrequest;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign m0_address = (M0_ADDR_WIDTH > S0_ADDR_WIDTH) ? { { (M0_ADDR_WIDTH - S0_ADDR_WIDTH) {1'b0} }, s0_address} : s0_address;
|
||||||
|
assign s0_readdata = m0_readdata;
|
||||||
|
assign m0_write = s0_write;
|
||||||
|
assign m0_writedata = s0_writedata;
|
||||||
|
assign m0_byteenable = s0_byteenable;
|
||||||
|
assign s0_readdatavalid = m0_readdatavalid;
|
||||||
|
assign m0_beginbursttransfer = s0_beginbursttransfer;
|
||||||
|
assign m0_burstcount = s0_burstcount;
|
||||||
|
|
||||||
|
endmodule
|
263
ip/altera/ddr3/altera_merlin_address_alignment.sv
Normal file
263
ip/altera/ddr3/altera_merlin_address_alignment.sv
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/main/ip/merlin/altera_merlin_axi_master_ni/address_alignment.sv#3 $
|
||||||
|
// $Revision: #3 $
|
||||||
|
// $Date: 2012/07/11 $
|
||||||
|
// $Author: tgngo $
|
||||||
|
|
||||||
|
//-----------------------------------------
|
||||||
|
// Address alignment:
|
||||||
|
// This component will aglin input address with input size
|
||||||
|
// Support address increment with butst type and burstwrap value
|
||||||
|
//-----------------------------------------
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_merlin_address_alignment
|
||||||
|
#(
|
||||||
|
parameter
|
||||||
|
ADDR_W = 12,
|
||||||
|
BURSTWRAP_W = 12,
|
||||||
|
TYPE_W = 2,
|
||||||
|
SIZE_W = 3,
|
||||||
|
INCREMENT_ADDRESS = 1,
|
||||||
|
NUMSYMBOLS = 8,
|
||||||
|
SELECT_BITS = log2(NUMSYMBOLS),
|
||||||
|
IN_DATA_W = ADDR_W + (BURSTWRAP_W-1) + TYPE_W + SIZE_W,
|
||||||
|
OUT_DATA_W = ADDR_W + SELECT_BITS
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
input [IN_DATA_W-1:0] in_data, // in_data = {wrap_boundary, address, type, size}
|
||||||
|
input in_valid,
|
||||||
|
//output in_ready,
|
||||||
|
input in_sop,
|
||||||
|
input in_eop,
|
||||||
|
|
||||||
|
output reg [OUT_DATA_W-1:0] out_data,
|
||||||
|
input out_ready
|
||||||
|
//output out_valid
|
||||||
|
|
||||||
|
);
|
||||||
|
typedef enum bit [1:0]
|
||||||
|
{
|
||||||
|
FIXED = 2'b00,
|
||||||
|
INCR = 2'b01,
|
||||||
|
WRAP = 2'b10,
|
||||||
|
RESERVED = 2'b11
|
||||||
|
} AxiBurstType;
|
||||||
|
//----------------------------------------------------
|
||||||
|
// AXSIZE decoding
|
||||||
|
//
|
||||||
|
// Turns the axsize value into the actual number of bytes
|
||||||
|
// being transferred.
|
||||||
|
// ---------------------------------------------------
|
||||||
|
|
||||||
|
function reg[9:0] bytes_in_transfer;
|
||||||
|
input [SIZE_W-1:0] axsize;
|
||||||
|
case (axsize)
|
||||||
|
4'b0000: bytes_in_transfer = 10'b0000000001;
|
||||||
|
4'b0001: bytes_in_transfer = 10'b0000000010;
|
||||||
|
4'b0010: bytes_in_transfer = 10'b0000000100;
|
||||||
|
4'b0011: bytes_in_transfer = 10'b0000001000;
|
||||||
|
4'b0100: bytes_in_transfer = 10'b0000010000;
|
||||||
|
4'b0101: bytes_in_transfer = 10'b0000100000;
|
||||||
|
4'b0110: bytes_in_transfer = 10'b0001000000;
|
||||||
|
4'b0111: bytes_in_transfer = 10'b0010000000;
|
||||||
|
4'b1000: bytes_in_transfer = 10'b0100000000;
|
||||||
|
4'b1001: bytes_in_transfer = 10'b1000000000;
|
||||||
|
default: bytes_in_transfer = 10'b0000000001;
|
||||||
|
endcase
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
//--------------------------------------
|
||||||
|
// Burst type decode
|
||||||
|
//--------------------------------------
|
||||||
|
AxiBurstType write_burst_type;
|
||||||
|
|
||||||
|
function AxiBurstType burst_type_decode
|
||||||
|
(
|
||||||
|
input [1:0] axburst
|
||||||
|
);
|
||||||
|
AxiBurstType burst_type;
|
||||||
|
begin
|
||||||
|
case (axburst)
|
||||||
|
2'b00 : burst_type = FIXED;
|
||||||
|
2'b01 : burst_type = INCR;
|
||||||
|
2'b10 : burst_type = WRAP;
|
||||||
|
2'b11 : burst_type = RESERVED;
|
||||||
|
default : burst_type = INCR;
|
||||||
|
endcase
|
||||||
|
return burst_type;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
// Ubiquitous, familiar log2 function
|
||||||
|
//----------------------------------------------------
|
||||||
|
function integer log2;
|
||||||
|
input integer value;
|
||||||
|
|
||||||
|
value = value - 1;
|
||||||
|
for(log2 = 0; value > 0; log2 = log2 + 1)
|
||||||
|
value = value >> 1;
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// This component will read address and size and check
|
||||||
|
// if this is aligned or not. If not then it will align this address to the size
|
||||||
|
// of the transfer:
|
||||||
|
// Check alignment:
|
||||||
|
// - With data width, can define maximun how many lower bits of address to indicate this
|
||||||
|
// address align to the size
|
||||||
|
// - Ex: 32 bits data => size can be: 1, 2, 4 bytes
|
||||||
|
// For 4 bytes: when 2 lower bits of address equal 0, this is aligned address
|
||||||
|
// addr=00|00| (0), 01|00| (4) => align to size of 4 bytes
|
||||||
|
// addr=00|01| (1) => start addr at 1, is not aligned to size 4 byte
|
||||||
|
// For 2 bytes: use last one bit to indicate algined or not
|
||||||
|
// addr=000|0| (0), 001|0| (2) => align to size of 2 bytes
|
||||||
|
// addr=000|1| (1), 001|1| (3) => not align to 2 bytes
|
||||||
|
// As size runtime change, creat mask and change accordingly to size, can detect address alignment
|
||||||
|
// and to align to size, apply this mask with zero to the address.
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// THe function return a vector which has width [(SELECT_BITS * 2) -1 : 0]
|
||||||
|
// in which the first part contains the mask to check if this address aligned or not
|
||||||
|
// second part contains the mast to mask address to align to size
|
||||||
|
|
||||||
|
function reg[(SELECT_BITS*2)-1 : 0] mask_select_and_align_address;
|
||||||
|
input [ADDR_W-1:0] address;
|
||||||
|
input [SIZE_W-1:0] size; // size is in AXI coding: 001 -> 2 bytes
|
||||||
|
|
||||||
|
integer i;
|
||||||
|
reg [SELECT_BITS-1:0] mask_address;
|
||||||
|
reg [SELECT_BITS-1:0] check_unaligned; // any bits =1 -> unalgined (except size = 0; 1 byte)
|
||||||
|
mask_address = '1;
|
||||||
|
check_unaligned = '0;
|
||||||
|
for(i = 0; i < SELECT_BITS ; i = i + 1) begin
|
||||||
|
if (i < size) begin
|
||||||
|
check_unaligned[i] = address[i];
|
||||||
|
mask_address[i] = 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
mask_select_and_align_address = {check_unaligned,mask_address};
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reg [ADDR_W-1 : 0] in_address;
|
||||||
|
reg [ADDR_W-1 : 0] first_address_aligned;
|
||||||
|
reg [SIZE_W-1 : 0] in_size;
|
||||||
|
reg [(SELECT_BITS*2)-1 : 0] output_masks;
|
||||||
|
// Extract information from input data
|
||||||
|
assign in_address = in_data[SIZE_W+ADDR_W-1 : SIZE_W];
|
||||||
|
assign in_size = in_data[SIZE_W-1 : 0];
|
||||||
|
|
||||||
|
// Generate the masks
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
output_masks = mask_select_and_align_address(in_address, in_size);
|
||||||
|
end
|
||||||
|
|
||||||
|
// Align address if needed
|
||||||
|
|
||||||
|
generate
|
||||||
|
// SELECT_BITS == 1: input packet has 1 NUMSYMBOLS (1 bytes), it is aligned
|
||||||
|
if (SELECT_BITS == 0)
|
||||||
|
assign first_address_aligned = in_address;
|
||||||
|
else begin
|
||||||
|
// SELECT_BITS ==1 :input packet 2 bytes (2 SYMBOLS)
|
||||||
|
wire [SELECT_BITS-1 : 0] aligned_address_bits;
|
||||||
|
if (SELECT_BITS == 1)
|
||||||
|
assign aligned_address_bits = in_address[0] & output_masks[0];
|
||||||
|
else
|
||||||
|
assign aligned_address_bits = in_address[SELECT_BITS-1:0] & output_masks[SELECT_BITS-1:0];
|
||||||
|
assign first_address_aligned = {in_address[ADDR_W-1 : SELECT_BITS], aligned_address_bits};
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Increment address base on size, first address keep the same
|
||||||
|
generate
|
||||||
|
if (INCREMENT_ADDRESS)
|
||||||
|
begin
|
||||||
|
reg [ADDR_W-1 : 0] increment_address;
|
||||||
|
reg [ADDR_W-1 : 0] out_aligned_address_burst;
|
||||||
|
reg [ADDR_W-1 : 0] address_burst;
|
||||||
|
reg [ADDR_W-1 : 0] base_address;
|
||||||
|
reg [9 : 0] number_bytes_transfer;
|
||||||
|
reg [ADDR_W-1 : 0] burstwrap_mask;
|
||||||
|
reg [ADDR_W-1 : 0] burst_address_high;
|
||||||
|
reg [ADDR_W-1 : 0] burst_address_low;
|
||||||
|
reg [BURSTWRAP_W-2 :0] in_burstwrap_boundary;
|
||||||
|
reg [TYPE_W-1 : 0] in_type;
|
||||||
|
//------------------------------------------------
|
||||||
|
// Use the extended burstwrap value to split the high (constant) and
|
||||||
|
// low (changing) part of the address
|
||||||
|
//-----------------------------------------------
|
||||||
|
assign in_type = in_data[SIZE_W+ADDR_W+TYPE_W-1 : SIZE_W+ADDR_W];
|
||||||
|
assign in_burstwrap_boundary = in_data[IN_DATA_W-1 : ADDR_W+TYPE_W+SIZE_W];
|
||||||
|
assign burstwrap_mask = {{(ADDR_W - BURSTWRAP_W){1'b0}}, in_burstwrap_boundary};
|
||||||
|
assign burst_address_high = out_aligned_address_burst & ~burstwrap_mask;
|
||||||
|
assign burst_address_low = out_aligned_address_burst;
|
||||||
|
assign number_bytes_transfer = bytes_in_transfer(in_size);
|
||||||
|
assign write_burst_type = burst_type_decode(in_type);
|
||||||
|
|
||||||
|
always @*
|
||||||
|
begin
|
||||||
|
if (in_sop)
|
||||||
|
begin
|
||||||
|
out_aligned_address_burst = in_address;
|
||||||
|
base_address = first_address_aligned;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
out_aligned_address_burst = address_burst;
|
||||||
|
base_address = out_aligned_address_burst;
|
||||||
|
end
|
||||||
|
case (write_burst_type)
|
||||||
|
INCR:
|
||||||
|
increment_address = base_address + number_bytes_transfer;
|
||||||
|
WRAP:
|
||||||
|
increment_address = ((burst_address_low + number_bytes_transfer) & burstwrap_mask) | burst_address_high;
|
||||||
|
FIXED:
|
||||||
|
increment_address = out_aligned_address_burst;
|
||||||
|
default:
|
||||||
|
increment_address = base_address + number_bytes_transfer;
|
||||||
|
endcase // case (write_burst_type)
|
||||||
|
end // always @ *
|
||||||
|
always_ff @(posedge clk, negedge reset)
|
||||||
|
begin
|
||||||
|
if (!reset)
|
||||||
|
begin
|
||||||
|
address_burst <= '0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
if (in_valid & out_ready)
|
||||||
|
address_burst <= increment_address;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// send data to output with 2 part: [mask_t0_algin][address_aligned_increment]
|
||||||
|
assign out_data = {output_masks[SELECT_BITS-1 : 0], out_aligned_address_burst};
|
||||||
|
end // if (INCREMENT_ADDRESS)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
assign out_data = {output_masks[SELECT_BITS-1 : 0], first_address_aligned};
|
||||||
|
end // else: !if(INCREMENT_ADDRESS)
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
272
ip/altera/ddr3/altera_merlin_arbitrator.sv
Normal file
272
ip/altera/ddr3/altera_merlin_arbitrator.sv
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2010 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/main/ip/merlin/altera_merlin_std_arbitrator/altera_merlin_std_arbitrator_core.sv#3 $
|
||||||
|
// $Revision: #3 $
|
||||||
|
// $Date: 2010/07/07 $
|
||||||
|
// $Author: jyeap $
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
Round-robin/fixed arbitration implementation.
|
||||||
|
|
||||||
|
Q: how do you find the least-significant set-bit in an n-bit binary number, X?
|
||||||
|
|
||||||
|
A: M = X & (~X + 1)
|
||||||
|
|
||||||
|
Example: X = 101000100
|
||||||
|
101000100 &
|
||||||
|
010111011 + 1 =
|
||||||
|
|
||||||
|
101000100 &
|
||||||
|
010111100 =
|
||||||
|
-----------
|
||||||
|
000000100
|
||||||
|
|
||||||
|
The method can be generalized to find the first set-bit
|
||||||
|
at a bit index no lower than bit-index N, simply by adding
|
||||||
|
2**N rather than 1.
|
||||||
|
|
||||||
|
|
||||||
|
Q: how does this relate to round-robin arbitration?
|
||||||
|
A:
|
||||||
|
Let X be the concatenation of all request signals.
|
||||||
|
Let the number to be added to X (hereafter called the
|
||||||
|
top_priority) initialize to 1, and be assigned from the
|
||||||
|
concatenation of the previous saved-grant, left-rotated
|
||||||
|
by one position, each time arbitration occurs. The
|
||||||
|
concatenation of grants is then M.
|
||||||
|
|
||||||
|
Problem: consider this case:
|
||||||
|
|
||||||
|
top_priority = 010000
|
||||||
|
request = 001001
|
||||||
|
~request + top_priority = 000110
|
||||||
|
next_grant = 000000 <- no one is granted!
|
||||||
|
|
||||||
|
There was no "set bit at a bit index no lower than bit-index 4", so
|
||||||
|
the result was 0.
|
||||||
|
|
||||||
|
We need to propagate the carry out from (~request + top_priority) to the LSB, so
|
||||||
|
that the sum becomes 000111, and next_grant is 000001. This operation could be
|
||||||
|
called a "circular add".
|
||||||
|
|
||||||
|
A bit of experimentation on the circular add reveals a significant amount of
|
||||||
|
delay in exiting and re-entering the carry chain - this will vary with device
|
||||||
|
family. Quartus also reports a combinational loop warning. Finally,
|
||||||
|
Modelsim 6.3g has trouble with the expression, evaluating it to 'X'. But
|
||||||
|
Modelsim _doesn't_ report a combinational loop!)
|
||||||
|
|
||||||
|
An alternate solution: concatenate the request vector with itself, and OR
|
||||||
|
corresponding bits from the top and bottom halves to determine next_grant.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
top_priority = 010000
|
||||||
|
{request, request} = 001001 001001
|
||||||
|
{~request, ~request} + top_priority = 110111 000110
|
||||||
|
result of & operation = 000001 000000
|
||||||
|
next_grant = 000001
|
||||||
|
|
||||||
|
Notice that if request = 0, the sum operation will overflow, but we can ignore
|
||||||
|
this; the next_grant result is 0 (no one granted), as you might expect.
|
||||||
|
In the implementation, the last-granted value must be maintained as
|
||||||
|
a non-zero value - best probably simply not to update it when no requests
|
||||||
|
occur.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_merlin_arbitrator
|
||||||
|
#(
|
||||||
|
parameter NUM_REQUESTERS = 8,
|
||||||
|
// --------------------------------------
|
||||||
|
// Implemented schemes
|
||||||
|
// "round-robin"
|
||||||
|
// "fixed-priority"
|
||||||
|
// "no-arb"
|
||||||
|
// --------------------------------------
|
||||||
|
parameter SCHEME = "round-robin",
|
||||||
|
parameter PIPELINE = 0
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Requests
|
||||||
|
// --------------------------------------
|
||||||
|
input [NUM_REQUESTERS-1:0] request,
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Grants
|
||||||
|
// --------------------------------------
|
||||||
|
output [NUM_REQUESTERS-1:0] grant,
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Control Signals
|
||||||
|
// --------------------------------------
|
||||||
|
input increment_top_priority,
|
||||||
|
input save_top_priority
|
||||||
|
);
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Signals
|
||||||
|
// --------------------------------------
|
||||||
|
wire [NUM_REQUESTERS-1:0] top_priority;
|
||||||
|
reg [NUM_REQUESTERS-1:0] top_priority_reg;
|
||||||
|
reg [NUM_REQUESTERS-1:0] last_grant;
|
||||||
|
wire [2*NUM_REQUESTERS-1:0] result;
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Scheme Selection
|
||||||
|
// --------------------------------------
|
||||||
|
generate
|
||||||
|
if (SCHEME == "round-robin" && NUM_REQUESTERS > 1) begin
|
||||||
|
assign top_priority = top_priority_reg;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
// Fixed arbitration (or single-requester corner case)
|
||||||
|
assign top_priority = 1'b1;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Decision Logic
|
||||||
|
// --------------------------------------
|
||||||
|
altera_merlin_arb_adder
|
||||||
|
#(
|
||||||
|
.WIDTH (2 * NUM_REQUESTERS)
|
||||||
|
)
|
||||||
|
adder
|
||||||
|
(
|
||||||
|
.a ({ ~request, ~request }),
|
||||||
|
.b ({{NUM_REQUESTERS{1'b0}}, top_priority}),
|
||||||
|
.sum (result)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
generate if (SCHEME == "no-arb") begin
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// No arbitration: just wire request directly to grant
|
||||||
|
// --------------------------------------
|
||||||
|
assign grant = request;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
// Do the math in double-vector domain
|
||||||
|
wire [2*NUM_REQUESTERS-1:0] grant_double_vector;
|
||||||
|
assign grant_double_vector = {request, request} & result;
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Extract grant from the top and bottom halves
|
||||||
|
// of the double vector.
|
||||||
|
// --------------------------------------
|
||||||
|
assign grant =
|
||||||
|
grant_double_vector[NUM_REQUESTERS - 1 : 0] |
|
||||||
|
grant_double_vector[2 * NUM_REQUESTERS - 1 : NUM_REQUESTERS];
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Left-rotate the last grant vector to create top_priority.
|
||||||
|
// --------------------------------------
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
top_priority_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (PIPELINE) begin
|
||||||
|
if (increment_top_priority) begin
|
||||||
|
top_priority_reg <= (|request) ? {grant[NUM_REQUESTERS-2:0],
|
||||||
|
grant[NUM_REQUESTERS-1]} : top_priority_reg;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
if (increment_top_priority) begin
|
||||||
|
if (|request)
|
||||||
|
top_priority_reg <= { grant[NUM_REQUESTERS-2:0],
|
||||||
|
grant[NUM_REQUESTERS-1] };
|
||||||
|
else
|
||||||
|
top_priority_reg <= { top_priority_reg[NUM_REQUESTERS-2:0], top_priority_reg[NUM_REQUESTERS-1] };
|
||||||
|
end
|
||||||
|
else if (save_top_priority) begin
|
||||||
|
top_priority_reg <= grant;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Adder for the standard arbitrator
|
||||||
|
// ----------------------------------------------
|
||||||
|
module altera_merlin_arb_adder
|
||||||
|
#(
|
||||||
|
parameter WIDTH = 8
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input [WIDTH-1:0] a,
|
||||||
|
input [WIDTH-1:0] b,
|
||||||
|
|
||||||
|
output [WIDTH-1:0] sum
|
||||||
|
);
|
||||||
|
|
||||||
|
wire [WIDTH:0] sum_lint;
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Benchmarks indicate that for small widths, the full
|
||||||
|
// adder has higher fmax because synthesis can merge
|
||||||
|
// it with the mux, allowing partial decisions to be
|
||||||
|
// made early.
|
||||||
|
//
|
||||||
|
// The magic number is 4 requesters, which means an
|
||||||
|
// 8 bit adder.
|
||||||
|
// ----------------------------------------------
|
||||||
|
genvar i;
|
||||||
|
generate if (WIDTH <= 8) begin : full_adder
|
||||||
|
|
||||||
|
wire cout[WIDTH-1:0];
|
||||||
|
|
||||||
|
assign sum[0] = (a[0] ^ b[0]);
|
||||||
|
assign cout[0] = (a[0] & b[0]);
|
||||||
|
|
||||||
|
for (i = 1; i < WIDTH; i = i+1) begin : arb
|
||||||
|
|
||||||
|
assign sum[i] = (a[i] ^ b[i]) ^ cout[i-1];
|
||||||
|
assign cout[i] = (a[i] & b[i]) | (cout[i-1] & (a[i] ^ b[i]));
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end else begin : carry_chain
|
||||||
|
|
||||||
|
assign sum_lint = a + b;
|
||||||
|
assign sum = sum_lint[WIDTH-1:0];
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
261
ip/altera/ddr3/altera_merlin_burst_adapter.sv
Normal file
261
ip/altera/ddr3/altera_merlin_burst_adapter.sv
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// Top level for the burst adapter. This selects the
|
||||||
|
// implementation for the adapter, based on the
|
||||||
|
// parameterization.
|
||||||
|
// -----------------------------------------------------
|
||||||
|
module altera_merlin_burst_adapter
|
||||||
|
#(
|
||||||
|
parameter
|
||||||
|
// Indicates the implementation to instantiate:
|
||||||
|
// "13.1" means the slow, inexpensive generic burst converter.
|
||||||
|
// "new" means the fast, expensive per-burst converter.
|
||||||
|
ADAPTER_VERSION = "13.1",
|
||||||
|
|
||||||
|
// Indicates if this adapter needs to support read bursts
|
||||||
|
// (almost always true).
|
||||||
|
COMPRESSED_READ_SUPPORT = 1,
|
||||||
|
|
||||||
|
// Standard Merlin packet parameters that indicate
|
||||||
|
// field position within the packet
|
||||||
|
PKT_BEGIN_BURST = 81,
|
||||||
|
PKT_ADDR_H = 79,
|
||||||
|
PKT_ADDR_L = 48,
|
||||||
|
PKT_BYTE_CNT_H = 5,
|
||||||
|
PKT_BYTE_CNT_L = 0,
|
||||||
|
PKT_BURSTWRAP_H = 11,
|
||||||
|
PKT_BURSTWRAP_L = 6,
|
||||||
|
PKT_TRANS_COMPRESSED_READ = 14,
|
||||||
|
PKT_TRANS_WRITE = 13,
|
||||||
|
PKT_TRANS_READ = 12,
|
||||||
|
PKT_BYTEEN_H = 83,
|
||||||
|
PKT_BYTEEN_L = 80,
|
||||||
|
PKT_BURST_TYPE_H = 88,
|
||||||
|
PKT_BURST_TYPE_L = 87,
|
||||||
|
PKT_BURST_SIZE_H = 86,
|
||||||
|
PKT_BURST_SIZE_L = 84,
|
||||||
|
ST_DATA_W = 89,
|
||||||
|
ST_CHANNEL_W = 8,
|
||||||
|
|
||||||
|
// Component-specific parameters. Explained
|
||||||
|
// in the implementation levels
|
||||||
|
IN_NARROW_SIZE = 0,
|
||||||
|
NO_WRAP_SUPPORT = 0,
|
||||||
|
INCOMPLETE_WRAP_SUPPORT = 1,
|
||||||
|
BURSTWRAP_CONST_MASK = 0,
|
||||||
|
BURSTWRAP_CONST_VALUE = -1,
|
||||||
|
|
||||||
|
OUT_NARROW_SIZE = 0,
|
||||||
|
OUT_FIXED = 0,
|
||||||
|
OUT_COMPLETE_WRAP = 0,
|
||||||
|
BYTEENABLE_SYNTHESIS = 0,
|
||||||
|
PIPE_INPUTS = 0,
|
||||||
|
|
||||||
|
OUT_BYTE_CNT_H = 5,
|
||||||
|
OUT_BURSTWRAP_H = 11
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Sink (Input)
|
||||||
|
// -------------------
|
||||||
|
input sink0_valid,
|
||||||
|
input [ST_DATA_W-1 : 0] sink0_data,
|
||||||
|
input [ST_CHANNEL_W-1 : 0] sink0_channel,
|
||||||
|
input sink0_startofpacket,
|
||||||
|
input sink0_endofpacket,
|
||||||
|
output reg sink0_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Source (Output)
|
||||||
|
// -------------------
|
||||||
|
output wire source0_valid,
|
||||||
|
output wire [ST_DATA_W-1 : 0] source0_data,
|
||||||
|
output wire [ST_CHANNEL_W-1 : 0] source0_channel,
|
||||||
|
output wire source0_startofpacket,
|
||||||
|
output wire source0_endofpacket,
|
||||||
|
input source0_ready
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam PKT_BURSTWRAP_W = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1;
|
||||||
|
|
||||||
|
generate if (COMPRESSED_READ_SUPPORT == 0) begin : altera_merlin_burst_adapter_uncompressed_only
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// The reduced version of the adapter is only meant to be used on
|
||||||
|
// non-bursting wide to narrow links.
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
altera_merlin_burst_adapter_uncompressed_only #(
|
||||||
|
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
|
||||||
|
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L),
|
||||||
|
.PKT_BYTEEN_H (PKT_BYTEEN_H),
|
||||||
|
.PKT_BYTEEN_L (PKT_BYTEEN_L),
|
||||||
|
.ST_DATA_W (ST_DATA_W),
|
||||||
|
.ST_CHANNEL_W (ST_CHANNEL_W)
|
||||||
|
) burst_adapter (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.sink0_valid (sink0_valid),
|
||||||
|
.sink0_data (sink0_data),
|
||||||
|
.sink0_channel (sink0_channel),
|
||||||
|
.sink0_startofpacket (sink0_startofpacket),
|
||||||
|
.sink0_endofpacket (sink0_endofpacket),
|
||||||
|
.sink0_ready (sink0_ready),
|
||||||
|
.source0_valid (source0_valid),
|
||||||
|
.source0_data (source0_data),
|
||||||
|
.source0_channel (source0_channel),
|
||||||
|
.source0_startofpacket (source0_startofpacket),
|
||||||
|
.source0_endofpacket (source0_endofpacket),
|
||||||
|
.source0_ready (source0_ready)
|
||||||
|
);
|
||||||
|
|
||||||
|
end
|
||||||
|
else if (ADAPTER_VERSION == "13.1") begin : altera_merlin_burst_adapter_13_1
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// This is the generic converter implementation, which attempts
|
||||||
|
// to convert all burst types with a generalized conversion
|
||||||
|
// function. This results in low area, but low fmax.
|
||||||
|
// -----------------------------------------------------
|
||||||
|
altera_merlin_burst_adapter_13_1 #(
|
||||||
|
.PKT_BEGIN_BURST (PKT_BEGIN_BURST),
|
||||||
|
.PKT_ADDR_H (PKT_ADDR_H ),
|
||||||
|
.PKT_ADDR_L (PKT_ADDR_L),
|
||||||
|
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
|
||||||
|
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L ),
|
||||||
|
.PKT_BURSTWRAP_H (PKT_BURSTWRAP_H),
|
||||||
|
.PKT_BURSTWRAP_L (PKT_BURSTWRAP_L),
|
||||||
|
.PKT_TRANS_COMPRESSED_READ (PKT_TRANS_COMPRESSED_READ),
|
||||||
|
.PKT_TRANS_WRITE (PKT_TRANS_WRITE),
|
||||||
|
.PKT_TRANS_READ (PKT_TRANS_READ),
|
||||||
|
.PKT_BYTEEN_H (PKT_BYTEEN_H),
|
||||||
|
.PKT_BYTEEN_L (PKT_BYTEEN_L),
|
||||||
|
.PKT_BURST_TYPE_H (PKT_BURST_TYPE_H),
|
||||||
|
.PKT_BURST_TYPE_L (PKT_BURST_TYPE_L),
|
||||||
|
.PKT_BURST_SIZE_H (PKT_BURST_SIZE_H),
|
||||||
|
.PKT_BURST_SIZE_L (PKT_BURST_SIZE_L),
|
||||||
|
.IN_NARROW_SIZE (IN_NARROW_SIZE),
|
||||||
|
.BYTEENABLE_SYNTHESIS (BYTEENABLE_SYNTHESIS),
|
||||||
|
.OUT_NARROW_SIZE (OUT_NARROW_SIZE),
|
||||||
|
.OUT_FIXED (OUT_FIXED),
|
||||||
|
.OUT_COMPLETE_WRAP (OUT_COMPLETE_WRAP),
|
||||||
|
.ST_DATA_W (ST_DATA_W),
|
||||||
|
.ST_CHANNEL_W (ST_CHANNEL_W),
|
||||||
|
.BURSTWRAP_CONST_MASK (BURSTWRAP_CONST_MASK),
|
||||||
|
.BURSTWRAP_CONST_VALUE (BURSTWRAP_CONST_VALUE),
|
||||||
|
.PIPE_INPUTS (PIPE_INPUTS),
|
||||||
|
.NO_WRAP_SUPPORT (NO_WRAP_SUPPORT),
|
||||||
|
.OUT_BYTE_CNT_H (OUT_BYTE_CNT_H),
|
||||||
|
.OUT_BURSTWRAP_H (OUT_BURSTWRAP_H)
|
||||||
|
) burst_adapter (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.sink0_valid (sink0_valid),
|
||||||
|
.sink0_data (sink0_data),
|
||||||
|
.sink0_channel (sink0_channel),
|
||||||
|
.sink0_startofpacket (sink0_startofpacket),
|
||||||
|
.sink0_endofpacket (sink0_endofpacket),
|
||||||
|
.sink0_ready (sink0_ready),
|
||||||
|
.source0_valid (source0_valid),
|
||||||
|
.source0_data (source0_data),
|
||||||
|
.source0_channel (source0_channel),
|
||||||
|
.source0_startofpacket (source0_startofpacket),
|
||||||
|
.source0_endofpacket (source0_endofpacket),
|
||||||
|
.source0_ready (source0_ready)
|
||||||
|
);
|
||||||
|
|
||||||
|
end
|
||||||
|
else begin : altera_merlin_burst_adapter_new
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// This is the per-burst-type converter implementation. This attempts
|
||||||
|
// to convert bursts with specialized functions for each burst
|
||||||
|
// type. This typically results in higher area, but higher fmax.
|
||||||
|
// -----------------------------------------------------
|
||||||
|
altera_merlin_burst_adapter_new #(
|
||||||
|
.PKT_BEGIN_BURST (PKT_BEGIN_BURST),
|
||||||
|
.PKT_ADDR_H (PKT_ADDR_H ),
|
||||||
|
.PKT_ADDR_L (PKT_ADDR_L),
|
||||||
|
.PKT_BYTE_CNT_H (PKT_BYTE_CNT_H),
|
||||||
|
.PKT_BYTE_CNT_L (PKT_BYTE_CNT_L ),
|
||||||
|
.PKT_BURSTWRAP_H (PKT_BURSTWRAP_H),
|
||||||
|
.PKT_BURSTWRAP_L (PKT_BURSTWRAP_L),
|
||||||
|
.PKT_TRANS_COMPRESSED_READ (PKT_TRANS_COMPRESSED_READ),
|
||||||
|
.PKT_TRANS_WRITE (PKT_TRANS_WRITE),
|
||||||
|
.PKT_TRANS_READ (PKT_TRANS_READ),
|
||||||
|
.PKT_BYTEEN_H (PKT_BYTEEN_H),
|
||||||
|
.PKT_BYTEEN_L (PKT_BYTEEN_L),
|
||||||
|
.PKT_BURST_TYPE_H (PKT_BURST_TYPE_H),
|
||||||
|
.PKT_BURST_TYPE_L (PKT_BURST_TYPE_L),
|
||||||
|
.PKT_BURST_SIZE_H (PKT_BURST_SIZE_H),
|
||||||
|
.PKT_BURST_SIZE_L (PKT_BURST_SIZE_L),
|
||||||
|
.IN_NARROW_SIZE (IN_NARROW_SIZE),
|
||||||
|
.BYTEENABLE_SYNTHESIS (BYTEENABLE_SYNTHESIS),
|
||||||
|
.OUT_NARROW_SIZE (OUT_NARROW_SIZE),
|
||||||
|
.OUT_FIXED (OUT_FIXED),
|
||||||
|
.OUT_COMPLETE_WRAP (OUT_COMPLETE_WRAP),
|
||||||
|
.ST_DATA_W (ST_DATA_W),
|
||||||
|
.ST_CHANNEL_W (ST_CHANNEL_W),
|
||||||
|
.BURSTWRAP_CONST_MASK (BURSTWRAP_CONST_MASK),
|
||||||
|
.BURSTWRAP_CONST_VALUE (BURSTWRAP_CONST_VALUE),
|
||||||
|
.PIPE_INPUTS (PIPE_INPUTS),
|
||||||
|
.NO_WRAP_SUPPORT (NO_WRAP_SUPPORT),
|
||||||
|
.INCOMPLETE_WRAP_SUPPORT (INCOMPLETE_WRAP_SUPPORT),
|
||||||
|
.OUT_BYTE_CNT_H (OUT_BYTE_CNT_H),
|
||||||
|
.OUT_BURSTWRAP_H (OUT_BURSTWRAP_H)
|
||||||
|
) burst_adapter (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.sink0_valid (sink0_valid),
|
||||||
|
.sink0_data (sink0_data),
|
||||||
|
.sink0_channel (sink0_channel),
|
||||||
|
.sink0_startofpacket (sink0_startofpacket),
|
||||||
|
.sink0_endofpacket (sink0_endofpacket),
|
||||||
|
.sink0_ready (sink0_ready),
|
||||||
|
.source0_valid (source0_valid),
|
||||||
|
.source0_data (source0_data),
|
||||||
|
.source0_channel (source0_channel),
|
||||||
|
.source0_startofpacket (source0_startofpacket),
|
||||||
|
.source0_endofpacket (source0_endofpacket),
|
||||||
|
.source0_ready (source0_ready)
|
||||||
|
);
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// synthesis translate_off
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// Simulation-only check for incoming burstwrap values inconsistent with
|
||||||
|
// BURSTWRAP_CONST_MASK, which would indicate a paramerization error.
|
||||||
|
//
|
||||||
|
// Should be turned into an assertion, really.
|
||||||
|
// -----------------------------------------------------
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (~reset && sink0_valid &&
|
||||||
|
BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0] &
|
||||||
|
(BURSTWRAP_CONST_VALUE[PKT_BURSTWRAP_W - 1:0] ^ sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L])
|
||||||
|
) begin
|
||||||
|
$display("%t: %m: Error: burstwrap value %X is inconsistent with BURSTWRAP_CONST_MASK value %X", $time(), sink0_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L], BURSTWRAP_CONST_MASK[PKT_BURSTWRAP_W - 1:0]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// synthesis translate_on
|
||||||
|
|
||||||
|
endmodule
|
1174
ip/altera/ddr3/altera_merlin_burst_adapter_13_1.sv
Normal file
1174
ip/altera/ddr3/altera_merlin_burst_adapter_13_1.sv
Normal file
File diff suppressed because it is too large
Load Diff
1890
ip/altera/ddr3/altera_merlin_burst_adapter_new.sv
Normal file
1890
ip/altera/ddr3/altera_merlin_burst_adapter_new.sv
Normal file
File diff suppressed because it is too large
Load Diff
94
ip/altera/ddr3/altera_merlin_burst_adapter_uncmpr.sv
Normal file
94
ip/altera/ddr3/altera_merlin_burst_adapter_uncmpr.sv
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2012 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/main/ip/merlin/altera_merlin_burst_adapter/altera_merlin_burst_adapter.sv#68 $
|
||||||
|
// $Revision: #68 $
|
||||||
|
// $Date: 2014/01/23 $
|
||||||
|
// $Author: wkleong $
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Adapter for uncompressed transactions only. This adapter will
|
||||||
|
// typically be used to adapt burst length for non-bursting
|
||||||
|
// wide to narrow Avalon links.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
module altera_merlin_burst_adapter_uncompressed_only
|
||||||
|
#(
|
||||||
|
parameter
|
||||||
|
PKT_BYTE_CNT_H = 5,
|
||||||
|
PKT_BYTE_CNT_L = 0,
|
||||||
|
PKT_BYTEEN_H = 83,
|
||||||
|
PKT_BYTEEN_L = 80,
|
||||||
|
ST_DATA_W = 84,
|
||||||
|
ST_CHANNEL_W = 8
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Sink (Input)
|
||||||
|
// -------------------
|
||||||
|
input sink0_valid,
|
||||||
|
input [ST_DATA_W-1 : 0] sink0_data,
|
||||||
|
input [ST_CHANNEL_W-1 : 0] sink0_channel,
|
||||||
|
input sink0_startofpacket,
|
||||||
|
input sink0_endofpacket,
|
||||||
|
output reg sink0_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Source (Output)
|
||||||
|
// -------------------
|
||||||
|
output reg source0_valid,
|
||||||
|
output reg [ST_DATA_W-1 : 0] source0_data,
|
||||||
|
output reg [ST_CHANNEL_W-1 : 0] source0_channel,
|
||||||
|
output reg source0_startofpacket,
|
||||||
|
output reg source0_endofpacket,
|
||||||
|
input source0_ready
|
||||||
|
);
|
||||||
|
localparam
|
||||||
|
PKT_BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
|
||||||
|
NUM_SYMBOLS = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
|
||||||
|
|
||||||
|
wire [PKT_BYTE_CNT_W - 1 : 0] num_symbols_sig = NUM_SYMBOLS[PKT_BYTE_CNT_W - 1 : 0];
|
||||||
|
|
||||||
|
always_comb begin : source0_data_assignments
|
||||||
|
source0_valid = sink0_valid;
|
||||||
|
source0_channel = sink0_channel;
|
||||||
|
source0_startofpacket = sink0_startofpacket;
|
||||||
|
source0_endofpacket = sink0_endofpacket;
|
||||||
|
|
||||||
|
source0_data = sink0_data;
|
||||||
|
source0_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L] = num_symbols_sig;
|
||||||
|
|
||||||
|
sink0_ready = source0_ready;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
296
ip/altera/ddr3/altera_merlin_burst_uncompressor.sv
Normal file
296
ip/altera/ddr3/altera_merlin_burst_uncompressor.sv
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2012 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_slave_agent/altera_merlin_burst_uncompressor.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Merlin Burst Uncompressor
|
||||||
|
//
|
||||||
|
// Compressed read bursts -> uncompressed
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_merlin_burst_uncompressor
|
||||||
|
#(
|
||||||
|
parameter ADDR_W = 16,
|
||||||
|
parameter BURSTWRAP_W = 3,
|
||||||
|
parameter BYTE_CNT_W = 4,
|
||||||
|
parameter PKT_SYMBOLS = 4,
|
||||||
|
parameter BURST_SIZE_W = 3
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// sink ST signals
|
||||||
|
input sink_startofpacket,
|
||||||
|
input sink_endofpacket,
|
||||||
|
input sink_valid,
|
||||||
|
output sink_ready,
|
||||||
|
|
||||||
|
// sink ST "data"
|
||||||
|
input [ADDR_W - 1: 0] sink_addr,
|
||||||
|
input [BURSTWRAP_W - 1 : 0] sink_burstwrap,
|
||||||
|
input [BYTE_CNT_W - 1 : 0] sink_byte_cnt,
|
||||||
|
input sink_is_compressed,
|
||||||
|
input [BURST_SIZE_W-1 : 0] sink_burstsize,
|
||||||
|
|
||||||
|
// source ST signals
|
||||||
|
output source_startofpacket,
|
||||||
|
output source_endofpacket,
|
||||||
|
output source_valid,
|
||||||
|
input source_ready,
|
||||||
|
|
||||||
|
// source ST "data"
|
||||||
|
output [ADDR_W - 1: 0] source_addr,
|
||||||
|
output [BURSTWRAP_W - 1 : 0] source_burstwrap,
|
||||||
|
output [BYTE_CNT_W - 1 : 0] source_byte_cnt,
|
||||||
|
|
||||||
|
// Note: in the slave agent, the output should always be uncompressed. In
|
||||||
|
// other applications, it may be required to leave-compressed or not. How to
|
||||||
|
// control? Seems like a simple mux - pass-through if no uncompression is
|
||||||
|
// required.
|
||||||
|
output source_is_compressed,
|
||||||
|
output [BURST_SIZE_W-1 : 0] source_burstsize
|
||||||
|
);
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
// AXSIZE decoding
|
||||||
|
//
|
||||||
|
// Turns the axsize value into the actual number of bytes
|
||||||
|
// being transferred.
|
||||||
|
// ---------------------------------------------------
|
||||||
|
function reg[63:0] bytes_in_transfer;
|
||||||
|
input [BURST_SIZE_W-1:0] axsize;
|
||||||
|
case (axsize)
|
||||||
|
4'b0000: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000001;
|
||||||
|
4'b0001: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000010;
|
||||||
|
4'b0010: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000100;
|
||||||
|
4'b0011: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000001000;
|
||||||
|
4'b0100: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000010000;
|
||||||
|
4'b0101: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000100000;
|
||||||
|
4'b0110: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000001000000;
|
||||||
|
4'b0111: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000010000000;
|
||||||
|
4'b1000: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000100000000;
|
||||||
|
4'b1001: bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000001000000000;
|
||||||
|
default:bytes_in_transfer = 64'b0000000000000000000000000000000000000000000000000000000000000001;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
// num_symbols is PKT_SYMBOLS, appropriately sized.
|
||||||
|
wire [31:0] int_num_symbols = PKT_SYMBOLS;
|
||||||
|
wire [BYTE_CNT_W-1:0] num_symbols = int_num_symbols[BYTE_CNT_W-1:0];
|
||||||
|
|
||||||
|
// def: Burst Compression. In a merlin network, a compressed burst is one
|
||||||
|
// which is transmitted in a single beat. Example: read burst. In
|
||||||
|
// constrast, an uncompressed burst (example: write burst) is transmitted in
|
||||||
|
// one beat per writedata item.
|
||||||
|
//
|
||||||
|
// For compressed bursts which require response packets, burst
|
||||||
|
// uncompression is required. Concrete example: a read burst of size 8
|
||||||
|
// occupies one response-fifo position. When that fifo position reaches the
|
||||||
|
// front of the FIFO, the slave starts providing the required 8 readdatavalid
|
||||||
|
// pulses. The 8 return response beats must be provided in a single packet,
|
||||||
|
// with incrementing address and decrementing byte_cnt fields. Upon receipt
|
||||||
|
// of the final readdata item of the burst, the response FIFO item is
|
||||||
|
// retired.
|
||||||
|
// Burst uncompression logic provides:
|
||||||
|
// a) 2-state FSM (idle, busy)
|
||||||
|
// reset to idle state
|
||||||
|
// transition to busy state for 2nd and subsequent rdv pulses
|
||||||
|
// - a single-cycle burst (aka non-burst read) causes no transition to
|
||||||
|
// busy state.
|
||||||
|
// b) response startofpacket/endofpacket logic. The response FIFO item
|
||||||
|
// will have sop asserted, and may have eop asserted. (In the case of
|
||||||
|
// multiple read bursts transmit in the command fabric in a single packet,
|
||||||
|
// the eop assertion will come in a later FIFO item.) To support packet
|
||||||
|
// conservation, and emit a well-formed packet on the response fabric,
|
||||||
|
// i) response fabric startofpacket is asserted only for the first resp.
|
||||||
|
// beat;
|
||||||
|
// ii) response fabric endofpacket is asserted only for the last resp.
|
||||||
|
// beat.
|
||||||
|
// c) response address field. The response address field contains an
|
||||||
|
// incrementing sequence, such that each readdata item is associated with
|
||||||
|
// its slave-map location. N.b. a) computing the address correctly requires
|
||||||
|
// knowledge of burstwrap behavior b) there may be no clients of the address
|
||||||
|
// field, which makes this field a good target for optimization. See
|
||||||
|
// burst_uncompress_address_counter below.
|
||||||
|
// d) response byte_cnt field. The response byte_cnt field contains a
|
||||||
|
// decrementing sequence, such that each beat of the response contains the
|
||||||
|
// count of bytes to follow. In the case of sub-bursts in a single packet,
|
||||||
|
// the byte_cnt field may decrement down to num_symbols, then back up to
|
||||||
|
// some value, multiple times in the packet.
|
||||||
|
|
||||||
|
reg burst_uncompress_busy;
|
||||||
|
reg [BYTE_CNT_W:0] burst_uncompress_byte_counter;
|
||||||
|
wire [BYTE_CNT_W-1:0] burst_uncompress_byte_counter_lint;
|
||||||
|
wire first_packet_beat;
|
||||||
|
wire last_packet_beat;
|
||||||
|
|
||||||
|
assign first_packet_beat = sink_valid & ~burst_uncompress_busy;
|
||||||
|
assign burst_uncompress_byte_counter_lint = burst_uncompress_byte_counter[BYTE_CNT_W-1:0];
|
||||||
|
|
||||||
|
// First cycle: burst_uncompress_byte_counter isn't ready yet, mux the input to
|
||||||
|
// the output.
|
||||||
|
assign source_byte_cnt =
|
||||||
|
first_packet_beat ? sink_byte_cnt : burst_uncompress_byte_counter_lint;
|
||||||
|
assign source_valid = sink_valid;
|
||||||
|
|
||||||
|
// Last packet beat is set throughout receipt of an uncompressed read burst
|
||||||
|
// from the response FIFO - this forces all the burst uncompression machinery
|
||||||
|
// idle.
|
||||||
|
assign last_packet_beat = ~sink_is_compressed |
|
||||||
|
(
|
||||||
|
burst_uncompress_busy ?
|
||||||
|
(sink_valid & (burst_uncompress_byte_counter_lint == num_symbols)) :
|
||||||
|
sink_valid & (sink_byte_cnt == num_symbols)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
burst_uncompress_busy <= '0;
|
||||||
|
burst_uncompress_byte_counter <= '0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (source_valid & source_ready & sink_valid) begin
|
||||||
|
// No matter what the current state, last_packet_beat leads to
|
||||||
|
// idle.
|
||||||
|
if (last_packet_beat) begin
|
||||||
|
burst_uncompress_busy <= '0;
|
||||||
|
burst_uncompress_byte_counter <= '0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (burst_uncompress_busy) begin
|
||||||
|
burst_uncompress_byte_counter <= (burst_uncompress_byte_counter > 0) ?
|
||||||
|
(burst_uncompress_byte_counter_lint - num_symbols) :
|
||||||
|
(sink_byte_cnt - num_symbols);
|
||||||
|
end
|
||||||
|
else begin // not busy, at least one more beat to go
|
||||||
|
burst_uncompress_byte_counter <= sink_byte_cnt - num_symbols;
|
||||||
|
// To do: should busy go true for numsymbols-size compressed
|
||||||
|
// bursts?
|
||||||
|
burst_uncompress_busy <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [ADDR_W - 1 : 0 ] burst_uncompress_address_base;
|
||||||
|
reg [ADDR_W - 1 : 0] burst_uncompress_address_offset;
|
||||||
|
|
||||||
|
wire [63:0] decoded_burstsize_wire;
|
||||||
|
wire [ADDR_W-1:0] decoded_burstsize;
|
||||||
|
|
||||||
|
|
||||||
|
localparam ADD_BURSTWRAP_W = (ADDR_W > BURSTWRAP_W) ? ADDR_W : BURSTWRAP_W;
|
||||||
|
wire [ADD_BURSTWRAP_W-1:0] addr_width_burstwrap;
|
||||||
|
// The input burstwrap value can be used as a mask against address values,
|
||||||
|
// but with one caveat: the address width may be (probably is) wider than
|
||||||
|
// the burstwrap width. The spec says: extend the msb of the burstwrap
|
||||||
|
// value out over the entire address width (but only if the address width
|
||||||
|
// actually is wider than the burstwrap width; otherwise it's a 0-width or
|
||||||
|
// negative range and concatenation multiplier).
|
||||||
|
generate
|
||||||
|
if (ADDR_W > BURSTWRAP_W) begin : addr_sign_extend
|
||||||
|
// Sign-extend, just wires:
|
||||||
|
assign addr_width_burstwrap[ADDR_W - 1 : BURSTWRAP_W] =
|
||||||
|
{(ADDR_W - BURSTWRAP_W) {sink_burstwrap[BURSTWRAP_W - 1]}};
|
||||||
|
assign addr_width_burstwrap[BURSTWRAP_W-1:0] = sink_burstwrap [BURSTWRAP_W-1:0];
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
assign addr_width_burstwrap[BURSTWRAP_W-1 : 0] = sink_burstwrap;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
burst_uncompress_address_base <= '0;
|
||||||
|
end
|
||||||
|
else if (first_packet_beat & source_ready) begin
|
||||||
|
burst_uncompress_address_base <= sink_addr & ~addr_width_burstwrap[ADDR_W-1:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign decoded_burstsize_wire = bytes_in_transfer(sink_burstsize); //expand it to 64 bits
|
||||||
|
assign decoded_burstsize = decoded_burstsize_wire[ADDR_W-1:0]; //then take the width that is needed
|
||||||
|
|
||||||
|
wire [ADDR_W : 0] p1_burst_uncompress_address_offset =
|
||||||
|
(
|
||||||
|
(first_packet_beat ?
|
||||||
|
sink_addr :
|
||||||
|
burst_uncompress_address_offset) + decoded_burstsize
|
||||||
|
) &
|
||||||
|
addr_width_burstwrap[ADDR_W-1:0];
|
||||||
|
wire [ADDR_W-1:0] p1_burst_uncompress_address_offset_lint = p1_burst_uncompress_address_offset [ADDR_W-1:0];
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
burst_uncompress_address_offset <= '0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (source_ready & source_valid) begin
|
||||||
|
burst_uncompress_address_offset <= p1_burst_uncompress_address_offset_lint;
|
||||||
|
// if (first_packet_beat) begin
|
||||||
|
// burst_uncompress_address_offset <=
|
||||||
|
// (sink_addr + num_symbols) & addr_width_burstwrap;
|
||||||
|
// end
|
||||||
|
// else begin
|
||||||
|
// burst_uncompress_address_offset <=
|
||||||
|
// (burst_uncompress_address_offset + num_symbols) & addr_width_burstwrap;
|
||||||
|
// end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// On the first packet beat, send the input address out unchanged,
|
||||||
|
// while values are computed/registered for 2nd and subsequent beats.
|
||||||
|
assign source_addr = first_packet_beat ? sink_addr :
|
||||||
|
burst_uncompress_address_base | burst_uncompress_address_offset;
|
||||||
|
assign source_burstwrap = sink_burstwrap;
|
||||||
|
assign source_burstsize = sink_burstsize;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// A single (compressed) read burst will have sop/eop in the same beat.
|
||||||
|
// A sequence of read sub-bursts emitted by a burst adapter in response to a
|
||||||
|
// single read burst will have sop on the first sub-burst, eop on the last.
|
||||||
|
// Assert eop only upon (sink_endofpacket & last_packet_beat) to preserve
|
||||||
|
// packet conservation.
|
||||||
|
assign source_startofpacket = sink_startofpacket & ~burst_uncompress_busy;
|
||||||
|
assign source_endofpacket = sink_endofpacket & last_packet_beat;
|
||||||
|
assign sink_ready = source_valid & source_ready & last_packet_beat;
|
||||||
|
|
||||||
|
// This is correct for the slave agent usage, but won't always be true in the
|
||||||
|
// width adapter. To do: add an "please uncompress" input, and use it to
|
||||||
|
// pass-through or modify, and set source_is_compressed accordingly.
|
||||||
|
assign source_is_compressed = 1'b0;
|
||||||
|
endmodule
|
||||||
|
|
303
ip/altera/ddr3/altera_merlin_master_agent.sv
Normal file
303
ip/altera/ddr3/altera_merlin_master_agent.sv
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_master_agent/altera_merlin_master_agent.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Merlin Master Agent
|
||||||
|
//
|
||||||
|
// Converts Avalon-MM transactions into
|
||||||
|
// Merlin network packets.
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_merlin_master_agent
|
||||||
|
#(
|
||||||
|
// -------------------
|
||||||
|
// Packet Format Parameters
|
||||||
|
// -------------------
|
||||||
|
parameter
|
||||||
|
PKT_QOS_H = 109,
|
||||||
|
PKT_QOS_L = 106,
|
||||||
|
PKT_DATA_SIDEBAND_H = 105,
|
||||||
|
PKT_DATA_SIDEBAND_L = 98,
|
||||||
|
PKT_ADDR_SIDEBAND_H = 97,
|
||||||
|
PKT_ADDR_SIDEBAND_L = 93,
|
||||||
|
PKT_CACHE_H = 92,
|
||||||
|
PKT_CACHE_L = 89,
|
||||||
|
PKT_THREAD_ID_H = 88,
|
||||||
|
PKT_THREAD_ID_L = 87,
|
||||||
|
PKT_BEGIN_BURST = 81,
|
||||||
|
PKT_PROTECTION_H = 80,
|
||||||
|
PKT_PROTECTION_L = 80,
|
||||||
|
PKT_BURSTWRAP_H = 79,
|
||||||
|
PKT_BURSTWRAP_L = 77,
|
||||||
|
PKT_BYTE_CNT_H = 76,
|
||||||
|
PKT_BYTE_CNT_L = 74,
|
||||||
|
PKT_ADDR_H = 73,
|
||||||
|
PKT_ADDR_L = 42,
|
||||||
|
PKT_BURST_SIZE_H = 86,
|
||||||
|
PKT_BURST_SIZE_L = 84,
|
||||||
|
PKT_BURST_TYPE_H = 94,
|
||||||
|
PKT_BURST_TYPE_L = 93,
|
||||||
|
PKT_TRANS_EXCLUSIVE = 83,
|
||||||
|
PKT_TRANS_LOCK = 82,
|
||||||
|
PKT_TRANS_COMPRESSED_READ = 41,
|
||||||
|
PKT_TRANS_POSTED = 40,
|
||||||
|
PKT_TRANS_WRITE = 39,
|
||||||
|
PKT_TRANS_READ = 38,
|
||||||
|
PKT_DATA_H = 37,
|
||||||
|
PKT_DATA_L = 6,
|
||||||
|
PKT_BYTEEN_H = 5,
|
||||||
|
PKT_BYTEEN_L = 2,
|
||||||
|
PKT_SRC_ID_H = 1,
|
||||||
|
PKT_SRC_ID_L = 1,
|
||||||
|
PKT_DEST_ID_H = 0,
|
||||||
|
PKT_DEST_ID_L = 0,
|
||||||
|
PKT_RESPONSE_STATUS_L = 110,
|
||||||
|
PKT_RESPONSE_STATUS_H = 111,
|
||||||
|
PKT_ORI_BURST_SIZE_L = 112,
|
||||||
|
PKT_ORI_BURST_SIZE_H = 114,
|
||||||
|
ST_DATA_W = 115,
|
||||||
|
ST_CHANNEL_W = 1,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Agent Parameters
|
||||||
|
// -------------------
|
||||||
|
AV_BURSTCOUNT_W = 3,
|
||||||
|
ID = 1,
|
||||||
|
SUPPRESS_0_BYTEEN_RSP = 1,
|
||||||
|
BURSTWRAP_VALUE = 4,
|
||||||
|
CACHE_VALUE = 0,
|
||||||
|
SECURE_ACCESS_BIT = 1,
|
||||||
|
USE_READRESPONSE = 0,
|
||||||
|
USE_WRITERESPONSE = 0,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Derived Parameters
|
||||||
|
// -------------------
|
||||||
|
PKT_BURSTWRAP_W = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1,
|
||||||
|
PKT_BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1,
|
||||||
|
PKT_PROTECTION_W = PKT_PROTECTION_H - PKT_PROTECTION_L + 1,
|
||||||
|
PKT_ADDR_W = PKT_ADDR_H - PKT_ADDR_L + 1,
|
||||||
|
PKT_DATA_W = PKT_DATA_H - PKT_DATA_L + 1,
|
||||||
|
PKT_BYTEEN_W = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
|
||||||
|
PKT_SRC_ID_W = PKT_SRC_ID_H - PKT_SRC_ID_L + 1,
|
||||||
|
PKT_DEST_ID_W = PKT_DEST_ID_H - PKT_DEST_ID_L + 1,
|
||||||
|
PKT_BURST_SIZE_W = PKT_BURST_SIZE_H - PKT_BURST_SIZE_L + 1
|
||||||
|
) (
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Avalon-MM Anti-Master
|
||||||
|
// -------------------
|
||||||
|
input [PKT_ADDR_W-1 : 0] av_address,
|
||||||
|
input av_write,
|
||||||
|
input av_read,
|
||||||
|
input [PKT_DATA_W-1 : 0] av_writedata,
|
||||||
|
output reg [PKT_DATA_W-1 : 0] av_readdata,
|
||||||
|
output reg av_waitrequest,
|
||||||
|
output reg av_readdatavalid,
|
||||||
|
input [PKT_BYTEEN_W-1 : 0] av_byteenable,
|
||||||
|
input [AV_BURSTCOUNT_W-1 : 0] av_burstcount,
|
||||||
|
input av_debugaccess,
|
||||||
|
input av_lock,
|
||||||
|
output reg [1 : 0] av_response,
|
||||||
|
output reg av_writeresponsevalid,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Source
|
||||||
|
// -------------------
|
||||||
|
output reg cp_valid,
|
||||||
|
output reg [ST_DATA_W-1 : 0] cp_data,
|
||||||
|
output wire cp_startofpacket,
|
||||||
|
output wire cp_endofpacket,
|
||||||
|
input cp_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Response Sink
|
||||||
|
// -------------------
|
||||||
|
input rp_valid,
|
||||||
|
input [ST_DATA_W-1 : 0] rp_data,
|
||||||
|
input [ST_CHANNEL_W-1 : 0] rp_channel,
|
||||||
|
input rp_startofpacket,
|
||||||
|
input rp_endofpacket,
|
||||||
|
output reg rp_ready
|
||||||
|
);
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Utility Functions
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
function integer clogb2;
|
||||||
|
input [31 : 0] value;
|
||||||
|
begin
|
||||||
|
for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1)
|
||||||
|
value = value >> 1;
|
||||||
|
clogb2 = clogb2 - 1;
|
||||||
|
end
|
||||||
|
endfunction // clogb2
|
||||||
|
|
||||||
|
localparam MAX_BURST = 1 << (AV_BURSTCOUNT_W - 1);
|
||||||
|
localparam NUMSYMBOLS = PKT_BYTEEN_W;
|
||||||
|
localparam BURSTING = (MAX_BURST > NUMSYMBOLS);
|
||||||
|
localparam BITS_TO_ZERO = clogb2(NUMSYMBOLS);
|
||||||
|
localparam BURST_SIZE = clogb2(NUMSYMBOLS);
|
||||||
|
|
||||||
|
typedef enum bit [1 : 0]
|
||||||
|
{
|
||||||
|
FIXED = 2'b00,
|
||||||
|
INCR = 2'b01,
|
||||||
|
WRAP = 2'b10,
|
||||||
|
OTHER_WRAP = 2'b11
|
||||||
|
} MerlinBurstType;
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Potential optimization: compare in words to save bits?
|
||||||
|
// --------------------------------------
|
||||||
|
wire is_burst;
|
||||||
|
assign is_burst = (BURSTING) & (av_burstcount > NUMSYMBOLS);
|
||||||
|
|
||||||
|
wire [31 : 0] burstwrap_value_int = BURSTWRAP_VALUE;
|
||||||
|
wire [31 : 0] id_int = ID;
|
||||||
|
wire [PKT_BURST_SIZE_W-1 : 0] burstsize_sig = BURST_SIZE[PKT_BURST_SIZE_W-1 : 0];
|
||||||
|
wire [1 : 0] bursttype_value = burstwrap_value_int[PKT_BURSTWRAP_W-1] ? INCR : WRAP;
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Address alignment
|
||||||
|
//
|
||||||
|
// The packet format requires that addresses be aligned to
|
||||||
|
// the transaction size.
|
||||||
|
// --------------------------------------
|
||||||
|
wire [PKT_ADDR_W-1 : 0] av_address_aligned;
|
||||||
|
generate
|
||||||
|
if (NUMSYMBOLS > 1) begin
|
||||||
|
assign av_address_aligned =
|
||||||
|
{av_address[PKT_ADDR_W-1 : BITS_TO_ZERO], {BITS_TO_ZERO {1'b0}}};
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
assign av_address_aligned = av_address;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Command & Response Construction
|
||||||
|
// --------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
cp_data = '0;
|
||||||
|
|
||||||
|
cp_data[PKT_PROTECTION_L] = av_debugaccess;
|
||||||
|
cp_data[PKT_PROTECTION_L+1] = SECURE_ACCESS_BIT[0]; // secure cache bit
|
||||||
|
cp_data[PKT_PROTECTION_L+2] = 1'b0; // instruction/data cache bit
|
||||||
|
cp_data[PKT_BURSTWRAP_H : PKT_BURSTWRAP_L] = burstwrap_value_int[PKT_BURSTWRAP_W-1 : 0];
|
||||||
|
cp_data[PKT_BYTE_CNT_H : PKT_BYTE_CNT_L] = av_burstcount;
|
||||||
|
cp_data[PKT_ADDR_H : PKT_ADDR_L] = av_address_aligned;
|
||||||
|
cp_data[PKT_TRANS_EXCLUSIVE] = 1'b0;
|
||||||
|
cp_data[PKT_TRANS_LOCK] = av_lock;
|
||||||
|
cp_data[PKT_TRANS_COMPRESSED_READ] = av_read & is_burst;
|
||||||
|
cp_data[PKT_TRANS_READ] = av_read;
|
||||||
|
cp_data[PKT_TRANS_WRITE] = av_write;
|
||||||
|
cp_data[PKT_TRANS_POSTED] = av_write & !USE_WRITERESPONSE;
|
||||||
|
cp_data[PKT_DATA_H : PKT_DATA_L] = av_writedata;
|
||||||
|
cp_data[PKT_BYTEEN_H : PKT_BYTEEN_L] = av_byteenable;
|
||||||
|
cp_data[PKT_BURST_SIZE_H : PKT_BURST_SIZE_L] = burstsize_sig;
|
||||||
|
cp_data[PKT_ORI_BURST_SIZE_H : PKT_ORI_BURST_SIZE_L] = burstsize_sig;
|
||||||
|
cp_data[PKT_BURST_TYPE_H : PKT_BURST_TYPE_L] = bursttype_value;
|
||||||
|
cp_data[PKT_SRC_ID_H : PKT_SRC_ID_L] = id_int[PKT_SRC_ID_W-1 : 0];
|
||||||
|
cp_data[PKT_THREAD_ID_H : PKT_THREAD_ID_L] = '0;
|
||||||
|
cp_data[PKT_CACHE_H : PKT_CACHE_L] = CACHE_VALUE[3 : 0];
|
||||||
|
cp_data[PKT_QOS_H : PKT_QOS_L] = '0;
|
||||||
|
cp_data[PKT_ADDR_SIDEBAND_H : PKT_ADDR_SIDEBAND_L] = '0;
|
||||||
|
cp_data[PKT_DATA_SIDEBAND_H : PKT_DATA_SIDEBAND_L] = '0;
|
||||||
|
|
||||||
|
av_readdata = rp_data[PKT_DATA_H : PKT_DATA_L];
|
||||||
|
if (USE_WRITERESPONSE || USE_READRESPONSE)
|
||||||
|
av_response = rp_data[PKT_RESPONSE_STATUS_H : PKT_RESPONSE_STATUS_L];
|
||||||
|
else
|
||||||
|
av_response = '0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Command Control
|
||||||
|
// --------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
cp_valid = 0;
|
||||||
|
|
||||||
|
if (av_write || av_read)
|
||||||
|
cp_valid = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
generate if (BURSTING) begin
|
||||||
|
reg sop_enable;
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
sop_enable <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (cp_valid && cp_ready) begin
|
||||||
|
sop_enable <= 1'b0;
|
||||||
|
if (cp_endofpacket)
|
||||||
|
sop_enable <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign cp_startofpacket = sop_enable;
|
||||||
|
assign cp_endofpacket = (av_read) | (av_burstcount == NUMSYMBOLS);
|
||||||
|
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
|
||||||
|
assign cp_startofpacket = 1'b1;
|
||||||
|
assign cp_endofpacket = 1'b1;
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Backpressure & Readdatavalid
|
||||||
|
// --------------------------------------
|
||||||
|
reg hold_waitrequest;
|
||||||
|
|
||||||
|
always @ (posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
hold_waitrequest <= 1'b1;
|
||||||
|
else
|
||||||
|
hold_waitrequest <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
rp_ready = 1;
|
||||||
|
av_readdatavalid = 0;
|
||||||
|
av_writeresponsevalid = 0;
|
||||||
|
av_waitrequest = hold_waitrequest | !cp_ready;
|
||||||
|
|
||||||
|
if (USE_WRITERESPONSE && (rp_data[PKT_TRANS_WRITE] == 1))
|
||||||
|
av_writeresponsevalid = rp_valid;
|
||||||
|
else
|
||||||
|
av_readdatavalid = rp_valid;
|
||||||
|
|
||||||
|
if (SUPPRESS_0_BYTEEN_RSP) begin
|
||||||
|
if (rp_data[PKT_BYTEEN_H : PKT_BYTEEN_L] == 0)
|
||||||
|
av_readdatavalid = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
556
ip/altera/ddr3/altera_merlin_master_translator.sv
Normal file
556
ip/altera/ddr3/altera_merlin_master_translator.sv
Normal file
@ -0,0 +1,556 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_master_translator/altera_merlin_master_translator.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Merlin Master Translator
|
||||||
|
//
|
||||||
|
// Converts an Avalon-MM master interface into an
|
||||||
|
// Avalon-MM "universal" master interface.
|
||||||
|
//
|
||||||
|
// The universal interface is defined as the superset of ports
|
||||||
|
// and parameters that can represent any legal Avalon
|
||||||
|
// interface.
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_merlin_master_translator #(
|
||||||
|
parameter
|
||||||
|
// widths
|
||||||
|
AV_ADDRESS_W = 32,
|
||||||
|
AV_DATA_W = 32,
|
||||||
|
AV_BURSTCOUNT_W = 4,
|
||||||
|
AV_BYTEENABLE_W = 4,
|
||||||
|
|
||||||
|
UAV_ADDRESS_W = 38,
|
||||||
|
UAV_BURSTCOUNT_W = 10,
|
||||||
|
|
||||||
|
// optional ports
|
||||||
|
USE_BURSTCOUNT = 1,
|
||||||
|
USE_BEGINBURSTTRANSFER = 0,
|
||||||
|
USE_BEGINTRANSFER = 0,
|
||||||
|
USE_CHIPSELECT = 0,
|
||||||
|
USE_READ = 1,
|
||||||
|
USE_READDATAVALID = 1,
|
||||||
|
USE_WRITE = 1,
|
||||||
|
USE_WAITREQUEST = 1,
|
||||||
|
USE_WRITERESPONSE = 0,
|
||||||
|
USE_READRESPONSE = 0,
|
||||||
|
|
||||||
|
AV_REGISTERINCOMINGSIGNALS = 0,
|
||||||
|
AV_SYMBOLS_PER_WORD = 4,
|
||||||
|
AV_ADDRESS_SYMBOLS = 0,
|
||||||
|
// must be enabled for a bursting master
|
||||||
|
AV_CONSTANT_BURST_BEHAVIOR = 1,
|
||||||
|
UAV_CONSTANT_BURST_BEHAVIOR = 0,
|
||||||
|
AV_BURSTCOUNT_SYMBOLS = 0,
|
||||||
|
AV_LINEWRAPBURSTS = 0
|
||||||
|
)(
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
|
||||||
|
// Universal Avalon Master
|
||||||
|
output reg uav_write,
|
||||||
|
output reg uav_read,
|
||||||
|
output reg [UAV_ADDRESS_W -1 : 0] uav_address,
|
||||||
|
output reg [UAV_BURSTCOUNT_W -1 : 0] uav_burstcount,
|
||||||
|
output wire [AV_BYTEENABLE_W -1 : 0] uav_byteenable,
|
||||||
|
output wire [AV_DATA_W -1 : 0] uav_writedata,
|
||||||
|
output wire uav_lock,
|
||||||
|
output wire uav_debugaccess,
|
||||||
|
output wire uav_clken,
|
||||||
|
|
||||||
|
input wire [AV_DATA_W -1 : 0] uav_readdata,
|
||||||
|
input wire uav_readdatavalid,
|
||||||
|
input wire uav_waitrequest,
|
||||||
|
input wire [1 : 0] uav_response,
|
||||||
|
input wire uav_writeresponsevalid,
|
||||||
|
|
||||||
|
// Avalon-MM Anti-master (slave)
|
||||||
|
input reg av_write,
|
||||||
|
input reg av_read,
|
||||||
|
input wire [AV_ADDRESS_W -1 : 0] av_address,
|
||||||
|
input wire [AV_BYTEENABLE_W -1 : 0] av_byteenable,
|
||||||
|
input wire [AV_BURSTCOUNT_W -1 : 0] av_burstcount,
|
||||||
|
input wire [AV_DATA_W -1 : 0] av_writedata,
|
||||||
|
input wire av_begintransfer,
|
||||||
|
input wire av_beginbursttransfer,
|
||||||
|
input wire av_lock,
|
||||||
|
input wire av_chipselect,
|
||||||
|
input wire av_debugaccess,
|
||||||
|
input wire av_clken,
|
||||||
|
|
||||||
|
output wire [AV_DATA_W -1 : 0] av_readdata,
|
||||||
|
output wire av_readdatavalid,
|
||||||
|
output reg av_waitrequest,
|
||||||
|
output reg [1 : 0] av_response,
|
||||||
|
output reg av_writeresponsevalid
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam BITS_PER_WORD = clog2(AV_SYMBOLS_PER_WORD);
|
||||||
|
localparam AV_MAX_SYMBOL_BURST = flog2(pow2(AV_BURSTCOUNT_W - 1) * (AV_BURSTCOUNT_SYMBOLS ? 1 : AV_SYMBOLS_PER_WORD));
|
||||||
|
localparam AV_MAX_SYMBOL_BURST_MINUS_ONE = AV_MAX_SYMBOL_BURST ? AV_MAX_SYMBOL_BURST - 1 : 0;
|
||||||
|
localparam UAV_BURSTCOUNT_H_OR_31 = (UAV_BURSTCOUNT_W > 32) ? 31 : UAV_BURSTCOUNT_W - 1;
|
||||||
|
localparam UAV_ADDRESS_H_OR_31 = (UAV_ADDRESS_W > 32) ? 31 : UAV_ADDRESS_W - 1;
|
||||||
|
|
||||||
|
localparam BITS_PER_WORD_BURSTCOUNT = (UAV_BURSTCOUNT_W == 1) ? 0 : BITS_PER_WORD;
|
||||||
|
localparam BITS_PER_WORD_ADDRESS = (UAV_ADDRESS_W == 1) ? 0 : BITS_PER_WORD;
|
||||||
|
|
||||||
|
localparam ADDRESS_LOW = AV_ADDRESS_SYMBOLS ? 0 : BITS_PER_WORD_ADDRESS;
|
||||||
|
localparam BURSTCOUNT_LOW = AV_BURSTCOUNT_SYMBOLS ? 0 : BITS_PER_WORD_BURSTCOUNT;
|
||||||
|
|
||||||
|
localparam ADDRESS_HIGH = (UAV_ADDRESS_W > AV_ADDRESS_W + ADDRESS_LOW) ? AV_ADDRESS_W : (UAV_ADDRESS_W - ADDRESS_LOW);
|
||||||
|
localparam BURSTCOUNT_HIGH = (UAV_BURSTCOUNT_W > AV_BURSTCOUNT_W + BURSTCOUNT_LOW) ? AV_BURSTCOUNT_W : (UAV_BURSTCOUNT_W - BURSTCOUNT_LOW);
|
||||||
|
|
||||||
|
function integer flog2;
|
||||||
|
input [31:0] depth;
|
||||||
|
integer i;
|
||||||
|
begin
|
||||||
|
i = depth;
|
||||||
|
if ( i <= 0 ) flog2 = 0;
|
||||||
|
else begin
|
||||||
|
for (flog2 = -1; i > 0; flog2 = flog2 + 1)
|
||||||
|
i = i >> 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction // flog2
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Calculates the ceil(log2()) of the input val.
|
||||||
|
//
|
||||||
|
// Limited to a positive 32-bit input value.
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
function integer clog2;
|
||||||
|
input[31:0] val;
|
||||||
|
reg[31:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
clog2 = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
clog2 = clog2 + 1;
|
||||||
|
i = i[30:0] << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function integer pow2;
|
||||||
|
input [31:0] toShift;
|
||||||
|
begin
|
||||||
|
pow2 = 1;
|
||||||
|
pow2 = pow2 << toShift;
|
||||||
|
end
|
||||||
|
endfunction // pow2
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Assign some constants to appropriately-sized signals to
|
||||||
|
// avoid synthesis warnings. This also helps some simulators
|
||||||
|
// with their inferred sensitivity lists.
|
||||||
|
//
|
||||||
|
// The symbols per word calculation here rounds non-power of two
|
||||||
|
// symbols to the next highest power of two, which is what we want
|
||||||
|
// when calculating the decrementing byte count.
|
||||||
|
// -------------------------------------------------
|
||||||
|
wire [31 : 0] symbols_per_word_int = 2**(clog2(AV_SYMBOLS_PER_WORD[UAV_BURSTCOUNT_H_OR_31 : 0]));
|
||||||
|
wire [UAV_BURSTCOUNT_H_OR_31 : 0] symbols_per_word = symbols_per_word_int[UAV_BURSTCOUNT_H_OR_31 : 0];
|
||||||
|
|
||||||
|
reg internal_beginbursttransfer;
|
||||||
|
reg internal_begintransfer;
|
||||||
|
reg [UAV_ADDRESS_W -1 : 0] uav_address_pre;
|
||||||
|
reg [UAV_BURSTCOUNT_W -1 : 0] uav_burstcount_pre;
|
||||||
|
|
||||||
|
reg uav_read_pre;
|
||||||
|
reg uav_write_pre;
|
||||||
|
reg read_accepted;
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Pass through signals that we don't touch
|
||||||
|
// -------------------------------------------------
|
||||||
|
assign uav_writedata = av_writedata;
|
||||||
|
assign uav_byteenable = av_byteenable;
|
||||||
|
assign uav_lock = av_lock;
|
||||||
|
assign uav_debugaccess = av_debugaccess;
|
||||||
|
assign uav_clken = av_clken;
|
||||||
|
|
||||||
|
assign av_readdata = uav_readdata;
|
||||||
|
assign av_readdatavalid = uav_readdatavalid;
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Response signals
|
||||||
|
// -------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
if (!USE_READRESPONSE && !USE_WRITERESPONSE)
|
||||||
|
av_response = '0;
|
||||||
|
else
|
||||||
|
av_response = uav_response;
|
||||||
|
|
||||||
|
if (USE_WRITERESPONSE) begin
|
||||||
|
av_writeresponsevalid = uav_writeresponsevalid;
|
||||||
|
end else begin
|
||||||
|
av_writeresponsevalid = '0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Convert byte and word addresses into byte addresses
|
||||||
|
// -------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
uav_address_pre = {UAV_ADDRESS_W{1'b0}};
|
||||||
|
|
||||||
|
if (AV_ADDRESS_SYMBOLS)
|
||||||
|
uav_address_pre[(ADDRESS_HIGH ? ADDRESS_HIGH - 1 : 0) : 0] = av_address[(ADDRESS_HIGH ? ADDRESS_HIGH - 1 : 0) : 0];
|
||||||
|
else begin
|
||||||
|
uav_address_pre[ADDRESS_LOW + ADDRESS_HIGH - 1 : ADDRESS_LOW] = av_address[(ADDRESS_HIGH ? ADDRESS_HIGH - 1 : 0) : 0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Convert burstcount into symbol units
|
||||||
|
// -------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
uav_burstcount_pre = symbols_per_word; // default to a single transfer
|
||||||
|
|
||||||
|
if (USE_BURSTCOUNT) begin
|
||||||
|
uav_burstcount_pre = {UAV_BURSTCOUNT_W{1'b0}};
|
||||||
|
if (AV_BURSTCOUNT_SYMBOLS)
|
||||||
|
uav_burstcount_pre[(BURSTCOUNT_HIGH ? BURSTCOUNT_HIGH - 1 : 0) :0] = av_burstcount[(BURSTCOUNT_HIGH ? BURSTCOUNT_HIGH - 1 : 0) : 0];
|
||||||
|
else begin
|
||||||
|
uav_burstcount_pre[UAV_BURSTCOUNT_W - 1 : BURSTCOUNT_LOW] = av_burstcount[(BURSTCOUNT_HIGH ? BURSTCOUNT_HIGH - 1 : 0) : 0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// This is where we perform the per-transfer address and burstcount
|
||||||
|
// calculations that are required by downstream modules.
|
||||||
|
// -------------------------------------------------
|
||||||
|
reg [UAV_ADDRESS_W -1 : 0] address_register;
|
||||||
|
wire [UAV_BURSTCOUNT_W -1 : 0] burstcount_register;
|
||||||
|
reg [UAV_BURSTCOUNT_W : 0] burstcount_register_lint;
|
||||||
|
|
||||||
|
assign burstcount_register = burstcount_register_lint[UAV_BURSTCOUNT_W -1 : 0];
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
uav_address = uav_address_pre;
|
||||||
|
uav_burstcount = uav_burstcount_pre;
|
||||||
|
|
||||||
|
if (AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~internal_beginbursttransfer) begin
|
||||||
|
uav_address = address_register;
|
||||||
|
uav_burstcount = burstcount_register;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg first_burst_stalled;
|
||||||
|
reg burst_stalled;
|
||||||
|
|
||||||
|
wire [UAV_ADDRESS_W -1 : 0] combi_burst_addr_reg;
|
||||||
|
wire [UAV_ADDRESS_W -1 : 0] combi_addr_reg;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (AV_LINEWRAPBURSTS && AV_MAX_SYMBOL_BURST != 0) begin
|
||||||
|
if (AV_MAX_SYMBOL_BURST > UAV_ADDRESS_W - 1) begin
|
||||||
|
assign combi_burst_addr_reg = { uav_address_pre[UAV_ADDRESS_W-1:0] + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_W-1:0] };
|
||||||
|
assign combi_addr_reg = { address_register[UAV_ADDRESS_W-1:0] + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_W-1:0] };
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
assign combi_burst_addr_reg = { uav_address_pre[UAV_ADDRESS_W - 1 : AV_MAX_SYMBOL_BURST], uav_address_pre[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] + AV_SYMBOLS_PER_WORD[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] };
|
||||||
|
assign combi_addr_reg = { address_register[UAV_ADDRESS_W - 1 : AV_MAX_SYMBOL_BURST], address_register[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] + AV_SYMBOLS_PER_WORD[AV_MAX_SYMBOL_BURST_MINUS_ONE:0] };
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
assign combi_burst_addr_reg = uav_address_pre + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_H_OR_31:0];
|
||||||
|
assign combi_addr_reg = address_register + AV_SYMBOLS_PER_WORD[UAV_ADDRESS_H_OR_31:0];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
address_register <= '0;
|
||||||
|
burstcount_register_lint <= '0;
|
||||||
|
end else begin
|
||||||
|
address_register <= address_register;
|
||||||
|
burstcount_register_lint <= burstcount_register_lint;
|
||||||
|
|
||||||
|
if (internal_beginbursttransfer || first_burst_stalled) begin
|
||||||
|
if (av_waitrequest) begin
|
||||||
|
address_register <= uav_address_pre;
|
||||||
|
burstcount_register_lint[UAV_BURSTCOUNT_W - 1 : 0] <= uav_burstcount_pre;
|
||||||
|
end else begin
|
||||||
|
address_register <= combi_burst_addr_reg;
|
||||||
|
burstcount_register_lint <= uav_burstcount_pre - symbols_per_word;
|
||||||
|
end
|
||||||
|
end else if (internal_begintransfer || burst_stalled) begin
|
||||||
|
if (~av_waitrequest) begin
|
||||||
|
address_register <= combi_addr_reg;
|
||||||
|
burstcount_register_lint <= burstcount_register - symbols_per_word;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
first_burst_stalled <= 1'b0;
|
||||||
|
burst_stalled <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (internal_beginbursttransfer || first_burst_stalled) begin
|
||||||
|
if (av_waitrequest) begin
|
||||||
|
first_burst_stalled <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
first_burst_stalled <= 1'b0;
|
||||||
|
end
|
||||||
|
end else if (internal_begintransfer || burst_stalled) begin
|
||||||
|
if (~av_waitrequest) begin
|
||||||
|
burst_stalled <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
burst_stalled <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Waitrequest translation
|
||||||
|
// -------------------------------------------------
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
read_accepted <= 1'b0;
|
||||||
|
else begin
|
||||||
|
read_accepted <= read_accepted;
|
||||||
|
if (read_accepted == 0)
|
||||||
|
read_accepted <= av_waitrequest ? uav_read_pre & ~uav_waitrequest : 1'b0;
|
||||||
|
else if (read_accepted == 1 && uav_readdatavalid == 1) // reset acceptance only when rdv arrives
|
||||||
|
read_accepted <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
reg write_accepted = 0;
|
||||||
|
generate if (AV_REGISTERINCOMINGSIGNALS) begin
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
write_accepted <= 1'b0;
|
||||||
|
else begin
|
||||||
|
write_accepted <=
|
||||||
|
~av_waitrequest ? 1'b0 :
|
||||||
|
uav_write & ~uav_waitrequest? 1'b1 :
|
||||||
|
write_accepted;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end endgenerate
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
av_waitrequest = uav_waitrequest;
|
||||||
|
|
||||||
|
if (USE_READDATAVALID == 0) begin
|
||||||
|
av_waitrequest = uav_read_pre ? ~uav_readdatavalid : uav_waitrequest;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (AV_REGISTERINCOMINGSIGNALS) begin
|
||||||
|
av_waitrequest =
|
||||||
|
uav_read_pre ? ~uav_readdatavalid :
|
||||||
|
uav_write_pre ? (internal_begintransfer | uav_waitrequest) & ~write_accepted :
|
||||||
|
1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (USE_WAITREQUEST == 0) begin
|
||||||
|
av_waitrequest = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Determine the output read and write signals from
|
||||||
|
// the read/write/chipselect input signals.
|
||||||
|
// -------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
uav_write = 1'b0;
|
||||||
|
uav_write_pre = 1'b0;
|
||||||
|
uav_read = 1'b0;
|
||||||
|
uav_read_pre = 1'b0;
|
||||||
|
|
||||||
|
if (!USE_CHIPSELECT) begin
|
||||||
|
if (USE_READ) begin
|
||||||
|
uav_read_pre = av_read;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (USE_WRITE) begin
|
||||||
|
uav_write_pre = av_write;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
if (!USE_WRITE && USE_READ) begin
|
||||||
|
uav_write_pre = av_chipselect & ~av_read;
|
||||||
|
uav_read_pre = av_read;
|
||||||
|
end else if (!USE_READ && USE_WRITE) begin
|
||||||
|
uav_write_pre = av_write;
|
||||||
|
uav_read_pre = av_chipselect & ~av_write;
|
||||||
|
end else if (USE_READ && USE_WRITE) begin
|
||||||
|
uav_write_pre = av_write;
|
||||||
|
uav_read_pre = av_read;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (USE_READDATAVALID == 0)
|
||||||
|
uav_read = uav_read_pre & ~read_accepted;
|
||||||
|
else
|
||||||
|
uav_read = uav_read_pre;
|
||||||
|
|
||||||
|
if (AV_REGISTERINCOMINGSIGNALS == 0)
|
||||||
|
uav_write = uav_write_pre;
|
||||||
|
else
|
||||||
|
uav_write = uav_write_pre & ~write_accepted;
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Begintransfer assignment
|
||||||
|
// -------------------------------------------------
|
||||||
|
reg end_begintransfer;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
if (USE_BEGINTRANSFER) begin
|
||||||
|
internal_begintransfer = av_begintransfer;
|
||||||
|
end else begin
|
||||||
|
internal_begintransfer = ( uav_write | uav_read ) & ~end_begintransfer;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
end_begintransfer <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (internal_begintransfer == 1 && uav_waitrequest)
|
||||||
|
end_begintransfer <= 1'b1;
|
||||||
|
else if (uav_waitrequest)
|
||||||
|
end_begintransfer <= end_begintransfer;
|
||||||
|
else
|
||||||
|
end_begintransfer <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Beginbursttransfer assignment
|
||||||
|
// -------------------------------------------------
|
||||||
|
reg end_beginbursttransfer;
|
||||||
|
wire last_burst_transfer_pre;
|
||||||
|
wire last_burst_transfer_reg;
|
||||||
|
wire last_burst_transfer;
|
||||||
|
|
||||||
|
// compare values before the mux to shorten critical path; benchmark before changing
|
||||||
|
assign last_burst_transfer_pre = (uav_burstcount_pre == symbols_per_word);
|
||||||
|
assign last_burst_transfer_reg = (burstcount_register == symbols_per_word);
|
||||||
|
assign last_burst_transfer = (internal_beginbursttransfer) ? last_burst_transfer_pre : last_burst_transfer_reg;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
if (USE_BEGINBURSTTRANSFER) begin
|
||||||
|
internal_beginbursttransfer = av_beginbursttransfer;
|
||||||
|
end else begin
|
||||||
|
internal_beginbursttransfer = uav_read ? internal_begintransfer : internal_begintransfer && ~end_beginbursttransfer;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
end_beginbursttransfer <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
end_beginbursttransfer <= end_beginbursttransfer;
|
||||||
|
if (last_burst_transfer && internal_begintransfer || uav_read) begin
|
||||||
|
end_beginbursttransfer <= 1'b0;
|
||||||
|
end
|
||||||
|
else if (uav_write && internal_begintransfer) begin
|
||||||
|
end_beginbursttransfer <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// synthesis translate_off
|
||||||
|
|
||||||
|
// ------------------------------------------------
|
||||||
|
// check_1 : for waitrequest signal violation
|
||||||
|
// Ensure that when waitreqeust is asserted, the master is not allowed to change its controls
|
||||||
|
// Exception : begintransfer / beginbursttransfer
|
||||||
|
// : previously not in any transaction (idle)
|
||||||
|
// Note : Not checking clken which is not exactly part of Avalon controls/inputs
|
||||||
|
// : Not using system verilog assertions (seq/prop) since it is not supported if using Modelsim_SE
|
||||||
|
// ------------------------------------------------
|
||||||
|
|
||||||
|
reg av_waitrequest_r;
|
||||||
|
reg av_write_r, av_read_r, av_lock_r, av_chipselect_r, av_debugaccess_r;
|
||||||
|
reg [AV_ADDRESS_W-1:0] av_address_r;
|
||||||
|
reg [AV_BYTEENABLE_W-1:0] av_byteenable_r;
|
||||||
|
reg [AV_BURSTCOUNT_W-1:0] av_burstcount_r;
|
||||||
|
reg [AV_DATA_W-1:0] av_writedata_r;
|
||||||
|
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
av_waitrequest_r <= '0;
|
||||||
|
av_write_r <= '0;
|
||||||
|
av_read_r <= '0;
|
||||||
|
av_lock_r <= '0;
|
||||||
|
av_chipselect_r <= '0;
|
||||||
|
av_debugaccess_r <= '0;
|
||||||
|
av_address_r <= '0;
|
||||||
|
av_byteenable_r <= '0;
|
||||||
|
av_burstcount_r <= '0;
|
||||||
|
av_writedata_r <= '0;
|
||||||
|
end else begin
|
||||||
|
av_waitrequest_r <= av_waitrequest;
|
||||||
|
av_write_r <= av_write;
|
||||||
|
av_read_r <= av_read;
|
||||||
|
av_lock_r <= av_lock;
|
||||||
|
av_chipselect_r <= av_chipselect;
|
||||||
|
av_debugaccess_r <= av_debugaccess;
|
||||||
|
av_address_r <= av_address;
|
||||||
|
av_byteenable_r <= av_byteenable;
|
||||||
|
av_burstcount_r <= av_burstcount;
|
||||||
|
av_writedata_r <= av_writedata;
|
||||||
|
|
||||||
|
if (
|
||||||
|
av_waitrequest_r && // When waitrequest is asserted
|
||||||
|
(
|
||||||
|
(av_write != av_write_r) || // Checks that : Input controls/data does not change
|
||||||
|
(av_read != av_read_r) ||
|
||||||
|
(av_lock != av_lock_r) ||
|
||||||
|
(av_debugaccess != av_debugaccess_r) ||
|
||||||
|
(av_address != av_address_r) ||
|
||||||
|
(av_byteenable != av_byteenable_r) ||
|
||||||
|
(av_burstcount != av_burstcount_r)
|
||||||
|
) &&
|
||||||
|
(av_write_r | av_read_r) && // Check only when : previously initiated a write/read
|
||||||
|
(!USE_CHIPSELECT | av_chipselect_r) // and chipselect was asserted (or unused)
|
||||||
|
) begin
|
||||||
|
$display( "%t: %m: Error: Input controls/data changed while av_waitrequest is asserted.", $time());
|
||||||
|
$display("av_address %x --> %x", av_address_r , av_address );
|
||||||
|
$display("av_byteenable %x --> %x", av_byteenable_r , av_byteenable );
|
||||||
|
$display("av_burstcount %x --> %x", av_burstcount_r , av_burstcount );
|
||||||
|
$display("av_writedata %x --> %x", av_writedata_r , av_writedata );
|
||||||
|
$display("av_write %x --> %x", av_write_r , av_write );
|
||||||
|
$display("av_read %x --> %x", av_read_r , av_read );
|
||||||
|
$display("av_lock %x --> %x", av_lock_r , av_lock );
|
||||||
|
$display("av_chipselect %x --> %x", av_chipselect_r , av_chipselect );
|
||||||
|
$display("av_debugaccess %x --> %x", av_debugaccess_r , av_debugaccess );
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// end check_1
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// synthesis translate_on
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
297
ip/altera/ddr3/altera_merlin_reorder_memory.sv
Normal file
297
ip/altera/ddr3/altera_merlin_reorder_memory.sv
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_traffic_limiter/altera_merlin_reorder_memory.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// Merlin Order Memory: this stores responses from slave
|
||||||
|
// and do reorder. The memory structure is normal memory
|
||||||
|
// with many segments for different responses that master
|
||||||
|
// can handle.
|
||||||
|
// The number of segment is the number of MAX_OUTSTANDING_RESPONSE
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
module altera_merlin_reorder_memory
|
||||||
|
#(
|
||||||
|
parameter DATA_W = 32,
|
||||||
|
ADDR_H_W = 4, // width to represent how many segments
|
||||||
|
ADDR_L_W = 4,
|
||||||
|
VALID_W = 4,
|
||||||
|
NUM_SEGMENT = 4,
|
||||||
|
DEPTH = 16
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Clock
|
||||||
|
// -------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
// -------------------
|
||||||
|
// Signals
|
||||||
|
// -------------------
|
||||||
|
input [DATA_W - 1 : 0] in_data,
|
||||||
|
input in_valid,
|
||||||
|
output in_ready,
|
||||||
|
|
||||||
|
output reg [DATA_W - 1 : 0] out_data,
|
||||||
|
output reg out_valid,
|
||||||
|
input out_ready,
|
||||||
|
// --------------------------------------------
|
||||||
|
// wr_segment: select write portion of memory
|
||||||
|
// rd_segment: select read portion of memory
|
||||||
|
// --------------------------------------------
|
||||||
|
input [ADDR_H_W - 1 : 0] wr_segment,
|
||||||
|
input [ADDR_H_W - 1 : 0] rd_segment
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Local parameter
|
||||||
|
// -------------------------------------
|
||||||
|
localparam SEGMENT_W = ADDR_H_W;
|
||||||
|
|
||||||
|
wire [ADDR_H_W + ADDR_L_W - 1 : 0] mem_wr_addr;
|
||||||
|
reg [ADDR_H_W + ADDR_L_W - 1 : 0] mem_rd_addr;
|
||||||
|
wire [ADDR_L_W - 1 : 0] mem_wr_ptr;
|
||||||
|
wire [ADDR_L_W - 1 : 0] mem_rd_ptr;
|
||||||
|
reg [ADDR_L_W - 1 : 0] mem_next_rd_ptr;
|
||||||
|
reg [DATA_W - 1 : 0] out_payload;
|
||||||
|
|
||||||
|
wire [NUM_SEGMENT - 1 : 0] pointer_ctrl_in_ready;
|
||||||
|
wire [NUM_SEGMENT - 1 : 0] pointer_ctrl_in_valid;
|
||||||
|
wire [NUM_SEGMENT - 1 : 0] pointer_ctrl_out_valid;
|
||||||
|
wire [NUM_SEGMENT - 1 : 0] pointer_ctrl_out_ready;
|
||||||
|
wire [ADDR_L_W - 1 : 0] pointer_ctrl_wr_ptr [NUM_SEGMENT];
|
||||||
|
wire [ADDR_L_W - 1 : 0] pointer_ctrl_rd_ptr [NUM_SEGMENT];
|
||||||
|
wire [ADDR_L_W - 1 : 0] pointer_ctrl_next_rd_ptr [NUM_SEGMENT];
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// Memory storage
|
||||||
|
// ---------------------------------
|
||||||
|
(* ramstyle="no_rw_check" *) reg [DATA_W - 1 : 0] mem [DEPTH - 1 : 0];
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (in_valid && in_ready)
|
||||||
|
mem[mem_wr_addr] = in_data;
|
||||||
|
out_payload = mem[mem_rd_addr];
|
||||||
|
end
|
||||||
|
//assign mem_rd_addr = {rd_segment, mem_next_rd_ptr};
|
||||||
|
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
out_data = out_payload;
|
||||||
|
out_valid = pointer_ctrl_out_valid[rd_segment];
|
||||||
|
end
|
||||||
|
// ---------------------------------
|
||||||
|
// Memory addresses
|
||||||
|
// ---------------------------------
|
||||||
|
assign mem_wr_ptr = pointer_ctrl_wr_ptr[wr_segment];
|
||||||
|
//assign mem_rd_ptr = pointer_ctrl_rd_ptr[rd_segment];
|
||||||
|
//assign mem_next_rd_ptr = pointer_ctrl_next_rd_ptr[rd_segment];
|
||||||
|
|
||||||
|
assign mem_wr_addr = {wr_segment, mem_wr_ptr};
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Bcos want, empty latency, mean assert read the data will appear on out_data.
|
||||||
|
// And need to jump around different segment of the memory.
|
||||||
|
// So when seeing endofpacket for this current segment, the read address
|
||||||
|
// will jump to next segment at first read address, so that the data will be ready
|
||||||
|
// it is okay to jump to next segment as this is the sequence of all transaction
|
||||||
|
// and they just increment. (standing at segment 0, then for sure next segment 1)
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
wire endofpacket;
|
||||||
|
assign endofpacket = out_payload[0];
|
||||||
|
wire [ADDR_H_W - 1: 0] next_rd_segment;
|
||||||
|
assign next_rd_segment = ((rd_segment + 1'b1) == NUM_SEGMENT) ? '0 : rd_segment + 1'b1;
|
||||||
|
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
if (out_valid && out_ready && endofpacket)
|
||||||
|
begin
|
||||||
|
mem_next_rd_ptr = pointer_ctrl_rd_ptr[next_rd_segment];
|
||||||
|
//mem_rd_addr = {rd_segment + 1'b1, mem_next_rd_ptr};
|
||||||
|
mem_rd_addr = {next_rd_segment, mem_next_rd_ptr};
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
mem_next_rd_ptr = pointer_ctrl_next_rd_ptr[rd_segment];
|
||||||
|
mem_rd_addr = {rd_segment, mem_next_rd_ptr};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// Output signals
|
||||||
|
// ---------------------------------
|
||||||
|
assign in_ready = pointer_ctrl_in_ready[wr_segment];
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// Control signals for each segment
|
||||||
|
// ---------------------------------
|
||||||
|
genvar j;
|
||||||
|
generate
|
||||||
|
for (j = 0; j < NUM_SEGMENT; j = j + 1)
|
||||||
|
begin : pointer_signal
|
||||||
|
assign pointer_ctrl_in_valid[j] = (wr_segment == j) && in_valid;
|
||||||
|
assign pointer_ctrl_out_ready[j] = (rd_segment == j) && out_ready;
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// ---------------------------------
|
||||||
|
// Seperate write and read pointer
|
||||||
|
// for each segment in memory
|
||||||
|
// ---------------------------------
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < NUM_SEGMENT; i = i + 1)
|
||||||
|
begin : each_segment_pointer_controller
|
||||||
|
memory_pointer_controller
|
||||||
|
#(
|
||||||
|
.ADDR_W (ADDR_L_W)
|
||||||
|
) reorder_memory_pointer_controller
|
||||||
|
(
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.in_ready (pointer_ctrl_in_ready[i]),
|
||||||
|
.in_valid (pointer_ctrl_in_valid[i]),
|
||||||
|
.out_ready (pointer_ctrl_out_ready[i]),
|
||||||
|
.out_valid (pointer_ctrl_out_valid[i]),
|
||||||
|
.wr_pointer (pointer_ctrl_wr_ptr[i]),
|
||||||
|
.rd_pointer (pointer_ctrl_rd_ptr[i]),
|
||||||
|
.next_rd_pointer (pointer_ctrl_next_rd_ptr[i])
|
||||||
|
);
|
||||||
|
end // block: each_segment_pointer_controller
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module memory_pointer_controller
|
||||||
|
#(
|
||||||
|
parameter ADDR_W = 4
|
||||||
|
)
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Clock
|
||||||
|
// -------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
// -------------------
|
||||||
|
// Signals
|
||||||
|
// -------------------
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
// -------------------------------
|
||||||
|
// Output write and read pointer
|
||||||
|
// -------------------------------
|
||||||
|
output [ADDR_W - 1 : 0] wr_pointer,
|
||||||
|
output [ADDR_W - 1 : 0] rd_pointer,
|
||||||
|
output [ADDR_W - 1 : 0] next_rd_pointer
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [ADDR_W - 1 : 0] incremented_wr_ptr;
|
||||||
|
reg [ADDR_W - 1 : 0] incremented_rd_ptr;
|
||||||
|
reg [ADDR_W - 1 : 0] wr_ptr;
|
||||||
|
reg [ADDR_W - 1 : 0] rd_ptr;
|
||||||
|
reg [ADDR_W - 1 : 0] next_wr_ptr;
|
||||||
|
reg [ADDR_W - 1 : 0] next_rd_ptr;
|
||||||
|
reg full, empty, next_full, next_empty;
|
||||||
|
reg read, write, internal_out_ready, internal_out_valid;
|
||||||
|
|
||||||
|
assign incremented_wr_ptr = wr_ptr + 1'b1;
|
||||||
|
assign incremented_rd_ptr = rd_ptr + 1'b1;
|
||||||
|
assign next_wr_ptr = write ? incremented_wr_ptr : wr_ptr;
|
||||||
|
assign next_rd_ptr = read ? incremented_rd_ptr : rd_ptr;
|
||||||
|
assign wr_pointer = wr_ptr;
|
||||||
|
assign rd_pointer = rd_ptr;
|
||||||
|
assign next_rd_pointer = next_rd_ptr;
|
||||||
|
|
||||||
|
// -------------------------------
|
||||||
|
// Define write and read signals
|
||||||
|
// --------------------------------
|
||||||
|
// internal read, if it has any valid data
|
||||||
|
// and output are ready to accepts data then a read will be performed.
|
||||||
|
// -------------------------------
|
||||||
|
//assign read = internal_out_ready && internal_out_valid;
|
||||||
|
assign read = internal_out_ready && !empty;
|
||||||
|
assign write = in_ready && in_valid;
|
||||||
|
|
||||||
|
always_ff @(posedge clk or posedge reset)
|
||||||
|
begin
|
||||||
|
if (reset)
|
||||||
|
begin
|
||||||
|
wr_ptr <= 0;
|
||||||
|
rd_ptr <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
wr_ptr <= next_wr_ptr;
|
||||||
|
rd_ptr <= next_rd_ptr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Generate full/empty signal for memory
|
||||||
|
// if read and next read pointer same as write, set empty, write will clear empty
|
||||||
|
// if write and next write pointer same as read, set full, read will clear full
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
next_full = full;
|
||||||
|
next_empty = empty;
|
||||||
|
if (read && !write)
|
||||||
|
begin
|
||||||
|
next_full = 1'b0;
|
||||||
|
if (incremented_rd_ptr == wr_ptr)
|
||||||
|
next_empty = 1'b1;
|
||||||
|
end
|
||||||
|
if (write && !read)
|
||||||
|
begin
|
||||||
|
next_empty = 1'b0;
|
||||||
|
if (incremented_wr_ptr == rd_ptr)
|
||||||
|
next_full = 1'b1;
|
||||||
|
end
|
||||||
|
end // always_comb
|
||||||
|
|
||||||
|
always_ff @(posedge clk or posedge reset)
|
||||||
|
begin
|
||||||
|
if (reset)
|
||||||
|
begin
|
||||||
|
empty <= 1;
|
||||||
|
full <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
empty <= next_empty;
|
||||||
|
full <= next_full;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// Control signals
|
||||||
|
// --------------------
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
in_ready = !full;
|
||||||
|
out_valid = !empty;
|
||||||
|
internal_out_ready = out_ready;
|
||||||
|
end // always_comb
|
||||||
|
endmodule
|
||||||
|
|
622
ip/altera/ddr3/altera_merlin_slave_agent.sv
Normal file
622
ip/altera/ddr3/altera_merlin_slave_agent.sv
Normal file
@ -0,0 +1,622 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2011 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_slave_agent/altera_merlin_slave_agent.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_merlin_slave_agent
|
||||||
|
#(
|
||||||
|
// Packet parameters
|
||||||
|
parameter PKT_BEGIN_BURST = 81,
|
||||||
|
parameter PKT_DATA_H = 31,
|
||||||
|
parameter PKT_DATA_L = 0,
|
||||||
|
parameter PKT_SYMBOL_W = 8,
|
||||||
|
parameter PKT_BYTEEN_H = 71,
|
||||||
|
parameter PKT_BYTEEN_L = 68,
|
||||||
|
parameter PKT_ADDR_H = 63,
|
||||||
|
parameter PKT_ADDR_L = 32,
|
||||||
|
parameter PKT_TRANS_LOCK = 87,
|
||||||
|
parameter PKT_TRANS_COMPRESSED_READ = 67,
|
||||||
|
parameter PKT_TRANS_POSTED = 66,
|
||||||
|
parameter PKT_TRANS_WRITE = 65,
|
||||||
|
parameter PKT_TRANS_READ = 64,
|
||||||
|
parameter PKT_SRC_ID_H = 74,
|
||||||
|
parameter PKT_SRC_ID_L = 72,
|
||||||
|
parameter PKT_DEST_ID_H = 77,
|
||||||
|
parameter PKT_DEST_ID_L = 75,
|
||||||
|
parameter PKT_BURSTWRAP_H = 85,
|
||||||
|
parameter PKT_BURSTWRAP_L = 82,
|
||||||
|
parameter PKT_BYTE_CNT_H = 81,
|
||||||
|
parameter PKT_BYTE_CNT_L = 78,
|
||||||
|
parameter PKT_PROTECTION_H = 86,
|
||||||
|
parameter PKT_PROTECTION_L = 86,
|
||||||
|
parameter PKT_RESPONSE_STATUS_H = 89,
|
||||||
|
parameter PKT_RESPONSE_STATUS_L = 88,
|
||||||
|
parameter PKT_BURST_SIZE_H = 92,
|
||||||
|
parameter PKT_BURST_SIZE_L = 90,
|
||||||
|
parameter PKT_ORI_BURST_SIZE_L = 93,
|
||||||
|
parameter PKT_ORI_BURST_SIZE_H = 95,
|
||||||
|
parameter ST_DATA_W = 96,
|
||||||
|
parameter ST_CHANNEL_W = 32,
|
||||||
|
|
||||||
|
// Slave parameters
|
||||||
|
parameter ADDR_W = PKT_ADDR_H - PKT_ADDR_L + 1,
|
||||||
|
parameter AVS_DATA_W = PKT_DATA_H - PKT_DATA_L + 1,
|
||||||
|
parameter AVS_BURSTCOUNT_W = 4,
|
||||||
|
parameter PKT_SYMBOLS = AVS_DATA_W / PKT_SYMBOL_W,
|
||||||
|
|
||||||
|
// Slave agent parameters
|
||||||
|
parameter PREVENT_FIFO_OVERFLOW = 0,
|
||||||
|
parameter SUPPRESS_0_BYTEEN_CMD = 1,
|
||||||
|
parameter USE_READRESPONSE = 0,
|
||||||
|
parameter USE_WRITERESPONSE = 0,
|
||||||
|
|
||||||
|
// Derived slave parameters
|
||||||
|
parameter AVS_BE_W = PKT_BYTEEN_H - PKT_BYTEEN_L + 1,
|
||||||
|
parameter BURST_SIZE_W = 3,
|
||||||
|
|
||||||
|
// Derived FIFO width
|
||||||
|
parameter FIFO_DATA_W = ST_DATA_W + 1,
|
||||||
|
|
||||||
|
// ECC parameter
|
||||||
|
parameter ECC_ENABLE = 0
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// Universal-Avalon anti-slave
|
||||||
|
output [ADDR_W-1:0] m0_address,
|
||||||
|
output [AVS_BURSTCOUNT_W-1:0] m0_burstcount,
|
||||||
|
output [AVS_BE_W-1:0] m0_byteenable,
|
||||||
|
output m0_read,
|
||||||
|
input [AVS_DATA_W-1:0] m0_readdata,
|
||||||
|
input m0_waitrequest,
|
||||||
|
output m0_write,
|
||||||
|
output [AVS_DATA_W-1:0] m0_writedata,
|
||||||
|
input m0_readdatavalid,
|
||||||
|
output m0_debugaccess,
|
||||||
|
output m0_lock,
|
||||||
|
input [1:0] m0_response,
|
||||||
|
input m0_writeresponsevalid,
|
||||||
|
|
||||||
|
// Avalon-ST FIFO interfaces.
|
||||||
|
// Note: there's no need to include the "data" field here, at least for
|
||||||
|
// reads, since readdata is filled in from slave info. To keep life
|
||||||
|
// simple, have a data field, but fill it with 0s.
|
||||||
|
// Av-st response fifo source interface
|
||||||
|
output reg [FIFO_DATA_W-1:0] rf_source_data,
|
||||||
|
output rf_source_valid,
|
||||||
|
output rf_source_startofpacket,
|
||||||
|
output rf_source_endofpacket,
|
||||||
|
input rf_source_ready,
|
||||||
|
|
||||||
|
// Av-st response fifo sink interface
|
||||||
|
input [FIFO_DATA_W-1:0] rf_sink_data,
|
||||||
|
input rf_sink_valid,
|
||||||
|
input rf_sink_startofpacket,
|
||||||
|
input rf_sink_endofpacket,
|
||||||
|
output rf_sink_ready,
|
||||||
|
|
||||||
|
// Av-st readdata fifo src interface, data and response
|
||||||
|
// extra 2 bits for storing RESPONSE STATUS
|
||||||
|
output [AVS_DATA_W+1:0] rdata_fifo_src_data,
|
||||||
|
output rdata_fifo_src_valid,
|
||||||
|
input rdata_fifo_src_ready,
|
||||||
|
|
||||||
|
// Av-st readdata fifo sink interface
|
||||||
|
input [AVS_DATA_W+1:0] rdata_fifo_sink_data,
|
||||||
|
input rdata_fifo_sink_valid,
|
||||||
|
output rdata_fifo_sink_ready,
|
||||||
|
input rdata_fifo_sink_error,
|
||||||
|
|
||||||
|
// Av-st sink command packet interface
|
||||||
|
output cp_ready,
|
||||||
|
input cp_valid,
|
||||||
|
input [ST_DATA_W-1:0] cp_data,
|
||||||
|
input [ST_CHANNEL_W-1:0] cp_channel,
|
||||||
|
input cp_startofpacket,
|
||||||
|
input cp_endofpacket,
|
||||||
|
|
||||||
|
// Av-st source response packet interface
|
||||||
|
input rp_ready,
|
||||||
|
output reg rp_valid,
|
||||||
|
output reg [ST_DATA_W-1:0] rp_data,
|
||||||
|
output rp_startofpacket,
|
||||||
|
output rp_endofpacket
|
||||||
|
);
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Ceil(log2()) function log2ceil of 4 = 2
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input reg[63:0] val;
|
||||||
|
reg [63:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
// ------------------------------------------------
|
||||||
|
// Local Parameters
|
||||||
|
// ------------------------------------------------
|
||||||
|
localparam DATA_W = PKT_DATA_H - PKT_DATA_L + 1;
|
||||||
|
localparam BE_W = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
|
||||||
|
localparam MID_W = PKT_SRC_ID_H - PKT_SRC_ID_L + 1;
|
||||||
|
localparam SID_W = PKT_DEST_ID_H - PKT_DEST_ID_L + 1;
|
||||||
|
localparam BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1;
|
||||||
|
localparam BURSTWRAP_W = PKT_BURSTWRAP_H - PKT_BURSTWRAP_L + 1;
|
||||||
|
localparam BURSTSIZE_W = PKT_BURST_SIZE_H - PKT_BURST_SIZE_L + 1;
|
||||||
|
localparam BITS_TO_MASK = log2ceil(PKT_SYMBOLS);
|
||||||
|
localparam MAX_BURST = 1 << (AVS_BURSTCOUNT_W - 1);
|
||||||
|
localparam BURSTING = (MAX_BURST > PKT_SYMBOLS);
|
||||||
|
|
||||||
|
// ------------------------------------------------
|
||||||
|
// Signals
|
||||||
|
// ------------------------------------------------
|
||||||
|
wire [DATA_W-1:0] cmd_data;
|
||||||
|
wire [BE_W-1:0] cmd_byteen;
|
||||||
|
wire [ADDR_W-1:0] cmd_addr;
|
||||||
|
wire [MID_W-1:0] cmd_mid;
|
||||||
|
wire [SID_W-1:0] cmd_sid;
|
||||||
|
wire cmd_read;
|
||||||
|
wire cmd_write;
|
||||||
|
wire cmd_compressed;
|
||||||
|
wire cmd_posted;
|
||||||
|
wire [BYTE_CNT_W-1:0] cmd_byte_cnt;
|
||||||
|
wire [BURSTWRAP_W-1:0] cmd_burstwrap;
|
||||||
|
wire [BURSTSIZE_W-1:0] cmd_burstsize;
|
||||||
|
wire cmd_debugaccess;
|
||||||
|
|
||||||
|
wire suppress_cmd;
|
||||||
|
wire byteen_asserted;
|
||||||
|
wire suppress_read;
|
||||||
|
wire suppress_write;
|
||||||
|
wire needs_response_synthesis;
|
||||||
|
wire generate_response;
|
||||||
|
|
||||||
|
// Assign command fields
|
||||||
|
assign cmd_data = cp_data[PKT_DATA_H :PKT_DATA_L ];
|
||||||
|
assign cmd_byteen = cp_data[PKT_BYTEEN_H:PKT_BYTEEN_L];
|
||||||
|
assign cmd_addr = cp_data[PKT_ADDR_H :PKT_ADDR_L ];
|
||||||
|
assign cmd_compressed = cp_data[PKT_TRANS_COMPRESSED_READ];
|
||||||
|
assign cmd_posted = cp_data[PKT_TRANS_POSTED];
|
||||||
|
assign cmd_write = cp_data[PKT_TRANS_WRITE];
|
||||||
|
assign cmd_read = cp_data[PKT_TRANS_READ];
|
||||||
|
assign cmd_mid = cp_data[PKT_SRC_ID_H :PKT_SRC_ID_L];
|
||||||
|
assign cmd_sid = cp_data[PKT_DEST_ID_H:PKT_DEST_ID_L];
|
||||||
|
assign cmd_byte_cnt = cp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
|
||||||
|
assign cmd_burstwrap = cp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
|
||||||
|
assign cmd_burstsize = cp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
|
||||||
|
assign cmd_debugaccess = cp_data[PKT_PROTECTION_L];
|
||||||
|
|
||||||
|
// Local "ready_for_command" signal: deasserted when the agent is unable to accept
|
||||||
|
// another command, e.g. rdv FIFO is full, (local readdata storage is full &&
|
||||||
|
// ~rp_ready), ...
|
||||||
|
// Say, this could depend on the type of command, for example, even if the
|
||||||
|
// rdv FIFO is full, a write request can be accepted. For later.
|
||||||
|
wire ready_for_command;
|
||||||
|
|
||||||
|
wire local_lock = cp_valid & cp_data[PKT_TRANS_LOCK];
|
||||||
|
wire local_write = cp_valid & cp_data[PKT_TRANS_WRITE];
|
||||||
|
wire local_read = cp_valid & cp_data[PKT_TRANS_READ];
|
||||||
|
wire local_compressed_read = cp_valid & cp_data[PKT_TRANS_COMPRESSED_READ];
|
||||||
|
wire nonposted_write_endofpacket = ~cp_data[PKT_TRANS_POSTED] & local_write & cp_endofpacket;
|
||||||
|
|
||||||
|
// num_symbols is PKT_SYMBOLS, appropriately sized.
|
||||||
|
wire [31:0] int_num_symbols = PKT_SYMBOLS;
|
||||||
|
wire [BYTE_CNT_W-1:0] num_symbols = int_num_symbols[BYTE_CNT_W-1:0];
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (PREVENT_FIFO_OVERFLOW) begin : prevent_fifo_overflow_block
|
||||||
|
// ---------------------------------------------------
|
||||||
|
// Backpressure if the slave says to, or if FIFO overflow may occur.
|
||||||
|
//
|
||||||
|
// All commands are backpressured once the FIFO is full
|
||||||
|
// even if they don't need storage. This breaks a long
|
||||||
|
// combinatorial path from the master read/write through
|
||||||
|
// this logic and back to the master via the backpressure
|
||||||
|
// path.
|
||||||
|
//
|
||||||
|
// To avoid a loss of throughput the FIFO will be parameterized
|
||||||
|
// one slot deeper. The extra slot should never be used in normal
|
||||||
|
// operation, but should a slave misbehave and accept one more
|
||||||
|
// read than it should then backpressure will kick in.
|
||||||
|
//
|
||||||
|
// An example: assume a slave with MPRT = 2. It can accept a
|
||||||
|
// command sequence RRWW without backpressuring. If the FIFO is
|
||||||
|
// only 2 deep, we'd backpressure the writes leading to loss of
|
||||||
|
// throughput. If the FIFO is 3 deep, we'll only backpressure when
|
||||||
|
// RRR... which is an illegal condition anyway.
|
||||||
|
// ---------------------------------------------------
|
||||||
|
|
||||||
|
assign ready_for_command = rf_source_ready;
|
||||||
|
assign cp_ready = (~m0_waitrequest | suppress_cmd) && ready_for_command;
|
||||||
|
|
||||||
|
end else begin : no_prevent_fifo_overflow_block
|
||||||
|
|
||||||
|
// Do not suppress the command or the slave will
|
||||||
|
// not be able to waitrequest
|
||||||
|
assign ready_for_command = 1'b1;
|
||||||
|
// Backpressure only if the slave says to.
|
||||||
|
assign cp_ready = ~m0_waitrequest | suppress_cmd;
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate if (SUPPRESS_0_BYTEEN_CMD && !BURSTING) begin : suppress_0_byteen_cmd_non_bursting
|
||||||
|
assign byteen_asserted = |cmd_byteen;
|
||||||
|
assign suppress_read = ~byteen_asserted;
|
||||||
|
assign suppress_write = ~byteen_asserted;
|
||||||
|
assign suppress_cmd = ~byteen_asserted;
|
||||||
|
end else if (SUPPRESS_0_BYTEEN_CMD && BURSTING) begin: suppress_0_byteen_cmd_bursting
|
||||||
|
assign byteen_asserted = |cmd_byteen;
|
||||||
|
assign suppress_read = ~byteen_asserted;
|
||||||
|
assign suppress_write = 1'b0;
|
||||||
|
assign suppress_cmd = ~byteen_asserted && cmd_read;
|
||||||
|
end else begin : no_suppress_0_byteen_cmd
|
||||||
|
assign suppress_read = 1'b0;
|
||||||
|
assign suppress_write = 1'b0;
|
||||||
|
assign suppress_cmd = 1'b0;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Extract avalon signals from command packet.
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Mask off the lower bits of address.
|
||||||
|
// The burst adapter before this component will break narrow sized packets
|
||||||
|
// into sub-bursts of length 1. However, the packet addresses are preserved,
|
||||||
|
// which means this component may see size-aligned addresses.
|
||||||
|
//
|
||||||
|
// Masking ensures that the addresses seen by an Avalon slave are aligned to
|
||||||
|
// the full data width instead of the size.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// output from burst adapter (datawidth=4, size=2 bytes):
|
||||||
|
// subburst1 addr=0, subburst2 addr=2, subburst3 addr=4, subburst4 addr=6
|
||||||
|
// expected output from slave agent:
|
||||||
|
// subburst1 addr=0, subburst2 addr=0, subburst3 addr=4, subburst4 addr=4
|
||||||
|
generate
|
||||||
|
if (BITS_TO_MASK > 0) begin : mask_address
|
||||||
|
|
||||||
|
assign m0_address = { cmd_addr[ADDR_W-1:BITS_TO_MASK], {BITS_TO_MASK{1'b0}} };
|
||||||
|
|
||||||
|
end else begin : no_mask_address
|
||||||
|
|
||||||
|
assign m0_address = cmd_addr;
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign m0_byteenable = cmd_byteen;
|
||||||
|
assign m0_writedata = cmd_data;
|
||||||
|
|
||||||
|
// Note: no Avalon-MM slave in existence accepts uncompressed read bursts -
|
||||||
|
// this sort of burst exists only in merlin fabric ST packets. What to do
|
||||||
|
// if we see such a burst? All beats in that burst need to be transmitted
|
||||||
|
// to the slave so we have enough space-time for byteenable expression.
|
||||||
|
//
|
||||||
|
// There can be multiple bursts in a packet, but only one beat per burst
|
||||||
|
// in <most> cases. The exception is when we've decided not to insert a
|
||||||
|
// burst adapter for efficiency reasons, in which case this agent is also
|
||||||
|
// responsible for driving burstcount to 1 on each beat of an uncompressed
|
||||||
|
// read burst.
|
||||||
|
|
||||||
|
assign m0_read = ready_for_command & !suppress_read & (local_compressed_read | local_read);
|
||||||
|
|
||||||
|
generate
|
||||||
|
// AVS_BURSTCOUNT_W and BYTE_CNT_W may not be equal. Assign m0_burstcount
|
||||||
|
// from a sub-range, or 0-pad, as appropriate.
|
||||||
|
if (AVS_BURSTCOUNT_W > BYTE_CNT_W) begin : m0_burstcount_zero_pad
|
||||||
|
wire [AVS_BURSTCOUNT_W - BYTE_CNT_W - 1 : 0] zero_pad = {(AVS_BURSTCOUNT_W - BYTE_CNT_W) {1'b0}};
|
||||||
|
assign m0_burstcount = (local_read & ~local_compressed_read) ?
|
||||||
|
{zero_pad, num_symbols} :
|
||||||
|
{zero_pad, cmd_byte_cnt};
|
||||||
|
end
|
||||||
|
else begin : m0_burstcount_no_pad
|
||||||
|
assign m0_burstcount = (local_read & ~local_compressed_read) ?
|
||||||
|
num_symbols[AVS_BURSTCOUNT_W-1:0] :
|
||||||
|
cmd_byte_cnt[AVS_BURSTCOUNT_W-1:0];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign m0_write = ready_for_command & local_write & !suppress_write;
|
||||||
|
assign m0_lock = ready_for_command & local_lock & (m0_read | m0_write);
|
||||||
|
assign m0_debugaccess = cmd_debugaccess;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
// Indirection layer for response packet values. Some may always wire
|
||||||
|
// directly from the slave translator; others will no doubt emerge from
|
||||||
|
// various FIFOs.
|
||||||
|
// What to put in resp_data when a write occured? Answer: it does not
|
||||||
|
// matter, because only response status is needed for non-posted writes,
|
||||||
|
// and the packet already has a field for that.
|
||||||
|
//
|
||||||
|
// We use the rdata_fifo to store write responses as well. This allows us
|
||||||
|
// to handle backpressure on the response path, and allows write response
|
||||||
|
// merging.
|
||||||
|
assign rdata_fifo_src_valid = m0_readdatavalid | m0_writeresponsevalid;
|
||||||
|
assign rdata_fifo_src_data = {m0_response, m0_readdata};
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// Generate a token when read commands are suppressed. The token
|
||||||
|
// is stored in the response FIFO, and will be used to synthesize
|
||||||
|
// a read response. The same token is used for non-posted write
|
||||||
|
// response synthesis.
|
||||||
|
//
|
||||||
|
// Note: this token is not generated for suppressed uncompressed read cycles;
|
||||||
|
// the burst uncompression logic at the read side of the response FIFO
|
||||||
|
// generates the correct number of responses.
|
||||||
|
//
|
||||||
|
// When the slave can return the response, let it do its job. Don't
|
||||||
|
// synthesize a response in that case, unless we've suppressed the
|
||||||
|
// the last transfer in a write sub-burst.
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
wire write_end_of_subburst;
|
||||||
|
assign needs_response_synthesis = ((local_read | local_compressed_read) & suppress_read) ||
|
||||||
|
(!USE_WRITERESPONSE && nonposted_write_endofpacket) ||
|
||||||
|
(USE_WRITERESPONSE && write_end_of_subburst && suppress_write);
|
||||||
|
|
||||||
|
// Avalon-ST interfaces to external response FIFO.
|
||||||
|
//
|
||||||
|
// For efficiency, when synthesizing a write response we only store a non-posted write
|
||||||
|
// transaction at its endofpacket, even if it was split into multiple sub-bursts.
|
||||||
|
//
|
||||||
|
// When not synthesizing write responses, we store each sub-burst in the FIFO.
|
||||||
|
// Each sub-burst to the slave will return a response, which corresponds to one
|
||||||
|
// entry in the FIFO. We merge all the sub-burst responses on the final
|
||||||
|
// sub-burst and send it on the response channel.
|
||||||
|
|
||||||
|
wire internal_cp_endofburst;
|
||||||
|
wire [31:0] minimum_bytecount_wire = PKT_SYMBOLS; // to solve qis warning
|
||||||
|
wire [AVS_BURSTCOUNT_W-1:0] minimum_bytecount;
|
||||||
|
|
||||||
|
assign minimum_bytecount = minimum_bytecount_wire[AVS_BURSTCOUNT_W-1:0];
|
||||||
|
assign internal_cp_endofburst = (cmd_byte_cnt == minimum_bytecount);
|
||||||
|
assign write_end_of_subburst = local_write & internal_cp_endofburst;
|
||||||
|
|
||||||
|
assign rf_source_valid = (local_read | local_compressed_read | (nonposted_write_endofpacket && !USE_WRITERESPONSE) | (USE_WRITERESPONSE && internal_cp_endofburst && local_write))
|
||||||
|
& ready_for_command & cp_ready;
|
||||||
|
assign rf_source_startofpacket = cp_startofpacket;
|
||||||
|
assign rf_source_endofpacket = cp_endofpacket;
|
||||||
|
always @* begin
|
||||||
|
// default: assign every command packet field to the response FIFO...
|
||||||
|
rf_source_data = {1'b0, cp_data};
|
||||||
|
|
||||||
|
// ... and override select fields as needed.
|
||||||
|
rf_source_data[FIFO_DATA_W-1] = needs_response_synthesis;
|
||||||
|
rf_source_data[PKT_DATA_H :PKT_DATA_L] = {DATA_W {1'b0}};
|
||||||
|
rf_source_data[PKT_BYTEEN_H :PKT_BYTEEN_L] = cmd_byteen;
|
||||||
|
rf_source_data[PKT_ADDR_H :PKT_ADDR_L] = cmd_addr;
|
||||||
|
rf_source_data[PKT_TRANS_COMPRESSED_READ] = cmd_compressed;
|
||||||
|
rf_source_data[PKT_TRANS_POSTED] = cmd_posted;
|
||||||
|
rf_source_data[PKT_TRANS_WRITE] = cmd_write;
|
||||||
|
rf_source_data[PKT_TRANS_READ] = cmd_read;
|
||||||
|
rf_source_data[PKT_SRC_ID_H :PKT_SRC_ID_L] = cmd_mid;
|
||||||
|
rf_source_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = cmd_sid;
|
||||||
|
rf_source_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L] = cmd_byte_cnt;
|
||||||
|
rf_source_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L] = cmd_burstwrap;
|
||||||
|
rf_source_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L] = cmd_burstsize;
|
||||||
|
rf_source_data[PKT_PROTECTION_H:PKT_PROTECTION_L] = '0;
|
||||||
|
rf_source_data[PKT_PROTECTION_L] = cmd_debugaccess;
|
||||||
|
end
|
||||||
|
|
||||||
|
wire uncompressor_source_valid;
|
||||||
|
wire [BURSTSIZE_W-1:0] uncompressor_burstsize;
|
||||||
|
wire last_write_response;
|
||||||
|
|
||||||
|
// last_write_response indicates the last response of the broken-up write burst (sub-bursts).
|
||||||
|
// At this time, the final merged response is sent, and rp_valid is only asserted
|
||||||
|
// once for the whole burst.
|
||||||
|
generate
|
||||||
|
if (USE_WRITERESPONSE) begin
|
||||||
|
assign last_write_response = rf_sink_data[PKT_TRANS_WRITE] & rf_sink_endofpacket;
|
||||||
|
always @* begin
|
||||||
|
if (rf_sink_data[PKT_TRANS_WRITE] == 1)
|
||||||
|
rp_valid = (rdata_fifo_sink_valid | generate_response) & last_write_response & !rf_sink_data[PKT_TRANS_POSTED];
|
||||||
|
else
|
||||||
|
rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
assign last_write_response = 1'b0;
|
||||||
|
always @* begin
|
||||||
|
rp_valid = rdata_fifo_sink_valid | uncompressor_source_valid;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// Response merging
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
reg [1:0] current_response;
|
||||||
|
reg [1:0] response_merged;
|
||||||
|
generate
|
||||||
|
if (USE_WRITERESPONSE) begin : response_merging_all
|
||||||
|
reg first_write_response;
|
||||||
|
reg reset_merged_output;
|
||||||
|
reg [1:0] previous_response_in;
|
||||||
|
reg [1:0] previous_response;
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
first_write_response <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin // Merging work for write response, for read: previous_response_in = current_response
|
||||||
|
if (rf_sink_valid & (rdata_fifo_sink_valid | generate_response) & rf_sink_data[PKT_TRANS_WRITE]) begin
|
||||||
|
first_write_response <= 1'b0;
|
||||||
|
if (rf_sink_endofpacket)
|
||||||
|
first_write_response <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
current_response = generate_response ? 2'b00 : rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W] | {2{rdata_fifo_sink_error}};
|
||||||
|
reset_merged_output = first_write_response && (rdata_fifo_sink_valid || generate_response);
|
||||||
|
previous_response_in = reset_merged_output ? current_response : previous_response;
|
||||||
|
response_merged = current_response >= previous_response ? current_response: previous_response_in;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
previous_response <= 2'b00;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (rf_sink_valid & (rdata_fifo_sink_valid || generate_response)) begin
|
||||||
|
previous_response <= response_merged;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin : response_merging_read_only
|
||||||
|
always @* begin
|
||||||
|
current_response = generate_response ? 2'b00: rdata_fifo_sink_data[AVS_DATA_W+1:AVS_DATA_W] |
|
||||||
|
{2{rdata_fifo_sink_error}};
|
||||||
|
response_merged = current_response;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign generate_response = rf_sink_data[FIFO_DATA_W-1];
|
||||||
|
|
||||||
|
wire [BYTE_CNT_W-1:0] rf_sink_byte_cnt = rf_sink_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L];
|
||||||
|
wire rf_sink_compressed = rf_sink_data[PKT_TRANS_COMPRESSED_READ];
|
||||||
|
wire [BURSTWRAP_W-1:0] rf_sink_burstwrap = rf_sink_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L];
|
||||||
|
wire [BURSTSIZE_W-1:0] rf_sink_burstsize = rf_sink_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L];
|
||||||
|
wire [ADDR_W-1:0] rf_sink_addr = rf_sink_data[PKT_ADDR_H:PKT_ADDR_L];
|
||||||
|
// a non posted write response is always completed in 1 cycle. Modify the startofpacket signal to 1'b1 instead of taking whatever is in the rf_fifo
|
||||||
|
wire rf_sink_startofpacket_wire = rf_sink_data[PKT_TRANS_WRITE] ? 1'b1 : rf_sink_startofpacket;
|
||||||
|
|
||||||
|
wire [BYTE_CNT_W-1:0] burst_byte_cnt;
|
||||||
|
wire [BURSTWRAP_W-1:0] rp_burstwrap;
|
||||||
|
wire [ADDR_W-1:0] rp_address;
|
||||||
|
wire rp_is_compressed;
|
||||||
|
wire ready_for_response;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// We're typically ready for a response if the network is ready. There
|
||||||
|
// is one exception:
|
||||||
|
//
|
||||||
|
// If the slave issues write responses, we only issue a merged response on
|
||||||
|
// the final sub-burst. As a result, we only care about response channel
|
||||||
|
// availability on the final burst when we send out the merged response.
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
assign ready_for_response = (USE_WRITERESPONSE) ?
|
||||||
|
rp_ready || (rf_sink_data[PKT_TRANS_WRITE] && !last_write_response) || rf_sink_data[PKT_TRANS_POSTED]:
|
||||||
|
rp_ready;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// Backpressure the readdata fifo if we're supposed to synthesize a response.
|
||||||
|
// This may be a read response (for suppressed reads) or a write response
|
||||||
|
// (for non-posted writes).
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
assign rdata_fifo_sink_ready = rdata_fifo_sink_valid & ready_for_response & ~(rf_sink_valid & generate_response);
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
// By default, return all fields...
|
||||||
|
rp_data = rf_sink_data[ST_DATA_W - 1 : 0];
|
||||||
|
|
||||||
|
// ... and override specific fields.
|
||||||
|
rp_data[PKT_DATA_H :PKT_DATA_L] = rdata_fifo_sink_data[AVS_DATA_W-1:0];
|
||||||
|
// Assignments directly from the response fifo.
|
||||||
|
rp_data[PKT_TRANS_POSTED] = rf_sink_data[PKT_TRANS_POSTED];
|
||||||
|
rp_data[PKT_TRANS_WRITE] = rf_sink_data[PKT_TRANS_WRITE];
|
||||||
|
rp_data[PKT_SRC_ID_H :PKT_SRC_ID_L] = rf_sink_data[PKT_DEST_ID_H : PKT_DEST_ID_L];
|
||||||
|
rp_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = rf_sink_data[PKT_SRC_ID_H : PKT_SRC_ID_L];
|
||||||
|
rp_data[PKT_BYTEEN_H :PKT_BYTEEN_L] = rf_sink_data[PKT_BYTEEN_H : PKT_BYTEEN_L];
|
||||||
|
rp_data[PKT_PROTECTION_H:PKT_PROTECTION_L] = rf_sink_data[PKT_PROTECTION_H:PKT_PROTECTION_L];
|
||||||
|
|
||||||
|
// Burst uncompressor assignments
|
||||||
|
rp_data[PKT_ADDR_H :PKT_ADDR_L] = rp_address;
|
||||||
|
rp_data[PKT_BURSTWRAP_H:PKT_BURSTWRAP_L] = rp_burstwrap;
|
||||||
|
rp_data[PKT_BYTE_CNT_H:PKT_BYTE_CNT_L] = burst_byte_cnt;
|
||||||
|
rp_data[PKT_TRANS_READ] = rf_sink_data[PKT_TRANS_READ] | rf_sink_data[PKT_TRANS_COMPRESSED_READ];
|
||||||
|
rp_data[PKT_TRANS_COMPRESSED_READ] = rp_is_compressed;
|
||||||
|
|
||||||
|
rp_data[PKT_RESPONSE_STATUS_H:PKT_RESPONSE_STATUS_L] = response_merged;
|
||||||
|
rp_data[PKT_BURST_SIZE_H:PKT_BURST_SIZE_L] = uncompressor_burstsize;
|
||||||
|
// bounce the original size back to the master untouched
|
||||||
|
rp_data[PKT_ORI_BURST_SIZE_H:PKT_ORI_BURST_SIZE_L] = rf_sink_data[PKT_ORI_BURST_SIZE_H:PKT_ORI_BURST_SIZE_L];
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// Note: the burst uncompressor may be asked to generate responses for
|
||||||
|
// write packets; these are treated the same as single-cycle uncompressed
|
||||||
|
// reads.
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
altera_merlin_burst_uncompressor #(
|
||||||
|
.ADDR_W (ADDR_W),
|
||||||
|
.BURSTWRAP_W (BURSTWRAP_W),
|
||||||
|
.BYTE_CNT_W (BYTE_CNT_W),
|
||||||
|
.PKT_SYMBOLS (PKT_SYMBOLS),
|
||||||
|
.BURST_SIZE_W (BURSTSIZE_W)
|
||||||
|
) uncompressor (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.sink_startofpacket (rf_sink_startofpacket_wire),
|
||||||
|
.sink_endofpacket (rf_sink_endofpacket),
|
||||||
|
.sink_valid (rf_sink_valid & (rdata_fifo_sink_valid | generate_response)),
|
||||||
|
.sink_ready (rf_sink_ready),
|
||||||
|
.sink_addr (rf_sink_addr),
|
||||||
|
.sink_burstwrap (rf_sink_burstwrap),
|
||||||
|
.sink_byte_cnt (rf_sink_byte_cnt),
|
||||||
|
.sink_is_compressed (rf_sink_compressed),
|
||||||
|
.sink_burstsize (rf_sink_burstsize),
|
||||||
|
|
||||||
|
.source_startofpacket (rp_startofpacket),
|
||||||
|
.source_endofpacket (rp_endofpacket),
|
||||||
|
.source_valid (uncompressor_source_valid),
|
||||||
|
.source_ready (ready_for_response),
|
||||||
|
.source_addr (rp_address),
|
||||||
|
.source_burstwrap (rp_burstwrap),
|
||||||
|
.source_byte_cnt (burst_byte_cnt),
|
||||||
|
.source_is_compressed (rp_is_compressed),
|
||||||
|
.source_burstsize (uncompressor_burstsize)
|
||||||
|
);
|
||||||
|
|
||||||
|
//--------------------------------------
|
||||||
|
// Assertion: In case slave support response. The slave needs return response in order
|
||||||
|
// Ex: non-posted write followed by a read: write response must complete before read data
|
||||||
|
//--------------------------------------
|
||||||
|
// synthesis translate_off
|
||||||
|
ERROR_write_response_and_read_response_cannot_happen_same_time:
|
||||||
|
assert property ( @(posedge clk)
|
||||||
|
disable iff (reset) !(m0_writeresponsevalid && m0_readdatavalid)
|
||||||
|
);
|
||||||
|
|
||||||
|
// synthesis translate_on
|
||||||
|
endmodule
|
||||||
|
|
482
ip/altera/ddr3/altera_merlin_slave_translator.sv
Normal file
482
ip/altera/ddr3/altera_merlin_slave_translator.sv
Normal file
@ -0,0 +1,482 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_slave_translator/altera_merlin_slave_translator.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Merlin Slave Translator
|
||||||
|
//
|
||||||
|
// Translates Universal Avalon MM Slave
|
||||||
|
// to any Avalon MM Slave
|
||||||
|
// -------------------------------------
|
||||||
|
//
|
||||||
|
//Notable Note: 0 AV_READLATENCY is not allowed and will be converted to a 1 cycle readlatency in all cases but one
|
||||||
|
//If you declare a slave with fixed read timing requirements, the readlatency of such a slave will be allowed to be zero
|
||||||
|
//The key feature here is that no same cycle turnaround data is processed through the fabric.
|
||||||
|
|
||||||
|
//import avalon_utilities_pkg::*;
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_merlin_slave_translator #(
|
||||||
|
parameter
|
||||||
|
//Widths
|
||||||
|
AV_ADDRESS_W = 32,
|
||||||
|
AV_DATA_W = 32,
|
||||||
|
AV_BURSTCOUNT_W = 4,
|
||||||
|
AV_BYTEENABLE_W = 4,
|
||||||
|
UAV_BYTEENABLE_W = 4,
|
||||||
|
|
||||||
|
//Read Latency
|
||||||
|
AV_READLATENCY = 1,
|
||||||
|
|
||||||
|
//Timing
|
||||||
|
AV_READ_WAIT_CYCLES = 0,
|
||||||
|
AV_WRITE_WAIT_CYCLES = 0,
|
||||||
|
AV_SETUP_WAIT_CYCLES = 0,
|
||||||
|
AV_DATA_HOLD_CYCLES = 0,
|
||||||
|
|
||||||
|
//Optional Port Declarations
|
||||||
|
USE_READDATAVALID = 1,
|
||||||
|
USE_WAITREQUEST = 1,
|
||||||
|
USE_READRESPONSE = 0,
|
||||||
|
USE_WRITERESPONSE = 0,
|
||||||
|
|
||||||
|
//Variable Addressing
|
||||||
|
AV_SYMBOLS_PER_WORD = 4,
|
||||||
|
AV_ADDRESS_SYMBOLS = 0,
|
||||||
|
AV_BURSTCOUNT_SYMBOLS = 0,
|
||||||
|
BITS_PER_WORD = clog2_plusone(AV_SYMBOLS_PER_WORD - 1),
|
||||||
|
UAV_ADDRESS_W = 38,
|
||||||
|
UAV_BURSTCOUNT_W = 10,
|
||||||
|
UAV_DATA_W = 32,
|
||||||
|
|
||||||
|
AV_CONSTANT_BURST_BEHAVIOR = 0,
|
||||||
|
UAV_CONSTANT_BURST_BEHAVIOR = 0,
|
||||||
|
CHIPSELECT_THROUGH_READLATENCY = 0,
|
||||||
|
|
||||||
|
// Tightly-Coupled Options
|
||||||
|
USE_UAV_CLKEN = 0,
|
||||||
|
AV_REQUIRE_UNALIGNED_ADDRESSES = 0
|
||||||
|
) (
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Universal Avalon Slave
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
input wire [UAV_ADDRESS_W - 1 : 0] uav_address,
|
||||||
|
input wire [UAV_DATA_W - 1 : 0] uav_writedata,
|
||||||
|
input wire uav_write,
|
||||||
|
input wire uav_read,
|
||||||
|
input wire [UAV_BURSTCOUNT_W - 1 : 0] uav_burstcount,
|
||||||
|
input wire [UAV_BYTEENABLE_W - 1 : 0] uav_byteenable,
|
||||||
|
input wire uav_lock,
|
||||||
|
input wire uav_debugaccess,
|
||||||
|
input wire uav_clken,
|
||||||
|
|
||||||
|
output logic uav_readdatavalid,
|
||||||
|
output logic uav_waitrequest,
|
||||||
|
output logic [UAV_DATA_W - 1 : 0] uav_readdata,
|
||||||
|
output logic [1:0] uav_response,
|
||||||
|
// input wire uav_writeresponserequest,
|
||||||
|
output logic uav_writeresponsevalid,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Customizable Avalon Master
|
||||||
|
// -------------------
|
||||||
|
output logic [AV_ADDRESS_W - 1 : 0] av_address,
|
||||||
|
output logic [AV_DATA_W - 1 : 0] av_writedata,
|
||||||
|
output logic av_write,
|
||||||
|
output logic av_read,
|
||||||
|
output logic [AV_BURSTCOUNT_W - 1 : 0] av_burstcount,
|
||||||
|
output logic [AV_BYTEENABLE_W - 1 : 0] av_byteenable,
|
||||||
|
output logic [AV_BYTEENABLE_W - 1 : 0] av_writebyteenable,
|
||||||
|
output logic av_begintransfer,
|
||||||
|
output wire av_chipselect,
|
||||||
|
output logic av_beginbursttransfer,
|
||||||
|
output logic av_lock,
|
||||||
|
output wire av_clken,
|
||||||
|
output wire av_debugaccess,
|
||||||
|
output wire av_outputenable,
|
||||||
|
|
||||||
|
input logic [AV_DATA_W - 1 : 0] av_readdata,
|
||||||
|
input logic av_readdatavalid,
|
||||||
|
input logic av_waitrequest,
|
||||||
|
|
||||||
|
input logic [1:0] av_response,
|
||||||
|
// output logic av_writeresponserequest,
|
||||||
|
input wire av_writeresponsevalid
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
function integer clog2_plusone;
|
||||||
|
input [31:0] Depth;
|
||||||
|
integer i;
|
||||||
|
begin
|
||||||
|
i = Depth;
|
||||||
|
for(clog2_plusone = 0; i > 0; clog2_plusone = clog2_plusone + 1)
|
||||||
|
i = i >> 1;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function integer max;
|
||||||
|
//returns the larger of two passed arguments
|
||||||
|
input [31:0] one;
|
||||||
|
input [31:0] two;
|
||||||
|
if(one > two)
|
||||||
|
max=one;
|
||||||
|
else
|
||||||
|
max=two;
|
||||||
|
endfunction // int
|
||||||
|
|
||||||
|
localparam AV_READ_WAIT_INDEXED = (AV_SETUP_WAIT_CYCLES + AV_READ_WAIT_CYCLES);
|
||||||
|
localparam AV_WRITE_WAIT_INDEXED = (AV_SETUP_WAIT_CYCLES + AV_WRITE_WAIT_CYCLES);
|
||||||
|
localparam AV_DATA_HOLD_INDEXED = (AV_WRITE_WAIT_INDEXED + AV_DATA_HOLD_CYCLES);
|
||||||
|
localparam LOG2_OF_LATENCY_SUM = max(clog2_plusone(AV_READ_WAIT_INDEXED + 1),clog2_plusone(AV_DATA_HOLD_INDEXED + 1));
|
||||||
|
localparam BURSTCOUNT_SHIFT_SELECTOR = AV_BURSTCOUNT_SYMBOLS ? 0 : BITS_PER_WORD;
|
||||||
|
localparam ADDRESS_SHIFT_SELECTOR = AV_ADDRESS_SYMBOLS ? 0 : BITS_PER_WORD;
|
||||||
|
localparam ADDRESS_HIGH = ( UAV_ADDRESS_W > AV_ADDRESS_W + ADDRESS_SHIFT_SELECTOR ) ?
|
||||||
|
AV_ADDRESS_W :
|
||||||
|
UAV_ADDRESS_W - ADDRESS_SHIFT_SELECTOR;
|
||||||
|
localparam BURSTCOUNT_HIGH = ( UAV_BURSTCOUNT_W > AV_BURSTCOUNT_W + BURSTCOUNT_SHIFT_SELECTOR ) ?
|
||||||
|
AV_BURSTCOUNT_W :
|
||||||
|
UAV_BURSTCOUNT_W - BURSTCOUNT_SHIFT_SELECTOR;
|
||||||
|
localparam BYTEENABLE_ADDRESS_BITS = ( clog2_plusone(UAV_BYTEENABLE_W) - 1 ) >= 1 ? clog2_plusone(UAV_BYTEENABLE_W) - 1 : 1;
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate the symbols per word as the power of 2 extended symbols per word
|
||||||
|
wire [31 : 0] symbols_per_word_int = 2**(clog2_plusone(AV_SYMBOLS_PER_WORD[UAV_BURSTCOUNT_W : 0] - 1));
|
||||||
|
wire [UAV_BURSTCOUNT_W-1 : 0] symbols_per_word = symbols_per_word_int[UAV_BURSTCOUNT_W-1 : 0];
|
||||||
|
|
||||||
|
// +--------------------------------
|
||||||
|
// |Backwards Compatibility Signals
|
||||||
|
// +--------------------------------
|
||||||
|
assign av_clken = (USE_UAV_CLKEN) ? uav_clken : 1'b1;
|
||||||
|
assign av_debugaccess = uav_debugaccess;
|
||||||
|
|
||||||
|
// +-------------------
|
||||||
|
// |Passthru Signals
|
||||||
|
// +-------------------
|
||||||
|
|
||||||
|
reg [1 : 0] av_response_delayed;
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
av_response_delayed <= 2'b0;
|
||||||
|
end else begin
|
||||||
|
av_response_delayed <= av_response;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
if (!USE_READRESPONSE && !USE_WRITERESPONSE) begin
|
||||||
|
uav_response = '0;
|
||||||
|
end else begin
|
||||||
|
if (AV_READLATENCY != 0 || USE_READDATAVALID) begin
|
||||||
|
uav_response = av_response;
|
||||||
|
end else begin
|
||||||
|
uav_response = av_response_delayed;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// assign av_writeresponserequest = uav_writeresponserequest;
|
||||||
|
assign uav_writeresponsevalid = av_writeresponsevalid;
|
||||||
|
|
||||||
|
//-------------------------
|
||||||
|
//Writedata and Byteenable
|
||||||
|
//-------------------------
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
av_byteenable = '0;
|
||||||
|
av_byteenable = uav_byteenable[AV_BYTEENABLE_W - 1 : 0];
|
||||||
|
end
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
av_writedata = '0;
|
||||||
|
av_writedata = uav_writedata[AV_DATA_W - 1 : 0];
|
||||||
|
end
|
||||||
|
|
||||||
|
// +-------------------
|
||||||
|
// |Calculated Signals
|
||||||
|
// +-------------------
|
||||||
|
|
||||||
|
logic [UAV_ADDRESS_W - 1 : 0 ] real_uav_address;
|
||||||
|
|
||||||
|
function [BYTEENABLE_ADDRESS_BITS - 1 : 0 ] decode_byteenable;
|
||||||
|
input [UAV_BYTEENABLE_W - 1 : 0 ] byteenable;
|
||||||
|
|
||||||
|
for(int i = 0 ; i < UAV_BYTEENABLE_W; i++ ) begin
|
||||||
|
if(byteenable[i] == 1) begin
|
||||||
|
return i;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return '0;
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
reg [AV_BURSTCOUNT_W - 1 : 0] burstcount_reg;
|
||||||
|
reg [AV_ADDRESS_W - 1 : 0] address_reg;
|
||||||
|
always@(posedge clk, posedge reset) begin
|
||||||
|
if(reset) begin
|
||||||
|
burstcount_reg <= '0;
|
||||||
|
address_reg <= '0;
|
||||||
|
end else begin
|
||||||
|
burstcount_reg <= burstcount_reg;
|
||||||
|
address_reg <= address_reg;
|
||||||
|
if(av_beginbursttransfer) begin
|
||||||
|
burstcount_reg <= uav_burstcount [ BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];
|
||||||
|
address_reg <= real_uav_address [ ADDRESS_HIGH - 1 + ADDRESS_SHIFT_SELECTOR : ADDRESS_SHIFT_SELECTOR ];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
logic [BYTEENABLE_ADDRESS_BITS-1:0] temp_wire;
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
if( AV_REQUIRE_UNALIGNED_ADDRESSES == 1) begin
|
||||||
|
temp_wire = decode_byteenable(uav_byteenable);
|
||||||
|
real_uav_address = { uav_address[UAV_ADDRESS_W - 1 : BYTEENABLE_ADDRESS_BITS ], temp_wire[BYTEENABLE_ADDRESS_BITS - 1 : 0 ] };
|
||||||
|
end else begin
|
||||||
|
real_uav_address = uav_address;
|
||||||
|
end
|
||||||
|
|
||||||
|
av_address = real_uav_address[ADDRESS_HIGH - 1 + ADDRESS_SHIFT_SELECTOR : ADDRESS_SHIFT_SELECTOR ];
|
||||||
|
if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )
|
||||||
|
av_address = address_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
av_burstcount=uav_burstcount[BURSTCOUNT_HIGH - 1 + BURSTCOUNT_SHIFT_SELECTOR : BURSTCOUNT_SHIFT_SELECTOR ];
|
||||||
|
if( AV_CONSTANT_BURST_BEHAVIOR && !UAV_CONSTANT_BURST_BEHAVIOR && ~av_beginbursttransfer )
|
||||||
|
av_burstcount = burstcount_reg;
|
||||||
|
end
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
av_lock = uav_lock;
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Writebyteenable Assignment
|
||||||
|
// -------------------
|
||||||
|
always@* begin
|
||||||
|
av_writebyteenable = { (AV_BYTEENABLE_W){uav_write} } & uav_byteenable[AV_BYTEENABLE_W - 1 : 0];
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Waitrequest Assignment
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
reg av_waitrequest_generated;
|
||||||
|
reg av_waitrequest_generated_read;
|
||||||
|
reg av_waitrequest_generated_write;
|
||||||
|
reg waitrequest_reset_override;
|
||||||
|
reg [ ( LOG2_OF_LATENCY_SUM ? LOG2_OF_LATENCY_SUM - 1 : 0 ) : 0 ] wait_latency_counter;
|
||||||
|
|
||||||
|
always@(posedge reset, posedge clk) begin
|
||||||
|
if(reset) begin
|
||||||
|
wait_latency_counter <= '0;
|
||||||
|
waitrequest_reset_override <= 1'h1;
|
||||||
|
end else begin
|
||||||
|
waitrequest_reset_override <= 1'h0;
|
||||||
|
wait_latency_counter <= '0;
|
||||||
|
if( ~uav_waitrequest | waitrequest_reset_override )
|
||||||
|
wait_latency_counter <= '0;
|
||||||
|
else if( uav_read | uav_write )
|
||||||
|
wait_latency_counter <= wait_latency_counter + 1'h1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
|
||||||
|
av_read = uav_read;
|
||||||
|
av_write = uav_write;
|
||||||
|
av_waitrequest_generated = 1'h1;
|
||||||
|
av_waitrequest_generated_read = 1'h1;
|
||||||
|
av_waitrequest_generated_write = 1'h1;
|
||||||
|
|
||||||
|
if(LOG2_OF_LATENCY_SUM == 1)
|
||||||
|
av_waitrequest_generated = 0;
|
||||||
|
|
||||||
|
if(LOG2_OF_LATENCY_SUM > 1 && !USE_WAITREQUEST) begin
|
||||||
|
av_read = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_read;
|
||||||
|
av_write = wait_latency_counter >= AV_SETUP_WAIT_CYCLES && uav_write && wait_latency_counter <= AV_WRITE_WAIT_INDEXED;
|
||||||
|
av_waitrequest_generated_read = wait_latency_counter != AV_READ_WAIT_INDEXED;
|
||||||
|
av_waitrequest_generated_write = wait_latency_counter != AV_DATA_HOLD_INDEXED;
|
||||||
|
|
||||||
|
if(uav_write)
|
||||||
|
av_waitrequest_generated = av_waitrequest_generated_write;
|
||||||
|
else
|
||||||
|
av_waitrequest_generated = av_waitrequest_generated_read;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if(USE_WAITREQUEST) begin
|
||||||
|
uav_waitrequest = av_waitrequest;
|
||||||
|
end else begin
|
||||||
|
uav_waitrequest = av_waitrequest_generated | waitrequest_reset_override;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------
|
||||||
|
// Readdata Assignment
|
||||||
|
// --------------
|
||||||
|
|
||||||
|
reg[(AV_DATA_W ? AV_DATA_W -1 : 0 ): 0] av_readdata_pre;
|
||||||
|
|
||||||
|
always@(posedge clk, posedge reset) begin
|
||||||
|
if(reset)
|
||||||
|
av_readdata_pre <= 'b0;
|
||||||
|
else
|
||||||
|
av_readdata_pre <= av_readdata;
|
||||||
|
end
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
uav_readdata = {UAV_DATA_W{1'b0}};
|
||||||
|
if( AV_READLATENCY != 0 || USE_READDATAVALID ) begin
|
||||||
|
uav_readdata[AV_DATA_W-1:0] = av_readdata;
|
||||||
|
end else begin
|
||||||
|
uav_readdata[AV_DATA_W-1:0] = av_readdata_pre;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Readdatavalid Assigment
|
||||||
|
// -------------------
|
||||||
|
reg[(AV_READLATENCY>0 ? AV_READLATENCY-1:0) :0] read_latency_shift_reg;
|
||||||
|
reg top_read_latency_shift_reg;
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
uav_readdatavalid=top_read_latency_shift_reg;
|
||||||
|
if(USE_READDATAVALID) begin
|
||||||
|
uav_readdatavalid = av_readdatavalid;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
top_read_latency_shift_reg = uav_read & ~uav_waitrequest & ~waitrequest_reset_override;
|
||||||
|
if(AV_READLATENCY == 1 || AV_READLATENCY == 0 ) begin
|
||||||
|
top_read_latency_shift_reg=read_latency_shift_reg;
|
||||||
|
end
|
||||||
|
if (AV_READLATENCY > 1) begin
|
||||||
|
top_read_latency_shift_reg = read_latency_shift_reg[(AV_READLATENCY ? AV_READLATENCY-1 : 0)];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always@(posedge reset, posedge clk) begin
|
||||||
|
if (reset) begin
|
||||||
|
read_latency_shift_reg <= '0;
|
||||||
|
end else if (av_clken) begin
|
||||||
|
read_latency_shift_reg[0] <= uav_read && ~uav_waitrequest & ~waitrequest_reset_override;
|
||||||
|
for (int i=0; i+1 < AV_READLATENCY ; i+=1 ) begin
|
||||||
|
read_latency_shift_reg[i+1] <= read_latency_shift_reg[i];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------
|
||||||
|
// Chipselect and OutputEnable
|
||||||
|
// ------------
|
||||||
|
reg av_chipselect_pre;
|
||||||
|
wire cs_extension;
|
||||||
|
reg av_outputenable_pre;
|
||||||
|
|
||||||
|
assign av_chipselect = (uav_read | uav_write) ? 1'b1 : av_chipselect_pre;
|
||||||
|
assign cs_extension = ( (^ read_latency_shift_reg) & ~top_read_latency_shift_reg ) | ((| read_latency_shift_reg) & ~(^ read_latency_shift_reg));
|
||||||
|
assign av_outputenable = uav_read ? 1'b1 : av_outputenable_pre;
|
||||||
|
|
||||||
|
always@(posedge reset, posedge clk) begin
|
||||||
|
if(reset)
|
||||||
|
av_outputenable_pre <= 1'b0;
|
||||||
|
else if( AV_READLATENCY == 0 && AV_READ_WAIT_INDEXED != 0 )
|
||||||
|
av_outputenable_pre <= 0;
|
||||||
|
else
|
||||||
|
av_outputenable_pre <= cs_extension | uav_read;
|
||||||
|
end
|
||||||
|
|
||||||
|
always@(posedge reset, posedge clk) begin
|
||||||
|
if(reset) begin
|
||||||
|
av_chipselect_pre <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
av_chipselect_pre <= 1'b0;
|
||||||
|
if(AV_READLATENCY != 0 && CHIPSELECT_THROUGH_READLATENCY == 1) begin
|
||||||
|
//The AV_READLATENCY term is only here to prevent chipselect from remaining asserted while read and write fall.
|
||||||
|
//There is no functional impact as 0 cycle transactions are treated as 1 cycle on the other side of the translator.
|
||||||
|
if(uav_read) begin
|
||||||
|
av_chipselect_pre <= 1'b1;
|
||||||
|
end else if(cs_extension == 1) begin
|
||||||
|
av_chipselect_pre <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Begintransfer Assigment
|
||||||
|
// -------------------
|
||||||
|
reg end_begintransfer;
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
av_begintransfer = ( uav_write | uav_read ) & ~end_begintransfer;
|
||||||
|
end
|
||||||
|
|
||||||
|
always@ ( posedge clk or posedge reset ) begin
|
||||||
|
if(reset) begin
|
||||||
|
end_begintransfer <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if(av_begintransfer == 1 && uav_waitrequest && ~waitrequest_reset_override)
|
||||||
|
end_begintransfer <= 1'b1;
|
||||||
|
else if(uav_waitrequest)
|
||||||
|
end_begintransfer <= end_begintransfer;
|
||||||
|
else
|
||||||
|
end_begintransfer <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Beginbursttransfer Assigment
|
||||||
|
// -------------------
|
||||||
|
reg end_beginbursttransfer;
|
||||||
|
reg in_transfer;
|
||||||
|
|
||||||
|
always@* begin
|
||||||
|
av_beginbursttransfer = uav_read ? av_begintransfer : (av_begintransfer && ~end_beginbursttransfer && ~in_transfer);
|
||||||
|
end
|
||||||
|
|
||||||
|
always@ ( posedge clk or posedge reset ) begin
|
||||||
|
if(reset) begin
|
||||||
|
end_beginbursttransfer <= 1'b0;
|
||||||
|
in_transfer <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
end_beginbursttransfer <= uav_write & ( uav_burstcount != symbols_per_word );
|
||||||
|
if(uav_write && uav_burstcount == symbols_per_word)
|
||||||
|
in_transfer <=1'b0;
|
||||||
|
else if(uav_write)
|
||||||
|
in_transfer <=1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
787
ip/altera/ddr3/altera_merlin_traffic_limiter.sv
Normal file
787
ip/altera/ddr3/altera_merlin_traffic_limiter.sv
Normal file
@ -0,0 +1,787 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_traffic_limiter/altera_merlin_traffic_limiter.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// Merlin Traffic Limiter
|
||||||
|
//
|
||||||
|
// Ensures that non-posted transaction responses are returned
|
||||||
|
// in order of request. Out-of-order responses can happen
|
||||||
|
// when a master does a non-posted transaction on a slave
|
||||||
|
// while responses are pending from a different slave.
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// 1) read to any latent slave, followed by a read to a
|
||||||
|
// variable-latent slave
|
||||||
|
// 2) read to any fixed-latency slave, followed by a read
|
||||||
|
// to another fixed-latency slave whose fixed latency is smaller.
|
||||||
|
// 3) non-posted write to any latent slave, followed by a non-posted
|
||||||
|
// write or read to any variable-latent slave.
|
||||||
|
//
|
||||||
|
// This component has two implementation modes that ensure
|
||||||
|
// response order, controlled by the REORDER parameter.
|
||||||
|
//
|
||||||
|
// 0) Backpressure to prevent a master from switching slaves
|
||||||
|
// until all outstanding responses have returned. We also
|
||||||
|
// have to suppress the non-posted transaction, obviously.
|
||||||
|
//
|
||||||
|
// 1) Reorder the responses as they return using a memory
|
||||||
|
// block.
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
// altera message_off 10036
|
||||||
|
module altera_merlin_traffic_limiter
|
||||||
|
#(
|
||||||
|
parameter
|
||||||
|
PKT_TRANS_POSTED = 1,
|
||||||
|
PKT_DEST_ID_H = 0,
|
||||||
|
PKT_DEST_ID_L = 0,
|
||||||
|
PKT_SRC_ID_H = 0,
|
||||||
|
PKT_SRC_ID_L = 0,
|
||||||
|
PKT_BYTE_CNT_H = 0,
|
||||||
|
PKT_BYTE_CNT_L = 0,
|
||||||
|
PKT_BYTEEN_H = 0,
|
||||||
|
PKT_BYTEEN_L = 0,
|
||||||
|
PKT_TRANS_WRITE = 0,
|
||||||
|
PKT_TRANS_READ = 0,
|
||||||
|
ST_DATA_W = 72,
|
||||||
|
ST_CHANNEL_W = 32,
|
||||||
|
|
||||||
|
MAX_OUTSTANDING_RESPONSES = 1,
|
||||||
|
PIPELINED = 0,
|
||||||
|
ENFORCE_ORDER = 1,
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// internal: allows optimization between this
|
||||||
|
// component and the demux
|
||||||
|
// -------------------------------------
|
||||||
|
VALID_WIDTH = 1,
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Prevents all RAW and WAR hazards by waiting for
|
||||||
|
// responses to return before issuing a command
|
||||||
|
// with different direction.
|
||||||
|
//
|
||||||
|
// This is intended for Avalon masters which are
|
||||||
|
// connected to AXI slaves, because of the differing
|
||||||
|
// ordering models for the protocols.
|
||||||
|
//
|
||||||
|
// If PREVENT_HAZARDS is 1, then the current implementation
|
||||||
|
// needs to know whether incoming writes will be posted or
|
||||||
|
// not at compile-time. Only one of SUPPORTS_POSTED_WRITES
|
||||||
|
// and SUPPORTS_NONPOSTED_WRITES can be 1.
|
||||||
|
//
|
||||||
|
// When PREVENT_HAZARDS is 0 there is no such restriction.
|
||||||
|
//
|
||||||
|
// It is possible to be less restrictive for memories.
|
||||||
|
// -------------------------------------
|
||||||
|
PREVENT_HAZARDS = 0,
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Used only when hazard prevention is on, but may be used
|
||||||
|
// for optimization work in the future.
|
||||||
|
// -------------------------------------
|
||||||
|
SUPPORTS_POSTED_WRITES = 1,
|
||||||
|
SUPPORTS_NONPOSTED_WRITES = 0,
|
||||||
|
|
||||||
|
// -------------------------------------------------
|
||||||
|
// Enables the reorder buffer which allows a master to
|
||||||
|
// switch slaves while responses are pending.
|
||||||
|
// Reponses will be reordered following command issue order.
|
||||||
|
// -------------------------------------------------
|
||||||
|
REORDER = 0
|
||||||
|
)
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command
|
||||||
|
// -------------------
|
||||||
|
input cmd_sink_valid,
|
||||||
|
input [ST_DATA_W-1 : 0] cmd_sink_data,
|
||||||
|
input [ST_CHANNEL_W-1 : 0] cmd_sink_channel,
|
||||||
|
input cmd_sink_startofpacket,
|
||||||
|
input cmd_sink_endofpacket,
|
||||||
|
output cmd_sink_ready,
|
||||||
|
|
||||||
|
output reg [VALID_WIDTH-1 : 0] cmd_src_valid,
|
||||||
|
output reg [ST_DATA_W-1 : 0] cmd_src_data,
|
||||||
|
output reg [ST_CHANNEL_W-1 : 0] cmd_src_channel,
|
||||||
|
output reg cmd_src_startofpacket,
|
||||||
|
output reg cmd_src_endofpacket,
|
||||||
|
input cmd_src_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Response
|
||||||
|
// -------------------
|
||||||
|
input rsp_sink_valid,
|
||||||
|
input [ST_DATA_W-1 : 0] rsp_sink_data,
|
||||||
|
input [ST_CHANNEL_W-1 : 0] rsp_sink_channel,
|
||||||
|
input rsp_sink_startofpacket,
|
||||||
|
input rsp_sink_endofpacket,
|
||||||
|
output reg rsp_sink_ready,
|
||||||
|
|
||||||
|
output reg rsp_src_valid,
|
||||||
|
output reg [ST_DATA_W-1 : 0] rsp_src_data,
|
||||||
|
output reg [ST_CHANNEL_W-1 : 0] rsp_src_channel,
|
||||||
|
output reg rsp_src_startofpacket,
|
||||||
|
output reg rsp_src_endofpacket,
|
||||||
|
input rsp_src_ready
|
||||||
|
);
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Local Parameters
|
||||||
|
// -------------------------------------
|
||||||
|
localparam DEST_ID_W = PKT_DEST_ID_H - PKT_DEST_ID_L + 1;
|
||||||
|
localparam COUNTER_W = log2ceil(MAX_OUTSTANDING_RESPONSES + 1);
|
||||||
|
localparam PAYLOAD_W = ST_DATA_W + ST_CHANNEL_W + 4;
|
||||||
|
localparam NUMSYMBOLS = PKT_BYTEEN_H - PKT_BYTEEN_L + 1;
|
||||||
|
localparam MAX_DEST_ID = 1 << (DEST_ID_W);
|
||||||
|
localparam PKT_BYTE_CNT_W = PKT_BYTE_CNT_H - PKT_BYTE_CNT_L + 1;
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Memory Parameters
|
||||||
|
// ------------------------------------------------------
|
||||||
|
localparam MAX_BYTE_CNT = 1 << (PKT_BYTE_CNT_W);
|
||||||
|
localparam MAX_BURST_LENGTH = log2ceil(MAX_BYTE_CNT/NUMSYMBOLS);
|
||||||
|
|
||||||
|
// Memory stores packet width, including sop and eop
|
||||||
|
localparam MEM_W = ST_DATA_W + ST_CHANNEL_W + 1 + 1;
|
||||||
|
localparam MEM_DEPTH = MAX_OUTSTANDING_RESPONSES * (MAX_BYTE_CNT/NUMSYMBOLS);
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// Input Stage
|
||||||
|
//
|
||||||
|
// Figure out if the destination id has changed
|
||||||
|
// -----------------------------------------------------
|
||||||
|
wire stage1_dest_changed;
|
||||||
|
wire stage1_trans_changed;
|
||||||
|
wire [PAYLOAD_W-1 : 0] stage1_payload;
|
||||||
|
wire in_nonposted_cmd;
|
||||||
|
reg [ST_CHANNEL_W-1:0] last_channel;
|
||||||
|
wire [DEST_ID_W-1 : 0] dest_id;
|
||||||
|
reg [DEST_ID_W-1 : 0] last_dest_id;
|
||||||
|
reg was_write;
|
||||||
|
wire is_write;
|
||||||
|
wire suppress;
|
||||||
|
wire save_dest_id;
|
||||||
|
|
||||||
|
wire suppress_change_dest_id;
|
||||||
|
wire suppress_max_outstanding;
|
||||||
|
wire suppress_change_trans_but_not_dest;
|
||||||
|
wire suppress_change_trans_for_one_slave;
|
||||||
|
|
||||||
|
generate if (PREVENT_HAZARDS == 1) begin : convert_posted_to_nonposted_block
|
||||||
|
assign in_nonposted_cmd = 1'b1;
|
||||||
|
end else begin : non_posted_cmd_assignment_block
|
||||||
|
assign in_nonposted_cmd = (cmd_sink_data[PKT_TRANS_POSTED] == 0);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// ------------------------------------
|
||||||
|
// Optimization: for the unpipelined case, we can save the destid if
|
||||||
|
// this is an unsuppressed nonposted command. This eliminates
|
||||||
|
// dependence on the backpressure signal.
|
||||||
|
//
|
||||||
|
// Not a problem for the pipelined case.
|
||||||
|
// ------------------------------------
|
||||||
|
generate
|
||||||
|
if (PIPELINED) begin : pipelined_save_dest_id
|
||||||
|
assign save_dest_id = cmd_sink_valid & cmd_sink_ready & in_nonposted_cmd;
|
||||||
|
end else begin : unpipelined_save_dest_id
|
||||||
|
assign save_dest_id = cmd_sink_valid & ~(suppress_change_dest_id | suppress_max_outstanding) & in_nonposted_cmd;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
last_dest_id <= 0;
|
||||||
|
last_channel <= 0;
|
||||||
|
was_write <= 0;
|
||||||
|
end
|
||||||
|
else if (save_dest_id) begin
|
||||||
|
last_dest_id <= dest_id;
|
||||||
|
last_channel <= cmd_sink_channel;
|
||||||
|
was_write <= is_write;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign dest_id = cmd_sink_data[PKT_DEST_ID_H:PKT_DEST_ID_L];
|
||||||
|
assign is_write = cmd_sink_data[PKT_TRANS_WRITE];
|
||||||
|
assign stage1_dest_changed = (last_dest_id != dest_id);
|
||||||
|
assign stage1_trans_changed = (was_write != is_write);
|
||||||
|
|
||||||
|
assign stage1_payload = {
|
||||||
|
cmd_sink_data,
|
||||||
|
cmd_sink_channel,
|
||||||
|
cmd_sink_startofpacket,
|
||||||
|
cmd_sink_endofpacket,
|
||||||
|
stage1_dest_changed,
|
||||||
|
stage1_trans_changed };
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// (Optional) pipeline between input and output
|
||||||
|
// -----------------------------------------------------
|
||||||
|
wire stage2_valid;
|
||||||
|
reg stage2_ready;
|
||||||
|
wire [PAYLOAD_W-1 : 0] stage2_payload;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (PIPELINED == 1) begin : pipelined_limiter
|
||||||
|
altera_avalon_st_pipeline_base
|
||||||
|
#(
|
||||||
|
.BITS_PER_SYMBOL(PAYLOAD_W)
|
||||||
|
) stage1_pipe (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.in_ready (cmd_sink_ready),
|
||||||
|
.in_valid (cmd_sink_valid),
|
||||||
|
.in_data (stage1_payload),
|
||||||
|
.out_valid (stage2_valid),
|
||||||
|
.out_ready (stage2_ready),
|
||||||
|
.out_data (stage2_payload)
|
||||||
|
);
|
||||||
|
end else begin : unpipelined_limiter
|
||||||
|
assign stage2_valid = cmd_sink_valid;
|
||||||
|
assign stage2_payload = stage1_payload;
|
||||||
|
assign cmd_sink_ready = stage2_ready;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
// Output Stage
|
||||||
|
// -----------------------------------------------------
|
||||||
|
wire [ST_DATA_W-1 : 0] stage2_data;
|
||||||
|
wire [ST_CHANNEL_W-1:0] stage2_channel;
|
||||||
|
wire stage2_startofpacket;
|
||||||
|
wire stage2_endofpacket;
|
||||||
|
wire stage2_dest_changed;
|
||||||
|
wire stage2_trans_changed;
|
||||||
|
reg has_pending_responses;
|
||||||
|
reg [COUNTER_W-1 : 0] pending_response_count;
|
||||||
|
reg [COUNTER_W-1 : 0] next_pending_response_count;
|
||||||
|
wire nonposted_cmd;
|
||||||
|
wire nonposted_cmd_accepted;
|
||||||
|
wire response_accepted;
|
||||||
|
wire response_sink_accepted;
|
||||||
|
wire response_src_accepted;
|
||||||
|
wire count_is_1;
|
||||||
|
wire count_is_0;
|
||||||
|
reg internal_valid;
|
||||||
|
wire [VALID_WIDTH-1:0] wide_valid;
|
||||||
|
|
||||||
|
assign { stage2_data,
|
||||||
|
stage2_channel,
|
||||||
|
stage2_startofpacket,
|
||||||
|
stage2_endofpacket,
|
||||||
|
stage2_dest_changed,
|
||||||
|
stage2_trans_changed } = stage2_payload;
|
||||||
|
|
||||||
|
generate if (PREVENT_HAZARDS == 1) begin : stage2_nonposted_block
|
||||||
|
assign nonposted_cmd = 1'b1;
|
||||||
|
end else begin
|
||||||
|
assign nonposted_cmd = (stage2_data[PKT_TRANS_POSTED] == 0);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign nonposted_cmd_accepted = nonposted_cmd && internal_valid && (cmd_src_ready && cmd_src_endofpacket);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Use the sink's control signals here, because write responses may be dropped
|
||||||
|
// when hazard prevention is on.
|
||||||
|
//
|
||||||
|
// When case REORDER, move all side to rsp_source as all packets from rsp_sink will
|
||||||
|
// go in the reorder memory.
|
||||||
|
// One special case when PREVENT_HAZARD is on, need to use reorder_memory_valid
|
||||||
|
// as the rsp_source will drop
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
assign response_sink_accepted = rsp_sink_valid && rsp_sink_ready && rsp_sink_endofpacket;
|
||||||
|
// Avoid Qis warning when incase, no REORDER, the signal reorder_mem_valid is not in used.
|
||||||
|
wire reorder_mem_out_valid;
|
||||||
|
wire reorder_mem_valid;
|
||||||
|
generate
|
||||||
|
if (REORDER) begin
|
||||||
|
assign reorder_mem_out_valid = reorder_mem_valid;
|
||||||
|
end else begin
|
||||||
|
assign reorder_mem_out_valid = '0;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign response_src_accepted = reorder_mem_out_valid & rsp_src_ready & rsp_src_endofpacket;
|
||||||
|
assign response_accepted = (REORDER == 1) ? response_src_accepted : response_sink_accepted;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
next_pending_response_count = pending_response_count;
|
||||||
|
|
||||||
|
if (nonposted_cmd_accepted)
|
||||||
|
next_pending_response_count = pending_response_count + 1'b1;
|
||||||
|
if (response_accepted)
|
||||||
|
next_pending_response_count = pending_response_count - 1'b1;
|
||||||
|
if (nonposted_cmd_accepted && response_accepted)
|
||||||
|
next_pending_response_count = pending_response_count;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign count_is_1 = (pending_response_count == 1);
|
||||||
|
assign count_is_0 = (pending_response_count == 0);
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
// count_max_reached : count if maximum command reach to backpressure
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
reg count_max_reached;
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
pending_response_count <= 0;
|
||||||
|
has_pending_responses <= 0;
|
||||||
|
count_max_reached <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
pending_response_count <= next_pending_response_count;
|
||||||
|
// synthesis translate_off
|
||||||
|
if (count_is_0 && response_accepted)
|
||||||
|
$display("%t: %m: Error: unexpected response: pending_response_count underflow", $time());
|
||||||
|
// synthesis translate_on
|
||||||
|
has_pending_responses <= has_pending_responses
|
||||||
|
&& ~(count_is_1 && response_accepted && ~nonposted_cmd_accepted)
|
||||||
|
|| (count_is_0 && nonposted_cmd_accepted && ~response_accepted);
|
||||||
|
count_max_reached <= (next_pending_response_count == MAX_OUTSTANDING_RESPONSES);
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
wire suppress_prevent_harzard_for_particular_destid;
|
||||||
|
wire this_destid_trans_changed;
|
||||||
|
genvar j;
|
||||||
|
generate
|
||||||
|
if (REORDER) begin: fifo_dest_id_write_read_control_reorder_on
|
||||||
|
wire [COUNTER_W - 1 : 0] current_trans_seq_of_this_destid;
|
||||||
|
wire [MAX_DEST_ID - 1 : 0] current_trans_seq_of_this_destid_valid;
|
||||||
|
wire [MAX_DEST_ID - 1 : 0] responses_arrived;
|
||||||
|
reg [COUNTER_W - 1:0] trans_sequence;
|
||||||
|
wire [MAX_DEST_ID - 1 : 0] trans_sequence_we;
|
||||||
|
|
||||||
|
wire [COUNTER_W : 0] trans_sequence_plus_trans_type;
|
||||||
|
wire current_trans_type_of_this_destid;
|
||||||
|
wire [COUNTER_W : 0] current_trans_seq_of_this_destid_plus_trans_type [MAX_DEST_ID];
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Control write trans_sequence to fifos
|
||||||
|
//
|
||||||
|
// 1. when command accepted, read destid from command packet,
|
||||||
|
// write this id to the fifo (each fifo for each desitid)
|
||||||
|
// 2. when response acepted, read the destid from response packet,
|
||||||
|
// will know which sequence of this response, write it to
|
||||||
|
// correct segment in memory.
|
||||||
|
// what if two commands go to same slave, the two sequences
|
||||||
|
// go time same fifo, this even helps us to maintain order
|
||||||
|
// when two commands same thread to one slave.
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
wire [DEST_ID_W - 1 : 0] rsp_sink_dest_id;
|
||||||
|
wire [DEST_ID_W - 1 : 0] cmd_dest_id;
|
||||||
|
assign rsp_sink_dest_id = rsp_sink_data[PKT_SRC_ID_H : PKT_SRC_ID_L];
|
||||||
|
|
||||||
|
// write in fifo the trans_sequence and type of transaction
|
||||||
|
assign trans_sequence_plus_trans_type = {stage2_data[PKT_TRANS_WRITE], trans_sequence};
|
||||||
|
|
||||||
|
// read the cmd_dest_id from output of pipeline stage so that either
|
||||||
|
// or not, it wont affect how we write to fifo
|
||||||
|
assign cmd_dest_id = stage2_data[PKT_DEST_ID_H : PKT_DEST_ID_L];
|
||||||
|
// -------------------------------------
|
||||||
|
// Get the transaction_seq for that dest_id
|
||||||
|
// -------------------------------------
|
||||||
|
wire [COUNTER_W - 1: 0] trans_sequence_rsp;
|
||||||
|
wire [COUNTER_W : 0] trans_sequence_rsp_plus_trans_type;
|
||||||
|
wire [COUNTER_W - 1: 0] trans_sequence_rsp_this_destid_waiting;
|
||||||
|
wire [COUNTER_W : 0] sequence_and_trans_type_this_destid_waiting;
|
||||||
|
wire trans_sequence_rsp_this_destid_waiting_valid;
|
||||||
|
assign trans_sequence_rsp_plus_trans_type = current_trans_seq_of_this_destid_plus_trans_type[rsp_sink_dest_id];
|
||||||
|
assign trans_sequence_rsp = trans_sequence_rsp_plus_trans_type[COUNTER_W - 1: 0];
|
||||||
|
|
||||||
|
// do I need to check if this fifo is valid, it should be always valid, unless a command not yet sent
|
||||||
|
// and response comes back which means something weird happens.
|
||||||
|
// It is worth to do an assertion but now to avoid QIS warning, just do as normal ST handshaking
|
||||||
|
// check valid and ready
|
||||||
|
|
||||||
|
for (j = 0; j < MAX_DEST_ID; j = j+1)
|
||||||
|
begin : write_and_read_trans_sequence
|
||||||
|
assign trans_sequence_we[j] = (cmd_dest_id == j) && nonposted_cmd_accepted;
|
||||||
|
assign responses_arrived[j] = (rsp_sink_dest_id == j) && response_sink_accepted;
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// This is array of fifos, which will be created base on how many slaves
|
||||||
|
// that this master can see (max dest_id_width)
|
||||||
|
// Each fifo, will store the trans_sequence, which go to that slave
|
||||||
|
// On the response path, based in the response from which slave
|
||||||
|
// the fifo of that slave will be read, to check the sequences.
|
||||||
|
// and this sequence is the write address to the memory
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
|
// There are 3 sequences run around the limiter, they have a relationship
|
||||||
|
// And this is how the key point of reorder work:
|
||||||
|
//
|
||||||
|
// trans_sequence : command sequence, each command go thru the limiter
|
||||||
|
// will have a sequence to show their order. A simple
|
||||||
|
// counter from 0 go up and repeat.
|
||||||
|
// trans_sequence_rsp : response sequence, each response that go back to limiter,
|
||||||
|
// will be read from trans_fifos to know their sequence.
|
||||||
|
// expect_trans_sequence : Expected sequences for response that the master is waiting
|
||||||
|
// The limiter will hold this sequence and wait until exactly response
|
||||||
|
// for this sequence come back (trans_sequence_rsp)
|
||||||
|
// aka: if trans_sequence_rsp back is same as expect_trans_sequence
|
||||||
|
// then it is correct order, else response store in memory and
|
||||||
|
// send out to master later, when expect_trans_sequence match.
|
||||||
|
// ------------------------------------------------------------------------------------
|
||||||
|
for (j = 0;j < MAX_DEST_ID; j = j+1) begin : trans_sequence_per_fifo
|
||||||
|
altera_avalon_sc_fifo
|
||||||
|
#(
|
||||||
|
.SYMBOLS_PER_BEAT (1),
|
||||||
|
.BITS_PER_SYMBOL (COUNTER_W + 1), // one bit extra to store type of transaction
|
||||||
|
.FIFO_DEPTH (MAX_OUTSTANDING_RESPONSES),
|
||||||
|
.CHANNEL_WIDTH (0),
|
||||||
|
.ERROR_WIDTH (0),
|
||||||
|
.USE_PACKETS (0),
|
||||||
|
.USE_FILL_LEVEL (0),
|
||||||
|
.EMPTY_LATENCY (1),
|
||||||
|
.USE_MEMORY_BLOCKS (0),
|
||||||
|
.USE_STORE_FORWARD (0),
|
||||||
|
.USE_ALMOST_FULL_IF (0),
|
||||||
|
.USE_ALMOST_EMPTY_IF (0)
|
||||||
|
) dest_id_fifo
|
||||||
|
(
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.in_data (trans_sequence_plus_trans_type),
|
||||||
|
.in_valid (trans_sequence_we[j]),
|
||||||
|
.in_ready (),
|
||||||
|
.out_data (current_trans_seq_of_this_destid_plus_trans_type[j]),
|
||||||
|
.out_valid (current_trans_seq_of_this_destid_valid[j]),
|
||||||
|
.out_ready (responses_arrived[j]),
|
||||||
|
.csr_address (2'b00), // (terminated)
|
||||||
|
.csr_read (1'b0), // (terminated)
|
||||||
|
.csr_write (1'b0), // (terminated)
|
||||||
|
.csr_readdata (), // (terminated)
|
||||||
|
.csr_writedata (32'b00000000000000000000000000000000), // (terminated)
|
||||||
|
.almost_full_data (), // (terminated)
|
||||||
|
.almost_empty_data (), // (terminated)
|
||||||
|
.in_startofpacket (1'b0), // (terminated)
|
||||||
|
.in_endofpacket (1'b0), // (terminated)
|
||||||
|
.out_startofpacket (), // (terminated)
|
||||||
|
.out_endofpacket (), // (terminated)
|
||||||
|
.in_empty (1'b0), // (terminated)
|
||||||
|
.out_empty (), // (terminated)
|
||||||
|
.in_error (1'b0), // (terminated)
|
||||||
|
.out_error (), // (terminated)
|
||||||
|
.in_channel (1'b0), // (terminated)
|
||||||
|
.out_channel () // (terminated)
|
||||||
|
);
|
||||||
|
end // block: trans_sequence_per_fifo
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Calculate the transaction sequence, just simple increase
|
||||||
|
// when each commands pass by
|
||||||
|
// --------------------------------------------------------
|
||||||
|
always @(posedge clk or posedge reset)
|
||||||
|
begin
|
||||||
|
if (reset) begin
|
||||||
|
trans_sequence <= '0;
|
||||||
|
end else begin
|
||||||
|
if (nonposted_cmd_accepted)
|
||||||
|
trans_sequence <= ( (trans_sequence + 1'b1) == MAX_OUTSTANDING_RESPONSES) ? '0 : trans_sequence + 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Control Memory for reorder responses
|
||||||
|
// -------------------------------------
|
||||||
|
wire [COUNTER_W - 1 : 0] next_rd_trans_sequence;
|
||||||
|
reg [COUNTER_W - 1 : 0] rd_trans_sequence;
|
||||||
|
reg [COUNTER_W - 1 : 0] next_expected_trans_sequence;
|
||||||
|
reg [COUNTER_W - 1 : 0] expect_trans_sequence;
|
||||||
|
wire [ST_DATA_W - 1 : 0] reorder_mem_data;
|
||||||
|
wire [ST_CHANNEL_W - 1 : 0] reorder_mem_channel;
|
||||||
|
wire reorder_mem_startofpacket;
|
||||||
|
wire reorder_mem_endofpacket;
|
||||||
|
wire reorder_mem_ready;
|
||||||
|
// -------------------------------------------
|
||||||
|
// Data to write and read from reorder memory
|
||||||
|
// Store everything includes channel, sop, eop
|
||||||
|
// -------------------------------------------
|
||||||
|
reg [MEM_W - 1 : 0] mem_in_rsp_sink_data;
|
||||||
|
reg [MEM_W - 1 : 0] reorder_mem_out_data;
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
mem_in_rsp_sink_data = {rsp_sink_data, rsp_sink_channel, rsp_sink_startofpacket, rsp_sink_endofpacket};
|
||||||
|
end
|
||||||
|
|
||||||
|
assign next_rd_trans_sequence = ((rd_trans_sequence + 1'b1) == MAX_OUTSTANDING_RESPONSES) ? '0 : rd_trans_sequence + 1'b1;
|
||||||
|
assign next_expected_trans_sequence = ((expect_trans_sequence + 1'b1) == MAX_OUTSTANDING_RESPONSES) ? '0 : expect_trans_sequence + 1'b1;
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset)
|
||||||
|
begin
|
||||||
|
if (reset) begin
|
||||||
|
rd_trans_sequence <= '0;
|
||||||
|
expect_trans_sequence <= '0;
|
||||||
|
end else begin
|
||||||
|
if (rsp_src_ready && reorder_mem_valid) begin
|
||||||
|
if (reorder_mem_endofpacket == 1) begin //endofpacket
|
||||||
|
expect_trans_sequence <= next_expected_trans_sequence;
|
||||||
|
rd_trans_sequence <= next_rd_trans_sequence;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end // always_ff @
|
||||||
|
|
||||||
|
// For PREVENT_HAZARD,
|
||||||
|
// Case: Master Write to S0, read S1, and Read S0 back but if Write for S0
|
||||||
|
// not yet return then we need to backpressure this, else read S0 might take over write
|
||||||
|
// This is more checking after the fifo destid, as read S1 is inserted in midle
|
||||||
|
// when see new packet, try to look at the fifo for that slave id, check if it
|
||||||
|
// type of transaction
|
||||||
|
assign sequence_and_trans_type_this_destid_waiting = current_trans_seq_of_this_destid_plus_trans_type[cmd_dest_id];
|
||||||
|
assign current_trans_type_of_this_destid = sequence_and_trans_type_this_destid_waiting[COUNTER_W];
|
||||||
|
assign trans_sequence_rsp_this_destid_waiting_valid = current_trans_seq_of_this_destid_valid[cmd_dest_id];
|
||||||
|
// it might waiting other sequence, check if different type of transaction as only for PREVENT HAZARD
|
||||||
|
// if comming comamnd to one slave and this slave is still waiting for response from previous command
|
||||||
|
// which has diiferent type of transaction, we back-pressure this command to avoid HAZARD
|
||||||
|
assign suppress_prevent_harzard_for_particular_destid = (current_trans_type_of_this_destid != is_write) & trans_sequence_rsp_this_destid_waiting_valid;
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Memory for reorder buffer
|
||||||
|
// -------------------------------------
|
||||||
|
altera_merlin_reorder_memory
|
||||||
|
#(
|
||||||
|
.DATA_W (MEM_W),
|
||||||
|
.ADDR_H_W (COUNTER_W),
|
||||||
|
.ADDR_L_W (MAX_BURST_LENGTH),
|
||||||
|
.NUM_SEGMENT (MAX_OUTSTANDING_RESPONSES),
|
||||||
|
.DEPTH (MEM_DEPTH)
|
||||||
|
) reorder_memory
|
||||||
|
(
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.in_data (mem_in_rsp_sink_data),
|
||||||
|
.in_valid (rsp_sink_valid),
|
||||||
|
.in_ready (reorder_mem_ready),
|
||||||
|
.out_data (reorder_mem_out_data),
|
||||||
|
.out_valid (reorder_mem_valid),
|
||||||
|
.out_ready (rsp_src_ready),
|
||||||
|
.wr_segment (trans_sequence_rsp),
|
||||||
|
.rd_segment (expect_trans_sequence)
|
||||||
|
);
|
||||||
|
// -------------------------------------
|
||||||
|
// Output from reorder buffer
|
||||||
|
// -------------------------------------
|
||||||
|
assign reorder_mem_data = reorder_mem_out_data[MEM_W -1 : ST_CHANNEL_W + 2];
|
||||||
|
assign reorder_mem_channel = reorder_mem_out_data[ST_CHANNEL_W + 2 - 1 : 2];
|
||||||
|
assign reorder_mem_startofpacket = reorder_mem_out_data[1];
|
||||||
|
assign reorder_mem_endofpacket = reorder_mem_out_data[0];
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Because use generate statment
|
||||||
|
// so move all rsp_src_xxx controls here
|
||||||
|
// -------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
cmd_src_data = stage2_data;
|
||||||
|
rsp_src_valid = reorder_mem_valid;
|
||||||
|
rsp_src_data = reorder_mem_data;
|
||||||
|
rsp_src_channel = reorder_mem_channel;
|
||||||
|
rsp_src_startofpacket = reorder_mem_startofpacket;
|
||||||
|
rsp_src_endofpacket = reorder_mem_endofpacket;
|
||||||
|
// -------------------------------------
|
||||||
|
// Forces commands to be non-posted if hazard prevention
|
||||||
|
// is on, also drops write responses
|
||||||
|
// -------------------------------------
|
||||||
|
rsp_sink_ready = reorder_mem_ready; // now it takes ready signal from the memory not direct from master
|
||||||
|
if (PREVENT_HAZARDS == 1) begin
|
||||||
|
cmd_src_data[PKT_TRANS_POSTED] = 1'b0;
|
||||||
|
|
||||||
|
if (rsp_src_data[PKT_TRANS_WRITE] == 1'b1 && SUPPORTS_POSTED_WRITES == 1 && SUPPORTS_NONPOSTED_WRITES == 0) begin
|
||||||
|
rsp_src_valid = 1'b0;
|
||||||
|
rsp_sink_ready = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end // always_comb
|
||||||
|
|
||||||
|
end // block: fifo_dest_id_write_read_control_reorder_on
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Pass-through command and response
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
always_comb
|
||||||
|
begin
|
||||||
|
cmd_src_channel = stage2_channel;
|
||||||
|
cmd_src_startofpacket = stage2_startofpacket;
|
||||||
|
cmd_src_endofpacket = stage2_endofpacket;
|
||||||
|
end // always_comb
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// When there is no REORDER requirement
|
||||||
|
// Just pass through signals
|
||||||
|
// -------------------------------------
|
||||||
|
generate
|
||||||
|
if (!REORDER) begin : use_selector_or_pass_thru_rsp
|
||||||
|
always_comb begin
|
||||||
|
cmd_src_data = stage2_data;
|
||||||
|
// pass thru almost signals
|
||||||
|
rsp_src_valid = rsp_sink_valid;
|
||||||
|
rsp_src_data = rsp_sink_data;
|
||||||
|
rsp_src_channel = rsp_sink_channel;
|
||||||
|
rsp_src_startofpacket = rsp_sink_startofpacket;
|
||||||
|
rsp_src_endofpacket = rsp_sink_endofpacket;
|
||||||
|
// -------------------------------------
|
||||||
|
// Forces commands to be non-posted if hazard prevention
|
||||||
|
// is on, also drops write responses
|
||||||
|
// -------------------------------------
|
||||||
|
rsp_sink_ready = rsp_src_ready; // take care this, should check memory empty
|
||||||
|
if (PREVENT_HAZARDS == 1) begin
|
||||||
|
cmd_src_data[PKT_TRANS_POSTED] = 1'b0;
|
||||||
|
|
||||||
|
if (rsp_sink_data[PKT_TRANS_WRITE] == 1'b1 && SUPPORTS_POSTED_WRITES == 1 && SUPPORTS_NONPOSTED_WRITES == 0) begin
|
||||||
|
rsp_src_valid = 1'b0;
|
||||||
|
rsp_sink_ready = 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end // always_comb
|
||||||
|
end // if (!REORDER)
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// Backpressure & Suppression
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// ENFORCE_ORDER: unused option, always is 1, remove it
|
||||||
|
// Now the limiter will suppress when max_outstanding reach
|
||||||
|
// --------------------------------------------------------
|
||||||
|
generate
|
||||||
|
if (ENFORCE_ORDER) begin : enforce_order_block
|
||||||
|
assign suppress_change_dest_id = (REORDER == 1) ? 1'b0 : nonposted_cmd && has_pending_responses &&
|
||||||
|
(stage2_dest_changed || (PREVENT_HAZARDS == 1 && stage2_trans_changed));
|
||||||
|
end else begin : no_order_block
|
||||||
|
assign suppress_change_dest_id = 1'b0;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
// Even we allow change slave while still have pending responses
|
||||||
|
// But one special case, when PREVENT_HAZARD=1, we still allow
|
||||||
|
// switch slave while type of transaction change (RAW, WAR) but
|
||||||
|
// only to different slaves.
|
||||||
|
// if to same slave, we still need back pressure that to make
|
||||||
|
// sure no racing
|
||||||
|
// ------------------------------------------------------------
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (REORDER) begin : prevent_hazard_block
|
||||||
|
assign suppress_change_trans_but_not_dest = nonposted_cmd && has_pending_responses &&
|
||||||
|
!stage2_dest_changed && (PREVENT_HAZARDS == 1 && stage2_trans_changed);
|
||||||
|
end else begin : no_hazard_block
|
||||||
|
assign suppress_change_trans_but_not_dest = 1'b0; // no REORDER, the suppress_changes_destid take care of this.
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (REORDER) begin : prevent_hazard_block_for_particular_slave
|
||||||
|
assign suppress_change_trans_for_one_slave = nonposted_cmd && has_pending_responses && (PREVENT_HAZARDS == 1 && suppress_prevent_harzard_for_particular_destid);
|
||||||
|
end else begin : no_hazard_block_for_particular_slave
|
||||||
|
assign suppress_change_trans_for_one_slave = 1'b0; // no REORDER, the suppress_changes_destid take care of this.
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Backpressure when max outstanding transactions are reached
|
||||||
|
// ------------------------------------------
|
||||||
|
generate
|
||||||
|
if (REORDER) begin : max_outstanding_block
|
||||||
|
assign suppress_max_outstanding = count_max_reached;
|
||||||
|
end else begin
|
||||||
|
assign suppress_max_outstanding = 1'b0;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign suppress = suppress_change_trans_for_one_slave | suppress_change_dest_id | suppress_max_outstanding;
|
||||||
|
assign wide_valid = { VALID_WIDTH {stage2_valid} } & stage2_channel;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
stage2_ready = cmd_src_ready;
|
||||||
|
internal_valid = stage2_valid;
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// change suppress condidtion, in case REODER it will alllow changing slave
|
||||||
|
// even still have pending transactions.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
if (suppress) begin
|
||||||
|
stage2_ready = 0;
|
||||||
|
internal_valid = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (VALID_WIDTH == 1) begin
|
||||||
|
cmd_src_valid = {VALID_WIDTH{1'b0}};
|
||||||
|
cmd_src_valid[0] = internal_valid;
|
||||||
|
end else begin
|
||||||
|
// -------------------------------------
|
||||||
|
// Use the one-hot channel to determine if the destination
|
||||||
|
// has changed. This results in a wide valid bus
|
||||||
|
// -------------------------------------
|
||||||
|
cmd_src_valid = wide_valid;
|
||||||
|
if (nonposted_cmd & has_pending_responses) begin
|
||||||
|
if (!REORDER) begin
|
||||||
|
cmd_src_valid = wide_valid & last_channel;
|
||||||
|
// -------------------------------------
|
||||||
|
// Mask the valid signals if the transaction type has changed
|
||||||
|
// if hazard prevention is enabled
|
||||||
|
// -------------------------------------
|
||||||
|
if (PREVENT_HAZARDS == 1)
|
||||||
|
cmd_src_valid = wide_valid & last_channel & { VALID_WIDTH {!stage2_trans_changed} };
|
||||||
|
end else begin // else: !if(!REORDER) if REORDER happen
|
||||||
|
if (PREVENT_HAZARDS == 1)
|
||||||
|
cmd_src_valid = wide_valid & { VALID_WIDTH {!suppress_change_trans_for_one_slave} };
|
||||||
|
if (suppress_max_outstanding) begin
|
||||||
|
cmd_src_valid = {VALID_WIDTH {1'b0}};
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Calculates the log2ceil of the input value.
|
||||||
|
//
|
||||||
|
// This function occurs a lot... please refactor.
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input integer val;
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
1206
ip/altera/ddr3/altera_merlin_width_adapter.sv
Normal file
1206
ip/altera/ddr3/altera_merlin_width_adapter.sv
Normal file
File diff suppressed because it is too large
Load Diff
30
ip/altera/ddr3/altera_reset_controller.sdc
Normal file
30
ip/altera/ddr3/altera_reset_controller.sdc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
# +---------------------------------------------------
|
||||||
|
# | Cut the async clear paths
|
||||||
|
# +---------------------------------------------------
|
||||||
|
set aclr_counter 0
|
||||||
|
set clrn_counter 0
|
||||||
|
set aclr_collection [get_pins -compatibility_mode -nocase -nowarn *|alt_rst_sync_uq1|altera_reset_synchronizer_int_chain*|aclr]
|
||||||
|
set clrn_collection [get_pins -compatibility_mode -nocase -nowarn *|alt_rst_sync_uq1|altera_reset_synchronizer_int_chain*|clrn]
|
||||||
|
set aclr_counter [get_collection_size $aclr_collection]
|
||||||
|
set clrn_counter [get_collection_size $clrn_collection]
|
||||||
|
|
||||||
|
if {$aclr_counter > 0} {
|
||||||
|
set_false_path -to [get_pins -compatibility_mode -nocase *|alt_rst_sync_uq1|altera_reset_synchronizer_int_chain*|aclr]
|
||||||
|
}
|
||||||
|
|
||||||
|
if {$clrn_counter > 0} {
|
||||||
|
set_false_path -to [get_pins -compatibility_mode -nocase *|alt_rst_sync_uq1|altera_reset_synchronizer_int_chain*|clrn]
|
||||||
|
}
|
319
ip/altera/ddr3/altera_reset_controller.v
Normal file
319
ip/altera/ddr3/altera_reset_controller.v
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2013 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_reset_controller/altera_reset_controller.v#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Reset controller
|
||||||
|
//
|
||||||
|
// Combines all the input resets and synchronizes
|
||||||
|
// the result to the clk.
|
||||||
|
// ACDS13.1 - Added reset request as part of reset sequencing
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_reset_controller
|
||||||
|
#(
|
||||||
|
parameter NUM_RESET_INPUTS = 6,
|
||||||
|
parameter USE_RESET_REQUEST_IN0 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN1 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN2 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN3 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN4 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN5 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN6 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN7 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN8 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN9 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN10 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN11 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN12 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN13 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN14 = 0,
|
||||||
|
parameter USE_RESET_REQUEST_IN15 = 0,
|
||||||
|
parameter OUTPUT_RESET_SYNC_EDGES = "deassert",
|
||||||
|
parameter SYNC_DEPTH = 2,
|
||||||
|
parameter RESET_REQUEST_PRESENT = 0,
|
||||||
|
parameter RESET_REQ_WAIT_TIME = 3,
|
||||||
|
parameter MIN_RST_ASSERTION_TIME = 11,
|
||||||
|
parameter RESET_REQ_EARLY_DSRT_TIME = 4,
|
||||||
|
parameter ADAPT_RESET_REQUEST = 0
|
||||||
|
)
|
||||||
|
(
|
||||||
|
// --------------------------------------
|
||||||
|
// We support up to 16 reset inputs, for now
|
||||||
|
// --------------------------------------
|
||||||
|
input reset_in0,
|
||||||
|
input reset_in1,
|
||||||
|
input reset_in2,
|
||||||
|
input reset_in3,
|
||||||
|
input reset_in4,
|
||||||
|
input reset_in5,
|
||||||
|
input reset_in6,
|
||||||
|
input reset_in7,
|
||||||
|
input reset_in8,
|
||||||
|
input reset_in9,
|
||||||
|
input reset_in10,
|
||||||
|
input reset_in11,
|
||||||
|
input reset_in12,
|
||||||
|
input reset_in13,
|
||||||
|
input reset_in14,
|
||||||
|
input reset_in15,
|
||||||
|
input reset_req_in0,
|
||||||
|
input reset_req_in1,
|
||||||
|
input reset_req_in2,
|
||||||
|
input reset_req_in3,
|
||||||
|
input reset_req_in4,
|
||||||
|
input reset_req_in5,
|
||||||
|
input reset_req_in6,
|
||||||
|
input reset_req_in7,
|
||||||
|
input reset_req_in8,
|
||||||
|
input reset_req_in9,
|
||||||
|
input reset_req_in10,
|
||||||
|
input reset_req_in11,
|
||||||
|
input reset_req_in12,
|
||||||
|
input reset_req_in13,
|
||||||
|
input reset_req_in14,
|
||||||
|
input reset_req_in15,
|
||||||
|
|
||||||
|
|
||||||
|
input clk,
|
||||||
|
output reg reset_out,
|
||||||
|
output reg reset_req
|
||||||
|
);
|
||||||
|
|
||||||
|
// Always use async reset synchronizer if reset_req is used
|
||||||
|
localparam ASYNC_RESET = (OUTPUT_RESET_SYNC_EDGES == "deassert");
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// Local parameter to control the reset_req and reset_out timing when RESET_REQUEST_PRESENT==1
|
||||||
|
// --------------------------------------
|
||||||
|
localparam MIN_METASTABLE = 3;
|
||||||
|
localparam RSTREQ_ASRT_SYNC_TAP = MIN_METASTABLE + RESET_REQ_WAIT_TIME;
|
||||||
|
|
||||||
|
localparam LARGER = RESET_REQ_WAIT_TIME > RESET_REQ_EARLY_DSRT_TIME ? RESET_REQ_WAIT_TIME : RESET_REQ_EARLY_DSRT_TIME;
|
||||||
|
|
||||||
|
localparam ASSERTION_CHAIN_LENGTH = (MIN_METASTABLE > LARGER) ?
|
||||||
|
MIN_RST_ASSERTION_TIME + 1 :
|
||||||
|
(
|
||||||
|
(MIN_RST_ASSERTION_TIME > LARGER)?
|
||||||
|
MIN_RST_ASSERTION_TIME + (LARGER - MIN_METASTABLE + 1) + 1 :
|
||||||
|
MIN_RST_ASSERTION_TIME + RESET_REQ_EARLY_DSRT_TIME + RESET_REQ_WAIT_TIME - MIN_METASTABLE + 2
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam RESET_REQ_DRST_TAP = RESET_REQ_EARLY_DSRT_TIME + 1;
|
||||||
|
// --------------------------------------
|
||||||
|
|
||||||
|
wire merged_reset;
|
||||||
|
wire merged_reset_req_in;
|
||||||
|
wire reset_out_pre;
|
||||||
|
wire reset_req_pre;
|
||||||
|
|
||||||
|
// Registers and Interconnect
|
||||||
|
(*preserve*) reg [RSTREQ_ASRT_SYNC_TAP: 0] altera_reset_synchronizer_int_chain;
|
||||||
|
reg [ASSERTION_CHAIN_LENGTH-1: 0] r_sync_rst_chain;
|
||||||
|
reg r_sync_rst;
|
||||||
|
reg r_early_rst;
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// "Or" all the input resets together
|
||||||
|
// --------------------------------------
|
||||||
|
assign merged_reset = (
|
||||||
|
reset_in0 |
|
||||||
|
reset_in1 |
|
||||||
|
reset_in2 |
|
||||||
|
reset_in3 |
|
||||||
|
reset_in4 |
|
||||||
|
reset_in5 |
|
||||||
|
reset_in6 |
|
||||||
|
reset_in7 |
|
||||||
|
reset_in8 |
|
||||||
|
reset_in9 |
|
||||||
|
reset_in10 |
|
||||||
|
reset_in11 |
|
||||||
|
reset_in12 |
|
||||||
|
reset_in13 |
|
||||||
|
reset_in14 |
|
||||||
|
reset_in15
|
||||||
|
);
|
||||||
|
|
||||||
|
assign merged_reset_req_in = (
|
||||||
|
( (USE_RESET_REQUEST_IN0 == 1) ? reset_req_in0 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN1 == 1) ? reset_req_in1 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN2 == 1) ? reset_req_in2 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN3 == 1) ? reset_req_in3 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN4 == 1) ? reset_req_in4 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN5 == 1) ? reset_req_in5 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN6 == 1) ? reset_req_in6 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN7 == 1) ? reset_req_in7 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN8 == 1) ? reset_req_in8 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN9 == 1) ? reset_req_in9 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN10 == 1) ? reset_req_in10 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN11 == 1) ? reset_req_in11 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN12 == 1) ? reset_req_in12 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN13 == 1) ? reset_req_in13 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN14 == 1) ? reset_req_in14 : 1'b0) |
|
||||||
|
( (USE_RESET_REQUEST_IN15 == 1) ? reset_req_in15 : 1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------
|
||||||
|
// And if required, synchronize it to the required clock domain,
|
||||||
|
// with the correct synchronization type
|
||||||
|
// --------------------------------------
|
||||||
|
generate if (OUTPUT_RESET_SYNC_EDGES == "none" && (RESET_REQUEST_PRESENT==0)) begin
|
||||||
|
|
||||||
|
assign reset_out_pre = merged_reset;
|
||||||
|
assign reset_req_pre = merged_reset_req_in;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
altera_reset_synchronizer
|
||||||
|
#(
|
||||||
|
.DEPTH (SYNC_DEPTH),
|
||||||
|
.ASYNC_RESET(RESET_REQUEST_PRESENT? 1'b1 : ASYNC_RESET)
|
||||||
|
)
|
||||||
|
alt_rst_sync_uq1
|
||||||
|
(
|
||||||
|
.clk (clk),
|
||||||
|
.reset_in (merged_reset),
|
||||||
|
.reset_out (reset_out_pre)
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_reset_synchronizer
|
||||||
|
#(
|
||||||
|
.DEPTH (SYNC_DEPTH),
|
||||||
|
.ASYNC_RESET(0)
|
||||||
|
)
|
||||||
|
alt_rst_req_sync_uq1
|
||||||
|
(
|
||||||
|
.clk (clk),
|
||||||
|
.reset_in (merged_reset_req_in),
|
||||||
|
.reset_out (reset_req_pre)
|
||||||
|
);
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate if ( ( (RESET_REQUEST_PRESENT == 0) && (ADAPT_RESET_REQUEST==0) )|
|
||||||
|
( (ADAPT_RESET_REQUEST == 1) && (OUTPUT_RESET_SYNC_EDGES != "deassert") ) ) begin
|
||||||
|
always @* begin
|
||||||
|
reset_out = reset_out_pre;
|
||||||
|
reset_req = reset_req_pre;
|
||||||
|
end
|
||||||
|
end else if ( (RESET_REQUEST_PRESENT == 0) && (ADAPT_RESET_REQUEST==1) ) begin
|
||||||
|
|
||||||
|
wire reset_out_pre2;
|
||||||
|
|
||||||
|
altera_reset_synchronizer
|
||||||
|
#(
|
||||||
|
.DEPTH (SYNC_DEPTH+1),
|
||||||
|
.ASYNC_RESET(0)
|
||||||
|
)
|
||||||
|
alt_rst_sync_uq2
|
||||||
|
(
|
||||||
|
.clk (clk),
|
||||||
|
.reset_in (reset_out_pre),
|
||||||
|
.reset_out (reset_out_pre2)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
reset_out = reset_out_pre2;
|
||||||
|
reset_req = reset_req_pre;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
|
||||||
|
// 3-FF Metastability Synchronizer
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
altera_reset_synchronizer_int_chain <= {RSTREQ_ASRT_SYNC_TAP{1'b1}};
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
altera_reset_synchronizer_int_chain[RSTREQ_ASRT_SYNC_TAP:0] <=
|
||||||
|
{altera_reset_synchronizer_int_chain[RSTREQ_ASRT_SYNC_TAP-1:0], reset_out_pre};
|
||||||
|
end
|
||||||
|
|
||||||
|
// Synchronous reset pipe
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
r_sync_rst_chain <= {ASSERTION_CHAIN_LENGTH{1'b1}};
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (altera_reset_synchronizer_int_chain[MIN_METASTABLE-1] == 1'b1)
|
||||||
|
begin
|
||||||
|
r_sync_rst_chain <= {ASSERTION_CHAIN_LENGTH{1'b1}};
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
r_sync_rst_chain <= {1'b0, r_sync_rst_chain[ASSERTION_CHAIN_LENGTH-1:1]};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Standard synchronous reset output. From 0-1, the transition lags the early output. For 1->0, the transition
|
||||||
|
// matches the early input.
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
case ({altera_reset_synchronizer_int_chain[RSTREQ_ASRT_SYNC_TAP], r_sync_rst_chain[1], r_sync_rst})
|
||||||
|
3'b000: r_sync_rst <= 1'b0; // Not reset
|
||||||
|
3'b001: r_sync_rst <= 1'b0;
|
||||||
|
3'b010: r_sync_rst <= 1'b0;
|
||||||
|
3'b011: r_sync_rst <= 1'b1;
|
||||||
|
3'b100: r_sync_rst <= 1'b1;
|
||||||
|
3'b101: r_sync_rst <= 1'b1;
|
||||||
|
3'b110: r_sync_rst <= 1'b1;
|
||||||
|
3'b111: r_sync_rst <= 1'b1; // In Reset
|
||||||
|
default: r_sync_rst <= 1'b1;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
case ({r_sync_rst_chain[1], r_sync_rst_chain[RESET_REQ_DRST_TAP] | reset_req_pre})
|
||||||
|
2'b00: r_early_rst <= 1'b0; // Not reset
|
||||||
|
2'b01: r_early_rst <= 1'b1; // Coming out of reset
|
||||||
|
2'b10: r_early_rst <= 1'b0; // Spurious reset - should not be possible via synchronous design.
|
||||||
|
2'b11: r_early_rst <= 1'b1; // Held in reset
|
||||||
|
default: r_early_rst <= 1'b1;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
reset_out = r_sync_rst;
|
||||||
|
reset_req = r_early_rst;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
87
ip/altera/ddr3/altera_reset_synchronizer.v
Normal file
87
ip/altera/ddr3/altera_reset_synchronizer.v
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_reset_controller/altera_reset_synchronizer.v#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// Reset Synchronizer
|
||||||
|
// -----------------------------------------------
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_reset_synchronizer
|
||||||
|
#(
|
||||||
|
parameter ASYNC_RESET = 1,
|
||||||
|
parameter DEPTH = 2
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input reset_in /* synthesis ALTERA_ATTRIBUTE = "SUPPRESS_DA_RULE_INTERNAL=R101" */,
|
||||||
|
|
||||||
|
input clk,
|
||||||
|
output reset_out
|
||||||
|
);
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// Synchronizer register chain. We cannot reuse the
|
||||||
|
// standard synchronizer in this implementation
|
||||||
|
// because our timing constraints are different.
|
||||||
|
//
|
||||||
|
// Instead of cutting the timing path to the d-input
|
||||||
|
// on the first flop we need to cut the aclr input.
|
||||||
|
//
|
||||||
|
// We omit the "preserve" attribute on the final
|
||||||
|
// output register, so that the synthesis tool can
|
||||||
|
// duplicate it where needed.
|
||||||
|
// -----------------------------------------------
|
||||||
|
(*preserve*) reg [DEPTH-1:0] altera_reset_synchronizer_int_chain;
|
||||||
|
reg altera_reset_synchronizer_int_chain_out;
|
||||||
|
|
||||||
|
generate if (ASYNC_RESET) begin
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// Assert asynchronously, deassert synchronously.
|
||||||
|
// -----------------------------------------------
|
||||||
|
always @(posedge clk or posedge reset_in) begin
|
||||||
|
if (reset_in) begin
|
||||||
|
altera_reset_synchronizer_int_chain <= {DEPTH{1'b1}};
|
||||||
|
altera_reset_synchronizer_int_chain_out <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
altera_reset_synchronizer_int_chain[DEPTH-2:0] <= altera_reset_synchronizer_int_chain[DEPTH-1:1];
|
||||||
|
altera_reset_synchronizer_int_chain[DEPTH-1] <= 0;
|
||||||
|
altera_reset_synchronizer_int_chain_out <= altera_reset_synchronizer_int_chain[0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign reset_out = altera_reset_synchronizer_int_chain_out;
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
// Assert synchronously, deassert synchronously.
|
||||||
|
// -----------------------------------------------
|
||||||
|
always @(posedge clk) begin
|
||||||
|
altera_reset_synchronizer_int_chain[DEPTH-2:0] <= altera_reset_synchronizer_int_chain[DEPTH-1:1];
|
||||||
|
altera_reset_synchronizer_int_chain[DEPTH-1] <= reset_in;
|
||||||
|
altera_reset_synchronizer_int_chain_out <= altera_reset_synchronizer_int_chain[0];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign reset_out = altera_reset_synchronizer_int_chain_out;
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
165
ip/altera/ddr3/altera_std_synchronizer_nocut.v
Normal file
165
ip/altera/ddr3/altera_std_synchronizer_nocut.v
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/main/ip/sopc/components/primitives/altera_std_synchronizer/altera_std_synchronizer.v#8 $
|
||||||
|
// $Revision: #8 $
|
||||||
|
// $Date: 2009/02/18 $
|
||||||
|
// $Author: pscheidt $
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// File: altera_std_synchronizer_nocut.v
|
||||||
|
//
|
||||||
|
// Abstract: Single bit clock domain crossing synchronizer. Exactly the same
|
||||||
|
// as altera_std_synchronizer.v, except that the embedded false
|
||||||
|
// path constraint is removed in this module. If you use this
|
||||||
|
// module, you will have to apply the appropriate timing
|
||||||
|
// constraints.
|
||||||
|
//
|
||||||
|
// We expect to make this a standard Quartus atom eventually.
|
||||||
|
//
|
||||||
|
// Composed of two or more flip flops connected in series.
|
||||||
|
// Random metastable condition is simulated when the
|
||||||
|
// __ALTERA_STD__METASTABLE_SIM macro is defined.
|
||||||
|
// Use +define+__ALTERA_STD__METASTABLE_SIM argument
|
||||||
|
// on the Verilog simulator compiler command line to
|
||||||
|
// enable this mode. In addition, define the macro
|
||||||
|
// __ALTERA_STD__METASTABLE_SIM_VERBOSE to get console output
|
||||||
|
// with every metastable event generated in the synchronizer.
|
||||||
|
//
|
||||||
|
// Copyright (C) Altera Corporation 2009, All Rights Reserved
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 1ns
|
||||||
|
|
||||||
|
module altera_std_synchronizer_nocut (
|
||||||
|
clk,
|
||||||
|
reset_n,
|
||||||
|
din,
|
||||||
|
dout
|
||||||
|
);
|
||||||
|
|
||||||
|
parameter depth = 3; // This value must be >= 2 !
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input reset_n;
|
||||||
|
input din;
|
||||||
|
output dout;
|
||||||
|
|
||||||
|
// QuartusII synthesis directives:
|
||||||
|
// 1. Preserve all registers ie. do not touch them.
|
||||||
|
// 2. Do not merge other flip-flops with synchronizer flip-flops.
|
||||||
|
// QuartusII TimeQuest directives:
|
||||||
|
// 1. Identify all flip-flops in this module as members of the synchronizer
|
||||||
|
// to enable automatic metastability MTBF analysis.
|
||||||
|
|
||||||
|
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS; -name DONT_MERGE_REGISTER ON; -name PRESERVE_REGISTER ON "} *) reg din_s1;
|
||||||
|
|
||||||
|
(* altera_attribute = {"-name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS; -name DONT_MERGE_REGISTER ON; -name PRESERVE_REGISTER ON"} *) reg [depth-2:0] dreg;
|
||||||
|
|
||||||
|
//synthesis translate_off
|
||||||
|
initial begin
|
||||||
|
if (depth <2) begin
|
||||||
|
$display("%m: Error: synchronizer length: %0d less than 2.", depth);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// the first synchronizer register is either a simple D flop for synthesis
|
||||||
|
// and non-metastable simulation or a D flop with a method to inject random
|
||||||
|
// metastable events resulting in random delay of [0,1] cycles
|
||||||
|
|
||||||
|
`ifdef __ALTERA_STD__METASTABLE_SIM
|
||||||
|
|
||||||
|
reg[31:0] RANDOM_SEED = 123456;
|
||||||
|
wire next_din_s1;
|
||||||
|
wire dout;
|
||||||
|
reg din_last;
|
||||||
|
reg random;
|
||||||
|
event metastable_event; // hook for debug monitoring
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
$display("%m: Info: Metastable event injection simulation mode enabled");
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
random <= $random(RANDOM_SEED);
|
||||||
|
else
|
||||||
|
random <= $random;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign next_din_s1 = (din_last ^ din) ? random : din;
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
din_last <= 1'b0;
|
||||||
|
else
|
||||||
|
din_last <= din;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
din_s1 <= 1'b0;
|
||||||
|
else
|
||||||
|
din_s1 <= next_din_s1;
|
||||||
|
end
|
||||||
|
|
||||||
|
`else
|
||||||
|
|
||||||
|
//synthesis translate_on
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
din_s1 <= 1'b0;
|
||||||
|
else
|
||||||
|
din_s1 <= din;
|
||||||
|
end
|
||||||
|
//synthesis translate_off
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
`ifdef __ALTERA_STD__METASTABLE_SIM_VERBOSE
|
||||||
|
always @(*) begin
|
||||||
|
if (reset_n && (din_last != din) && (random != din)) begin
|
||||||
|
$display("%m: Verbose Info: metastable event @ time %t", $time);
|
||||||
|
->metastable_event;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
|
//synthesis translate_on
|
||||||
|
|
||||||
|
// the remaining synchronizer registers form a simple shift register
|
||||||
|
// of length depth-1
|
||||||
|
generate
|
||||||
|
if (depth < 3) begin
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
dreg <= {depth-1{1'b0}};
|
||||||
|
else
|
||||||
|
dreg <= din_s1;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
always @(posedge clk or negedge reset_n) begin
|
||||||
|
if (reset_n == 0)
|
||||||
|
dreg <= {depth-1{1'b0}};
|
||||||
|
else
|
||||||
|
dreg <= {dreg[depth-3:0], din_s1};
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign dout = dreg[depth-2];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
335
ip/altera/ddr3/altera_wrap_burst_converter.sv
Normal file
335
ip/altera/ddr3/altera_wrap_burst_converter.sv
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_burst_adapter/new_source/altera_wrap_burst_converter.sv#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// This component is specially for Wrapping Avalon slave.
|
||||||
|
// It converts burst length of input packet
|
||||||
|
// to match slave burst.
|
||||||
|
// ------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module altera_wrap_burst_converter
|
||||||
|
#(
|
||||||
|
parameter
|
||||||
|
// ----------------------------------------
|
||||||
|
// Burst length Parameters
|
||||||
|
// (real burst length value, not bytecount)
|
||||||
|
// ----------------------------------------
|
||||||
|
MAX_IN_LEN = 16,
|
||||||
|
MAX_OUT_LEN = 4,
|
||||||
|
ADDR_WIDTH = 12,
|
||||||
|
BNDRY_WIDTH = 12,
|
||||||
|
NUM_SYMBOLS = 4,
|
||||||
|
AXI_SLAVE = 0,
|
||||||
|
OPTIMIZE_WRITE_BURST = 0,
|
||||||
|
// ------------------
|
||||||
|
// Derived Parameters
|
||||||
|
// ------------------
|
||||||
|
LEN_WIDTH = log2ceil(MAX_IN_LEN) + 1,
|
||||||
|
OUT_LEN_WIDTH = log2ceil(MAX_OUT_LEN) + 1,
|
||||||
|
LOG2_NUMSYMBOLS = log2ceil(NUM_SYMBOLS)
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
input enable_write,
|
||||||
|
input enable_read,
|
||||||
|
|
||||||
|
input [LEN_WIDTH - 1 : 0] in_len,
|
||||||
|
input [LEN_WIDTH - 1 : 0] first_len,
|
||||||
|
input in_sop,
|
||||||
|
|
||||||
|
input [ADDR_WIDTH - 1 : 0] in_addr,
|
||||||
|
input [ADDR_WIDTH - 1 : 0] in_addr_reg,
|
||||||
|
input [BNDRY_WIDTH - 1 : 0] in_boundary,
|
||||||
|
input [BNDRY_WIDTH - 1 : 0] in_burstwrap,
|
||||||
|
input [BNDRY_WIDTH - 1 : 0] in_burstwrap_reg,
|
||||||
|
|
||||||
|
// converted output length
|
||||||
|
// out_len : compressed burst, read
|
||||||
|
// uncompressed_len: uncompressed, write
|
||||||
|
output reg [LEN_WIDTH - 1 : 0] out_len,
|
||||||
|
output reg [LEN_WIDTH - 1 : 0] uncompr_out_len,
|
||||||
|
|
||||||
|
// Compressed address output
|
||||||
|
output reg [ADDR_WIDTH - 1 : 0] out_addr,
|
||||||
|
output reg new_burst_export
|
||||||
|
);
|
||||||
|
|
||||||
|
// ------------------------------
|
||||||
|
// Local parameters
|
||||||
|
// ------------------------------
|
||||||
|
localparam
|
||||||
|
OUT_BOUNDARY = MAX_OUT_LEN * NUM_SYMBOLS,
|
||||||
|
ADDR_SEL = log2ceil(OUT_BOUNDARY);
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Signals for wrapping support
|
||||||
|
// ----------------------------------------
|
||||||
|
reg [LEN_WIDTH - 1 : 0] remaining_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_out_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_rem_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] uncompr_remaining_len;
|
||||||
|
reg new_burst;
|
||||||
|
reg uncompr_sub_burst;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_uncompr_out_len;
|
||||||
|
reg [LEN_WIDTH - 1 : 0] next_uncompr_sub_len;
|
||||||
|
|
||||||
|
// Avoid QIS warning
|
||||||
|
wire [OUT_LEN_WIDTH - 1 : 0] max_out_length;
|
||||||
|
assign max_out_length = MAX_OUT_LEN[OUT_LEN_WIDTH - 1 : 0];
|
||||||
|
|
||||||
|
// ----------------------------------------
|
||||||
|
// Calculate aligned length for WRAP burst
|
||||||
|
// ----------------------------------------
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] extended_burstwrap;
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] extended_burstwrap_reg;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
extended_burstwrap = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap[BNDRY_WIDTH - 1]}}, in_burstwrap};
|
||||||
|
extended_burstwrap_reg = {{(ADDR_WIDTH - BNDRY_WIDTH) {in_burstwrap_reg[BNDRY_WIDTH - 1]}}, in_burstwrap_reg};
|
||||||
|
new_burst_export = new_burst;
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
// length calculation
|
||||||
|
// -------------------------------------------
|
||||||
|
reg [LEN_WIDTH -1 : 0] next_uncompr_remaining_len;
|
||||||
|
always_comb begin
|
||||||
|
// Signals name
|
||||||
|
// *_uncompr_* --> uncompressed transaction
|
||||||
|
// -------------------------------------------
|
||||||
|
// Always use max_out_length as possible.
|
||||||
|
// Else use the remaining length.
|
||||||
|
// If in length smaller and not cross bndry or same, pass thru.
|
||||||
|
|
||||||
|
if (in_sop) begin
|
||||||
|
uncompr_remaining_len = in_len;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
uncompr_remaining_len = next_uncompr_remaining_len;
|
||||||
|
end
|
||||||
|
end // always_comb
|
||||||
|
|
||||||
|
// compressed transactions
|
||||||
|
always_comb begin : proc_compressed_read
|
||||||
|
remaining_len = in_len;
|
||||||
|
if (!new_burst)
|
||||||
|
remaining_len = next_rem_len;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
next_uncompr_out_len = first_len;
|
||||||
|
if (in_sop) begin
|
||||||
|
next_uncompr_out_len = first_len;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (uncompr_sub_burst)
|
||||||
|
next_uncompr_out_len = next_uncompr_sub_len;
|
||||||
|
else begin
|
||||||
|
if (uncompr_remaining_len < max_out_length)
|
||||||
|
next_uncompr_out_len = uncompr_remaining_len;
|
||||||
|
else
|
||||||
|
next_uncompr_out_len = max_out_length;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Compressed transaction: Always try to send MAX out_len then remaining length.
|
||||||
|
// Seperate it as the main difference is the first out len.
|
||||||
|
// For a WRAP burst, the first beat is the aligned length, then similar to INCR.
|
||||||
|
always_comb begin
|
||||||
|
if (new_burst) begin
|
||||||
|
next_out_len = first_len;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
next_out_len = max_out_length;
|
||||||
|
if (remaining_len < max_out_length) begin
|
||||||
|
next_out_len = remaining_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end // always_comb
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Length remaining calculation : Compressed
|
||||||
|
// --------------------------------------------------
|
||||||
|
// length remaining for compressed transaction
|
||||||
|
// for wrap, need special handling for first out length
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
next_rem_len <= 0;
|
||||||
|
else if (enable_read) begin
|
||||||
|
if (new_burst)
|
||||||
|
next_rem_len <= in_len - first_len;
|
||||||
|
else
|
||||||
|
next_rem_len <= next_rem_len - max_out_length;
|
||||||
|
end
|
||||||
|
end // always_ff @
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Length remaining calculation : Uncompressed
|
||||||
|
// --------------------------------------------------
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
next_uncompr_remaining_len <= 0;
|
||||||
|
end
|
||||||
|
else if (enable_write) begin
|
||||||
|
if (in_sop)
|
||||||
|
next_uncompr_remaining_len <= in_len - first_len;
|
||||||
|
else if (!uncompr_sub_burst)
|
||||||
|
next_uncompr_remaining_len <= next_uncompr_remaining_len - max_out_length;
|
||||||
|
end
|
||||||
|
end // always_ff @
|
||||||
|
|
||||||
|
// length for each sub-burst if it needs to chop the burst
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
next_uncompr_sub_len <= 0;
|
||||||
|
end
|
||||||
|
else if (enable_write) begin
|
||||||
|
next_uncompr_sub_len <= next_uncompr_out_len - 1'b1; // in term of length, it just reduces 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// the sub-burst still active
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
uncompr_sub_burst <= 0;
|
||||||
|
end
|
||||||
|
else if (enable_write) begin
|
||||||
|
uncompr_sub_burst <= (next_uncompr_out_len > 1'b1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Control signals
|
||||||
|
// --------------------------------------------------
|
||||||
|
wire end_compressed_sub_burst;
|
||||||
|
assign end_compressed_sub_burst = (remaining_len == next_out_len);
|
||||||
|
|
||||||
|
// new_burst:
|
||||||
|
// the converter takes in_len for new caculation
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
new_burst <= 1;
|
||||||
|
end
|
||||||
|
else if (enable_read) begin
|
||||||
|
new_burst <= end_compressed_sub_burst;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Output length
|
||||||
|
// --------------------------------------------------
|
||||||
|
// register out_len for compressed trans
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
out_len <= 0;
|
||||||
|
end
|
||||||
|
else if (enable_read) begin
|
||||||
|
out_len <= next_out_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// register uncompr_out_len for uncompressed trans
|
||||||
|
generate
|
||||||
|
if (OPTIMIZE_WRITE_BURST) begin : optimized_write_burst_len
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
uncompr_out_len <= '0;
|
||||||
|
end
|
||||||
|
//else if (enable_write) begin
|
||||||
|
else if (enable_read) begin
|
||||||
|
uncompr_out_len <= first_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin : unoptimized_write_burst_len
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
uncompr_out_len <= '0;
|
||||||
|
end
|
||||||
|
else if (enable_write) begin
|
||||||
|
uncompr_out_len <= next_uncompr_out_len;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Address calculation
|
||||||
|
// --------------------------------------------------
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] addr_incr;
|
||||||
|
localparam [ADDR_WIDTH - 1 : 0] ADDR_INCR = MAX_OUT_LEN << LOG2_NUMSYMBOLS;
|
||||||
|
assign addr_incr = ADDR_INCR[ADDR_WIDTH - 1 : 0];
|
||||||
|
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] next_out_addr;
|
||||||
|
reg [ADDR_WIDTH - 1 : 0] incremented_addr;
|
||||||
|
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
out_addr <= '0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (enable_read) begin
|
||||||
|
out_addr <= (next_out_addr);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end // always_ff @
|
||||||
|
|
||||||
|
// use burstwrap/burstwrap_reg to calculate address incrementing
|
||||||
|
always_ff @(posedge clk, posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
incremented_addr <= '0;
|
||||||
|
end
|
||||||
|
else if (enable_read) begin
|
||||||
|
incremented_addr <= ((next_out_addr + addr_incr) & extended_burstwrap_reg);
|
||||||
|
if (new_burst) begin
|
||||||
|
incremented_addr <= ((next_out_addr + (first_len << LOG2_NUMSYMBOLS)) & extended_burstwrap); //byte address
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end // always_ff @
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
next_out_addr = in_addr;
|
||||||
|
if (!new_burst) begin
|
||||||
|
next_out_addr = in_addr_reg & ~extended_burstwrap_reg | incremented_addr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Calculates the log2ceil of the input value
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input integer val;
|
||||||
|
reg[31:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i[30:0] << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
1086
ip/altera/ddr3/ddr3_0002.v
Normal file
1086
ip/altera/ddr3/ddr3_0002.v
Normal file
File diff suppressed because it is too large
Load Diff
354
ip/altera/ddr3/ddr3_dmaster.v
Normal file
354
ip/altera/ddr3/ddr3_dmaster.v
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
// ddr3_dmaster.v
|
||||||
|
|
||||||
|
// This file was auto-generated from altera_jtag_avalon_master_hw.tcl. If you edit it your changes
|
||||||
|
// will probably be lost.
|
||||||
|
//
|
||||||
|
// Generated using ACDS version 15.1 185
|
||||||
|
|
||||||
|
`timescale 1 ps / 1 ps
|
||||||
|
module ddr3_dmaster #(
|
||||||
|
parameter USE_PLI = 0,
|
||||||
|
parameter PLI_PORT = 50000,
|
||||||
|
parameter FIFO_DEPTHS = 2
|
||||||
|
) (
|
||||||
|
input wire clk_clk, // clk.clk
|
||||||
|
input wire clk_reset_reset, // clk_reset.reset
|
||||||
|
output wire [31:0] master_address, // master.address
|
||||||
|
input wire [31:0] master_readdata, // .readdata
|
||||||
|
output wire master_read, // .read
|
||||||
|
output wire master_write, // .write
|
||||||
|
output wire [31:0] master_writedata, // .writedata
|
||||||
|
input wire master_waitrequest, // .waitrequest
|
||||||
|
input wire master_readdatavalid, // .readdatavalid
|
||||||
|
output wire [3:0] master_byteenable, // .byteenable
|
||||||
|
output wire master_reset_reset // master_reset.reset
|
||||||
|
);
|
||||||
|
|
||||||
|
wire jtag_phy_embedded_in_jtag_master_src_valid; // jtag_phy_embedded_in_jtag_master:source_valid -> timing_adt:in_valid
|
||||||
|
wire [7:0] jtag_phy_embedded_in_jtag_master_src_data; // jtag_phy_embedded_in_jtag_master:source_data -> timing_adt:in_data
|
||||||
|
wire timing_adt_out_valid; // timing_adt:out_valid -> fifo:in_valid
|
||||||
|
wire [7:0] timing_adt_out_data; // timing_adt:out_data -> fifo:in_data
|
||||||
|
wire timing_adt_out_ready; // fifo:in_ready -> timing_adt:out_ready
|
||||||
|
wire fifo_out_valid; // fifo:out_valid -> b2p:in_valid
|
||||||
|
wire [7:0] fifo_out_data; // fifo:out_data -> b2p:in_data
|
||||||
|
wire fifo_out_ready; // b2p:in_ready -> fifo:out_ready
|
||||||
|
wire b2p_out_packets_stream_valid; // b2p:out_valid -> b2p_adapter:in_valid
|
||||||
|
wire [7:0] b2p_out_packets_stream_data; // b2p:out_data -> b2p_adapter:in_data
|
||||||
|
wire b2p_out_packets_stream_ready; // b2p_adapter:in_ready -> b2p:out_ready
|
||||||
|
wire [7:0] b2p_out_packets_stream_channel; // b2p:out_channel -> b2p_adapter:in_channel
|
||||||
|
wire b2p_out_packets_stream_startofpacket; // b2p:out_startofpacket -> b2p_adapter:in_startofpacket
|
||||||
|
wire b2p_out_packets_stream_endofpacket; // b2p:out_endofpacket -> b2p_adapter:in_endofpacket
|
||||||
|
wire b2p_adapter_out_valid; // b2p_adapter:out_valid -> transacto:in_valid
|
||||||
|
wire [7:0] b2p_adapter_out_data; // b2p_adapter:out_data -> transacto:in_data
|
||||||
|
wire b2p_adapter_out_ready; // transacto:in_ready -> b2p_adapter:out_ready
|
||||||
|
wire b2p_adapter_out_startofpacket; // b2p_adapter:out_startofpacket -> transacto:in_startofpacket
|
||||||
|
wire b2p_adapter_out_endofpacket; // b2p_adapter:out_endofpacket -> transacto:in_endofpacket
|
||||||
|
wire transacto_out_stream_valid; // transacto:out_valid -> p2b_adapter:in_valid
|
||||||
|
wire [7:0] transacto_out_stream_data; // transacto:out_data -> p2b_adapter:in_data
|
||||||
|
wire transacto_out_stream_ready; // p2b_adapter:in_ready -> transacto:out_ready
|
||||||
|
wire transacto_out_stream_startofpacket; // transacto:out_startofpacket -> p2b_adapter:in_startofpacket
|
||||||
|
wire transacto_out_stream_endofpacket; // transacto:out_endofpacket -> p2b_adapter:in_endofpacket
|
||||||
|
wire p2b_adapter_out_valid; // p2b_adapter:out_valid -> p2b:in_valid
|
||||||
|
wire [7:0] p2b_adapter_out_data; // p2b_adapter:out_data -> p2b:in_data
|
||||||
|
wire p2b_adapter_out_ready; // p2b:in_ready -> p2b_adapter:out_ready
|
||||||
|
wire [7:0] p2b_adapter_out_channel; // p2b_adapter:out_channel -> p2b:in_channel
|
||||||
|
wire p2b_adapter_out_startofpacket; // p2b_adapter:out_startofpacket -> p2b:in_startofpacket
|
||||||
|
wire p2b_adapter_out_endofpacket; // p2b_adapter:out_endofpacket -> p2b:in_endofpacket
|
||||||
|
wire p2b_out_bytes_stream_valid; // p2b:out_valid -> jtag_phy_embedded_in_jtag_master:sink_valid
|
||||||
|
wire [7:0] p2b_out_bytes_stream_data; // p2b:out_data -> jtag_phy_embedded_in_jtag_master:sink_data
|
||||||
|
wire p2b_out_bytes_stream_ready; // jtag_phy_embedded_in_jtag_master:sink_ready -> p2b:out_ready
|
||||||
|
wire rst_controller_reset_out_reset; // rst_controller:reset_out -> [b2p:reset_n, b2p_adapter:reset_n, fifo:reset, jtag_phy_embedded_in_jtag_master:reset_n, p2b:reset_n, p2b_adapter:reset_n, timing_adt:reset_n, transacto:reset_n]
|
||||||
|
|
||||||
|
generate
|
||||||
|
// If any of the display statements (or deliberately broken
|
||||||
|
// instantiations) within this generate block triggers then this module
|
||||||
|
// has been instantiated this module with a set of parameters different
|
||||||
|
// from those it was generated for. This will usually result in a
|
||||||
|
// non-functioning system.
|
||||||
|
if (USE_PLI != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
use_pli_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (PLI_PORT != 50000)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
pli_port_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (FIFO_DEPTHS != 2)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
fifo_depths_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
altera_avalon_st_jtag_interface #(
|
||||||
|
.PURPOSE (1),
|
||||||
|
.UPSTREAM_FIFO_SIZE (0),
|
||||||
|
.DOWNSTREAM_FIFO_SIZE (64),
|
||||||
|
.MGMT_CHANNEL_WIDTH (-1),
|
||||||
|
.EXPORT_JTAG (0),
|
||||||
|
.USE_PLI (0),
|
||||||
|
.PLI_PORT (50000)
|
||||||
|
) jtag_phy_embedded_in_jtag_master (
|
||||||
|
.clk (clk_clk), // clock.clk
|
||||||
|
.reset_n (~rst_controller_reset_out_reset), // clock_reset.reset_n
|
||||||
|
.source_data (jtag_phy_embedded_in_jtag_master_src_data), // src.data
|
||||||
|
.source_valid (jtag_phy_embedded_in_jtag_master_src_valid), // .valid
|
||||||
|
.sink_data (p2b_out_bytes_stream_data), // sink.data
|
||||||
|
.sink_valid (p2b_out_bytes_stream_valid), // .valid
|
||||||
|
.sink_ready (p2b_out_bytes_stream_ready), // .ready
|
||||||
|
.resetrequest (master_reset_reset), // resetrequest.reset
|
||||||
|
.source_ready (1'b1), // (terminated)
|
||||||
|
.mgmt_valid (), // (terminated)
|
||||||
|
.mgmt_channel (), // (terminated)
|
||||||
|
.mgmt_data (), // (terminated)
|
||||||
|
.jtag_tck (1'b0), // (terminated)
|
||||||
|
.jtag_tms (1'b0), // (terminated)
|
||||||
|
.jtag_tdi (1'b0), // (terminated)
|
||||||
|
.jtag_tdo (), // (terminated)
|
||||||
|
.jtag_ena (1'b0), // (terminated)
|
||||||
|
.jtag_usr1 (1'b0), // (terminated)
|
||||||
|
.jtag_clr (1'b0), // (terminated)
|
||||||
|
.jtag_clrn (1'b0), // (terminated)
|
||||||
|
.jtag_state_tlr (1'b0), // (terminated)
|
||||||
|
.jtag_state_rti (1'b0), // (terminated)
|
||||||
|
.jtag_state_sdrs (1'b0), // (terminated)
|
||||||
|
.jtag_state_cdr (1'b0), // (terminated)
|
||||||
|
.jtag_state_sdr (1'b0), // (terminated)
|
||||||
|
.jtag_state_e1dr (1'b0), // (terminated)
|
||||||
|
.jtag_state_pdr (1'b0), // (terminated)
|
||||||
|
.jtag_state_e2dr (1'b0), // (terminated)
|
||||||
|
.jtag_state_udr (1'b0), // (terminated)
|
||||||
|
.jtag_state_sirs (1'b0), // (terminated)
|
||||||
|
.jtag_state_cir (1'b0), // (terminated)
|
||||||
|
.jtag_state_sir (1'b0), // (terminated)
|
||||||
|
.jtag_state_e1ir (1'b0), // (terminated)
|
||||||
|
.jtag_state_pir (1'b0), // (terminated)
|
||||||
|
.jtag_state_e2ir (1'b0), // (terminated)
|
||||||
|
.jtag_state_uir (1'b0), // (terminated)
|
||||||
|
.jtag_ir_in (3'b000), // (terminated)
|
||||||
|
.jtag_irq (), // (terminated)
|
||||||
|
.jtag_ir_out () // (terminated)
|
||||||
|
);
|
||||||
|
|
||||||
|
ddr3_dmaster_timing_adt timing_adt (
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset_n (~rst_controller_reset_out_reset), // reset.reset_n
|
||||||
|
.in_data (jtag_phy_embedded_in_jtag_master_src_data), // in.data
|
||||||
|
.in_valid (jtag_phy_embedded_in_jtag_master_src_valid), // .valid
|
||||||
|
.out_data (timing_adt_out_data), // out.data
|
||||||
|
.out_valid (timing_adt_out_valid), // .valid
|
||||||
|
.out_ready (timing_adt_out_ready) // .ready
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_avalon_sc_fifo #(
|
||||||
|
.SYMBOLS_PER_BEAT (1),
|
||||||
|
.BITS_PER_SYMBOL (8),
|
||||||
|
.FIFO_DEPTH (64),
|
||||||
|
.CHANNEL_WIDTH (0),
|
||||||
|
.ERROR_WIDTH (0),
|
||||||
|
.USE_PACKETS (0),
|
||||||
|
.USE_FILL_LEVEL (0),
|
||||||
|
.EMPTY_LATENCY (3),
|
||||||
|
.USE_MEMORY_BLOCKS (1),
|
||||||
|
.USE_STORE_FORWARD (0),
|
||||||
|
.USE_ALMOST_FULL_IF (0),
|
||||||
|
.USE_ALMOST_EMPTY_IF (0)
|
||||||
|
) fifo (
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset (rst_controller_reset_out_reset), // clk_reset.reset
|
||||||
|
.in_data (timing_adt_out_data), // in.data
|
||||||
|
.in_valid (timing_adt_out_valid), // .valid
|
||||||
|
.in_ready (timing_adt_out_ready), // .ready
|
||||||
|
.out_data (fifo_out_data), // out.data
|
||||||
|
.out_valid (fifo_out_valid), // .valid
|
||||||
|
.out_ready (fifo_out_ready), // .ready
|
||||||
|
.csr_address (2'b00), // (terminated)
|
||||||
|
.csr_read (1'b0), // (terminated)
|
||||||
|
.csr_write (1'b0), // (terminated)
|
||||||
|
.csr_readdata (), // (terminated)
|
||||||
|
.csr_writedata (32'b00000000000000000000000000000000), // (terminated)
|
||||||
|
.almost_full_data (), // (terminated)
|
||||||
|
.almost_empty_data (), // (terminated)
|
||||||
|
.in_startofpacket (1'b0), // (terminated)
|
||||||
|
.in_endofpacket (1'b0), // (terminated)
|
||||||
|
.out_startofpacket (), // (terminated)
|
||||||
|
.out_endofpacket (), // (terminated)
|
||||||
|
.in_empty (1'b0), // (terminated)
|
||||||
|
.out_empty (), // (terminated)
|
||||||
|
.in_error (1'b0), // (terminated)
|
||||||
|
.out_error (), // (terminated)
|
||||||
|
.in_channel (1'b0), // (terminated)
|
||||||
|
.out_channel () // (terminated)
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_avalon_st_bytes_to_packets #(
|
||||||
|
.CHANNEL_WIDTH (8),
|
||||||
|
.ENCODING (0)
|
||||||
|
) b2p (
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset_n (~rst_controller_reset_out_reset), // clk_reset.reset_n
|
||||||
|
.out_channel (b2p_out_packets_stream_channel), // out_packets_stream.channel
|
||||||
|
.out_ready (b2p_out_packets_stream_ready), // .ready
|
||||||
|
.out_valid (b2p_out_packets_stream_valid), // .valid
|
||||||
|
.out_data (b2p_out_packets_stream_data), // .data
|
||||||
|
.out_startofpacket (b2p_out_packets_stream_startofpacket), // .startofpacket
|
||||||
|
.out_endofpacket (b2p_out_packets_stream_endofpacket), // .endofpacket
|
||||||
|
.in_ready (fifo_out_ready), // in_bytes_stream.ready
|
||||||
|
.in_valid (fifo_out_valid), // .valid
|
||||||
|
.in_data (fifo_out_data) // .data
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_avalon_st_packets_to_bytes #(
|
||||||
|
.CHANNEL_WIDTH (8),
|
||||||
|
.ENCODING (0)
|
||||||
|
) p2b (
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset_n (~rst_controller_reset_out_reset), // clk_reset.reset_n
|
||||||
|
.in_ready (p2b_adapter_out_ready), // in_packets_stream.ready
|
||||||
|
.in_valid (p2b_adapter_out_valid), // .valid
|
||||||
|
.in_data (p2b_adapter_out_data), // .data
|
||||||
|
.in_channel (p2b_adapter_out_channel), // .channel
|
||||||
|
.in_startofpacket (p2b_adapter_out_startofpacket), // .startofpacket
|
||||||
|
.in_endofpacket (p2b_adapter_out_endofpacket), // .endofpacket
|
||||||
|
.out_ready (p2b_out_bytes_stream_ready), // out_bytes_stream.ready
|
||||||
|
.out_valid (p2b_out_bytes_stream_valid), // .valid
|
||||||
|
.out_data (p2b_out_bytes_stream_data) // .data
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_avalon_packets_to_master #(
|
||||||
|
.FAST_VER (0),
|
||||||
|
.FIFO_DEPTHS (2),
|
||||||
|
.FIFO_WIDTHU (1)
|
||||||
|
) transacto (
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset_n (~rst_controller_reset_out_reset), // clk_reset.reset_n
|
||||||
|
.out_ready (transacto_out_stream_ready), // out_stream.ready
|
||||||
|
.out_valid (transacto_out_stream_valid), // .valid
|
||||||
|
.out_data (transacto_out_stream_data), // .data
|
||||||
|
.out_startofpacket (transacto_out_stream_startofpacket), // .startofpacket
|
||||||
|
.out_endofpacket (transacto_out_stream_endofpacket), // .endofpacket
|
||||||
|
.in_ready (b2p_adapter_out_ready), // in_stream.ready
|
||||||
|
.in_valid (b2p_adapter_out_valid), // .valid
|
||||||
|
.in_data (b2p_adapter_out_data), // .data
|
||||||
|
.in_startofpacket (b2p_adapter_out_startofpacket), // .startofpacket
|
||||||
|
.in_endofpacket (b2p_adapter_out_endofpacket), // .endofpacket
|
||||||
|
.address (master_address), // avalon_master.address
|
||||||
|
.readdata (master_readdata), // .readdata
|
||||||
|
.read (master_read), // .read
|
||||||
|
.write (master_write), // .write
|
||||||
|
.writedata (master_writedata), // .writedata
|
||||||
|
.waitrequest (master_waitrequest), // .waitrequest
|
||||||
|
.readdatavalid (master_readdatavalid), // .readdatavalid
|
||||||
|
.byteenable (master_byteenable) // .byteenable
|
||||||
|
);
|
||||||
|
|
||||||
|
ddr3_dmaster_b2p_adapter b2p_adapter (
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset_n (~rst_controller_reset_out_reset), // reset.reset_n
|
||||||
|
.in_data (b2p_out_packets_stream_data), // in.data
|
||||||
|
.in_valid (b2p_out_packets_stream_valid), // .valid
|
||||||
|
.in_ready (b2p_out_packets_stream_ready), // .ready
|
||||||
|
.in_startofpacket (b2p_out_packets_stream_startofpacket), // .startofpacket
|
||||||
|
.in_endofpacket (b2p_out_packets_stream_endofpacket), // .endofpacket
|
||||||
|
.in_channel (b2p_out_packets_stream_channel), // .channel
|
||||||
|
.out_data (b2p_adapter_out_data), // out.data
|
||||||
|
.out_valid (b2p_adapter_out_valid), // .valid
|
||||||
|
.out_ready (b2p_adapter_out_ready), // .ready
|
||||||
|
.out_startofpacket (b2p_adapter_out_startofpacket), // .startofpacket
|
||||||
|
.out_endofpacket (b2p_adapter_out_endofpacket) // .endofpacket
|
||||||
|
);
|
||||||
|
|
||||||
|
ddr3_dmaster_p2b_adapter p2b_adapter (
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset_n (~rst_controller_reset_out_reset), // reset.reset_n
|
||||||
|
.in_data (transacto_out_stream_data), // in.data
|
||||||
|
.in_valid (transacto_out_stream_valid), // .valid
|
||||||
|
.in_ready (transacto_out_stream_ready), // .ready
|
||||||
|
.in_startofpacket (transacto_out_stream_startofpacket), // .startofpacket
|
||||||
|
.in_endofpacket (transacto_out_stream_endofpacket), // .endofpacket
|
||||||
|
.out_data (p2b_adapter_out_data), // out.data
|
||||||
|
.out_valid (p2b_adapter_out_valid), // .valid
|
||||||
|
.out_ready (p2b_adapter_out_ready), // .ready
|
||||||
|
.out_startofpacket (p2b_adapter_out_startofpacket), // .startofpacket
|
||||||
|
.out_endofpacket (p2b_adapter_out_endofpacket), // .endofpacket
|
||||||
|
.out_channel (p2b_adapter_out_channel) // .channel
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_reset_controller #(
|
||||||
|
.NUM_RESET_INPUTS (1),
|
||||||
|
.OUTPUT_RESET_SYNC_EDGES ("deassert"),
|
||||||
|
.SYNC_DEPTH (2),
|
||||||
|
.RESET_REQUEST_PRESENT (0),
|
||||||
|
.RESET_REQ_WAIT_TIME (1),
|
||||||
|
.MIN_RST_ASSERTION_TIME (3),
|
||||||
|
.RESET_REQ_EARLY_DSRT_TIME (1),
|
||||||
|
.USE_RESET_REQUEST_IN0 (0),
|
||||||
|
.USE_RESET_REQUEST_IN1 (0),
|
||||||
|
.USE_RESET_REQUEST_IN2 (0),
|
||||||
|
.USE_RESET_REQUEST_IN3 (0),
|
||||||
|
.USE_RESET_REQUEST_IN4 (0),
|
||||||
|
.USE_RESET_REQUEST_IN5 (0),
|
||||||
|
.USE_RESET_REQUEST_IN6 (0),
|
||||||
|
.USE_RESET_REQUEST_IN7 (0),
|
||||||
|
.USE_RESET_REQUEST_IN8 (0),
|
||||||
|
.USE_RESET_REQUEST_IN9 (0),
|
||||||
|
.USE_RESET_REQUEST_IN10 (0),
|
||||||
|
.USE_RESET_REQUEST_IN11 (0),
|
||||||
|
.USE_RESET_REQUEST_IN12 (0),
|
||||||
|
.USE_RESET_REQUEST_IN13 (0),
|
||||||
|
.USE_RESET_REQUEST_IN14 (0),
|
||||||
|
.USE_RESET_REQUEST_IN15 (0),
|
||||||
|
.ADAPT_RESET_REQUEST (0)
|
||||||
|
) rst_controller (
|
||||||
|
.reset_in0 (clk_reset_reset), // reset_in0.reset
|
||||||
|
.clk (clk_clk), // clk.clk
|
||||||
|
.reset_out (rst_controller_reset_out_reset), // reset_out.reset
|
||||||
|
.reset_req (), // (terminated)
|
||||||
|
.reset_req_in0 (1'b0), // (terminated)
|
||||||
|
.reset_in1 (1'b0), // (terminated)
|
||||||
|
.reset_req_in1 (1'b0), // (terminated)
|
||||||
|
.reset_in2 (1'b0), // (terminated)
|
||||||
|
.reset_req_in2 (1'b0), // (terminated)
|
||||||
|
.reset_in3 (1'b0), // (terminated)
|
||||||
|
.reset_req_in3 (1'b0), // (terminated)
|
||||||
|
.reset_in4 (1'b0), // (terminated)
|
||||||
|
.reset_req_in4 (1'b0), // (terminated)
|
||||||
|
.reset_in5 (1'b0), // (terminated)
|
||||||
|
.reset_req_in5 (1'b0), // (terminated)
|
||||||
|
.reset_in6 (1'b0), // (terminated)
|
||||||
|
.reset_req_in6 (1'b0), // (terminated)
|
||||||
|
.reset_in7 (1'b0), // (terminated)
|
||||||
|
.reset_req_in7 (1'b0), // (terminated)
|
||||||
|
.reset_in8 (1'b0), // (terminated)
|
||||||
|
.reset_req_in8 (1'b0), // (terminated)
|
||||||
|
.reset_in9 (1'b0), // (terminated)
|
||||||
|
.reset_req_in9 (1'b0), // (terminated)
|
||||||
|
.reset_in10 (1'b0), // (terminated)
|
||||||
|
.reset_req_in10 (1'b0), // (terminated)
|
||||||
|
.reset_in11 (1'b0), // (terminated)
|
||||||
|
.reset_req_in11 (1'b0), // (terminated)
|
||||||
|
.reset_in12 (1'b0), // (terminated)
|
||||||
|
.reset_req_in12 (1'b0), // (terminated)
|
||||||
|
.reset_in13 (1'b0), // (terminated)
|
||||||
|
.reset_req_in13 (1'b0), // (terminated)
|
||||||
|
.reset_in14 (1'b0), // (terminated)
|
||||||
|
.reset_req_in14 (1'b0), // (terminated)
|
||||||
|
.reset_in15 (1'b0), // (terminated)
|
||||||
|
.reset_req_in15 (1'b0) // (terminated)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
100
ip/altera/ddr3/ddr3_dmaster_b2p_adapter.sv
Normal file
100
ip/altera/ddr3/ddr3_dmaster_b2p_adapter.sv
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2013 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/13.1/ip/.../avalon-st_channel_adapter.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2013/09/09 $
|
||||||
|
// $Author: dmunday $
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon Streaming Channel Adapter
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_dmaster_b2p_adapter
|
||||||
|
// in_channel_width: 8
|
||||||
|
// in_max_channel: 255
|
||||||
|
// out_channel_width: 0
|
||||||
|
// out_max_channel: 0
|
||||||
|
// data_width: 8
|
||||||
|
// error_width: 0
|
||||||
|
// use_ready: true
|
||||||
|
// use_packets: true
|
||||||
|
// use_empty: 0
|
||||||
|
// empty_width: 0
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_dmaster_b2p_adapter
|
||||||
|
(
|
||||||
|
// Interface: in
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [8-1: 0] in_data,
|
||||||
|
input [8-1: 0] in_channel,
|
||||||
|
input in_startofpacket,
|
||||||
|
input in_endofpacket,
|
||||||
|
// Interface: out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [8-1: 0] out_data,
|
||||||
|
output reg out_startofpacket,
|
||||||
|
output reg out_endofpacket,
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
// Interface: reset
|
||||||
|
input reset_n
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
reg out_channel;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Payload Mapping
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always @* begin
|
||||||
|
in_ready = out_ready;
|
||||||
|
out_valid = in_valid;
|
||||||
|
out_data = in_data;
|
||||||
|
out_startofpacket = in_startofpacket;
|
||||||
|
out_endofpacket = in_endofpacket;
|
||||||
|
|
||||||
|
out_channel = in_channel; //TODO delete this to avoid Quartus warnings
|
||||||
|
|
||||||
|
// Suppress channels that are higher than the destination's max_channel.
|
||||||
|
if (in_channel > 0) begin
|
||||||
|
out_valid = 0;
|
||||||
|
// Simulation Message goes here.
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
96
ip/altera/ddr3/ddr3_dmaster_p2b_adapter.sv
Normal file
96
ip/altera/ddr3/ddr3_dmaster_p2b_adapter.sv
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2013 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/13.1/ip/.../avalon-st_channel_adapter.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2013/09/09 $
|
||||||
|
// $Author: dmunday $
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon Streaming Channel Adapter
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_dmaster_p2b_adapter
|
||||||
|
// in_channel_width: 0
|
||||||
|
// in_max_channel: 0
|
||||||
|
// out_channel_width: 8
|
||||||
|
// out_max_channel: 255
|
||||||
|
// data_width: 8
|
||||||
|
// error_width: 0
|
||||||
|
// use_ready: true
|
||||||
|
// use_packets: true
|
||||||
|
// use_empty: 0
|
||||||
|
// empty_width: 0
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_dmaster_p2b_adapter
|
||||||
|
(
|
||||||
|
// Interface: in
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [8-1: 0] in_data,
|
||||||
|
input in_startofpacket,
|
||||||
|
input in_endofpacket,
|
||||||
|
// Interface: out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [8-1: 0] out_data,
|
||||||
|
output reg [8-1: 0] out_channel,
|
||||||
|
output reg out_startofpacket,
|
||||||
|
output reg out_endofpacket,
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
// Interface: reset
|
||||||
|
input reset_n
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
reg in_channel = 0;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Payload Mapping
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always @* begin
|
||||||
|
in_ready = out_ready;
|
||||||
|
out_valid = in_valid;
|
||||||
|
out_data = in_data;
|
||||||
|
out_startofpacket = in_startofpacket;
|
||||||
|
out_endofpacket = in_endofpacket;
|
||||||
|
|
||||||
|
out_channel = 0;
|
||||||
|
out_channel = in_channel;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
112
ip/altera/ddr3/ddr3_dmaster_timing_adt.sv
Normal file
112
ip/altera/ddr3/ddr3_dmaster_timing_adt.sv
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2013 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/13.1/ip/.../avalon-st_timing_adapter.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2013/09/27 $
|
||||||
|
// $Author: dmunday, korthner $
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon Streaming Timing Adapter
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_dmaster_timing_adt
|
||||||
|
// in_use_ready: false
|
||||||
|
// out_use_ready: true
|
||||||
|
// in_use_valid: true
|
||||||
|
// out_use_valid: true
|
||||||
|
// use_packets: false
|
||||||
|
// use_empty: 0
|
||||||
|
// empty_width: 0
|
||||||
|
// data_width: 8
|
||||||
|
// channel_width: 0
|
||||||
|
// error_width: 0
|
||||||
|
// in_ready_latency: 0
|
||||||
|
// out_ready_latency: 0
|
||||||
|
// in_payload_width: 8
|
||||||
|
// out_payload_width: 8
|
||||||
|
// in_payload_map: in_data
|
||||||
|
// out_payload_map: out_data
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_dmaster_timing_adt
|
||||||
|
(
|
||||||
|
input in_valid,
|
||||||
|
input [8-1: 0] in_data,
|
||||||
|
// Interface: out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [8-1: 0] out_data,
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
// Interface: reset
|
||||||
|
input reset_n
|
||||||
|
|
||||||
|
/*AUTOARG*/);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Signal Declarations
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
reg [8-1:0] in_payload;
|
||||||
|
reg [8-1:0] out_payload;
|
||||||
|
reg [1-1:0] ready;
|
||||||
|
reg in_ready;
|
||||||
|
// synthesis translate_off
|
||||||
|
always @(negedge in_ready) begin
|
||||||
|
$display("%m: The downstream component is backpressuring by deasserting ready, but the upstream component can't be backpressured.");
|
||||||
|
end
|
||||||
|
// synthesis translate_on
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Payload Mapping
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always @* begin
|
||||||
|
in_payload = {in_data};
|
||||||
|
{out_data} = out_payload;
|
||||||
|
end
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Ready & valid signals.
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
ready[0] = out_ready;
|
||||||
|
out_valid = in_valid;
|
||||||
|
out_payload = in_payload;
|
||||||
|
in_ready = ready[0];
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
168
ip/altera/ddr3/ddr3_mm_interconnect_1.v
Normal file
168
ip/altera/ddr3/ddr3_mm_interconnect_1.v
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// ddr3_mm_interconnect_1.v
|
||||||
|
|
||||||
|
// This file was auto-generated from altera_mm_interconnect_hw.tcl. If you edit it your changes
|
||||||
|
// will probably be lost.
|
||||||
|
//
|
||||||
|
// Generated using ACDS version 15.1 185
|
||||||
|
|
||||||
|
`timescale 1 ps / 1 ps
|
||||||
|
module ddr3_mm_interconnect_1 (
|
||||||
|
input wire p0_avl_clk_clk, // p0_avl_clk.clk
|
||||||
|
input wire dmaster_clk_reset_reset_bridge_in_reset_reset, // dmaster_clk_reset_reset_bridge_in_reset.reset
|
||||||
|
input wire dmaster_master_translator_reset_reset_bridge_in_reset_reset, // dmaster_master_translator_reset_reset_bridge_in_reset.reset
|
||||||
|
input wire [31:0] dmaster_master_address, // dmaster_master.address
|
||||||
|
output wire dmaster_master_waitrequest, // .waitrequest
|
||||||
|
input wire [3:0] dmaster_master_byteenable, // .byteenable
|
||||||
|
input wire dmaster_master_read, // .read
|
||||||
|
output wire [31:0] dmaster_master_readdata, // .readdata
|
||||||
|
output wire dmaster_master_readdatavalid, // .readdatavalid
|
||||||
|
input wire dmaster_master_write, // .write
|
||||||
|
input wire [31:0] dmaster_master_writedata, // .writedata
|
||||||
|
output wire [31:0] s0_seq_debug_address, // s0_seq_debug.address
|
||||||
|
output wire s0_seq_debug_write, // .write
|
||||||
|
output wire s0_seq_debug_read, // .read
|
||||||
|
input wire [31:0] s0_seq_debug_readdata, // .readdata
|
||||||
|
output wire [31:0] s0_seq_debug_writedata, // .writedata
|
||||||
|
output wire [0:0] s0_seq_debug_burstcount, // .burstcount
|
||||||
|
output wire [3:0] s0_seq_debug_byteenable, // .byteenable
|
||||||
|
input wire s0_seq_debug_readdatavalid, // .readdatavalid
|
||||||
|
input wire s0_seq_debug_waitrequest // .waitrequest
|
||||||
|
);
|
||||||
|
|
||||||
|
wire dmaster_master_translator_avalon_universal_master_0_waitrequest; // s0_seq_debug_translator:uav_waitrequest -> dmaster_master_translator:uav_waitrequest
|
||||||
|
wire [31:0] dmaster_master_translator_avalon_universal_master_0_readdata; // s0_seq_debug_translator:uav_readdata -> dmaster_master_translator:uav_readdata
|
||||||
|
wire dmaster_master_translator_avalon_universal_master_0_debugaccess; // dmaster_master_translator:uav_debugaccess -> s0_seq_debug_translator:uav_debugaccess
|
||||||
|
wire [31:0] dmaster_master_translator_avalon_universal_master_0_address; // dmaster_master_translator:uav_address -> s0_seq_debug_translator:uav_address
|
||||||
|
wire dmaster_master_translator_avalon_universal_master_0_read; // dmaster_master_translator:uav_read -> s0_seq_debug_translator:uav_read
|
||||||
|
wire [3:0] dmaster_master_translator_avalon_universal_master_0_byteenable; // dmaster_master_translator:uav_byteenable -> s0_seq_debug_translator:uav_byteenable
|
||||||
|
wire dmaster_master_translator_avalon_universal_master_0_readdatavalid; // s0_seq_debug_translator:uav_readdatavalid -> dmaster_master_translator:uav_readdatavalid
|
||||||
|
wire dmaster_master_translator_avalon_universal_master_0_lock; // dmaster_master_translator:uav_lock -> s0_seq_debug_translator:uav_lock
|
||||||
|
wire dmaster_master_translator_avalon_universal_master_0_write; // dmaster_master_translator:uav_write -> s0_seq_debug_translator:uav_write
|
||||||
|
wire [31:0] dmaster_master_translator_avalon_universal_master_0_writedata; // dmaster_master_translator:uav_writedata -> s0_seq_debug_translator:uav_writedata
|
||||||
|
wire [2:0] dmaster_master_translator_avalon_universal_master_0_burstcount; // dmaster_master_translator:uav_burstcount -> s0_seq_debug_translator:uav_burstcount
|
||||||
|
|
||||||
|
altera_merlin_master_translator #(
|
||||||
|
.AV_ADDRESS_W (32),
|
||||||
|
.AV_DATA_W (32),
|
||||||
|
.AV_BURSTCOUNT_W (1),
|
||||||
|
.AV_BYTEENABLE_W (4),
|
||||||
|
.UAV_ADDRESS_W (32),
|
||||||
|
.UAV_BURSTCOUNT_W (3),
|
||||||
|
.USE_READ (1),
|
||||||
|
.USE_WRITE (1),
|
||||||
|
.USE_BEGINBURSTTRANSFER (0),
|
||||||
|
.USE_BEGINTRANSFER (0),
|
||||||
|
.USE_CHIPSELECT (0),
|
||||||
|
.USE_BURSTCOUNT (0),
|
||||||
|
.USE_READDATAVALID (1),
|
||||||
|
.USE_WAITREQUEST (1),
|
||||||
|
.USE_READRESPONSE (0),
|
||||||
|
.USE_WRITERESPONSE (0),
|
||||||
|
.AV_SYMBOLS_PER_WORD (4),
|
||||||
|
.AV_ADDRESS_SYMBOLS (1),
|
||||||
|
.AV_BURSTCOUNT_SYMBOLS (0),
|
||||||
|
.AV_CONSTANT_BURST_BEHAVIOR (0),
|
||||||
|
.UAV_CONSTANT_BURST_BEHAVIOR (0),
|
||||||
|
.AV_LINEWRAPBURSTS (0),
|
||||||
|
.AV_REGISTERINCOMINGSIGNALS (0)
|
||||||
|
) dmaster_master_translator (
|
||||||
|
.clk (p0_avl_clk_clk), // clk.clk
|
||||||
|
.reset (dmaster_master_translator_reset_reset_bridge_in_reset_reset), // reset.reset
|
||||||
|
.uav_address (dmaster_master_translator_avalon_universal_master_0_address), // avalon_universal_master_0.address
|
||||||
|
.uav_burstcount (dmaster_master_translator_avalon_universal_master_0_burstcount), // .burstcount
|
||||||
|
.uav_read (dmaster_master_translator_avalon_universal_master_0_read), // .read
|
||||||
|
.uav_write (dmaster_master_translator_avalon_universal_master_0_write), // .write
|
||||||
|
.uav_waitrequest (dmaster_master_translator_avalon_universal_master_0_waitrequest), // .waitrequest
|
||||||
|
.uav_readdatavalid (dmaster_master_translator_avalon_universal_master_0_readdatavalid), // .readdatavalid
|
||||||
|
.uav_byteenable (dmaster_master_translator_avalon_universal_master_0_byteenable), // .byteenable
|
||||||
|
.uav_readdata (dmaster_master_translator_avalon_universal_master_0_readdata), // .readdata
|
||||||
|
.uav_writedata (dmaster_master_translator_avalon_universal_master_0_writedata), // .writedata
|
||||||
|
.uav_lock (dmaster_master_translator_avalon_universal_master_0_lock), // .lock
|
||||||
|
.uav_debugaccess (dmaster_master_translator_avalon_universal_master_0_debugaccess), // .debugaccess
|
||||||
|
.av_address (dmaster_master_address), // avalon_anti_master_0.address
|
||||||
|
.av_waitrequest (dmaster_master_waitrequest), // .waitrequest
|
||||||
|
.av_byteenable (dmaster_master_byteenable), // .byteenable
|
||||||
|
.av_read (dmaster_master_read), // .read
|
||||||
|
.av_readdata (dmaster_master_readdata), // .readdata
|
||||||
|
.av_readdatavalid (dmaster_master_readdatavalid), // .readdatavalid
|
||||||
|
.av_write (dmaster_master_write), // .write
|
||||||
|
.av_writedata (dmaster_master_writedata), // .writedata
|
||||||
|
.av_burstcount (1'b1), // (terminated)
|
||||||
|
.av_beginbursttransfer (1'b0), // (terminated)
|
||||||
|
.av_begintransfer (1'b0), // (terminated)
|
||||||
|
.av_chipselect (1'b0), // (terminated)
|
||||||
|
.av_lock (1'b0), // (terminated)
|
||||||
|
.av_debugaccess (1'b0), // (terminated)
|
||||||
|
.uav_clken (), // (terminated)
|
||||||
|
.av_clken (1'b1), // (terminated)
|
||||||
|
.uav_response (2'b00), // (terminated)
|
||||||
|
.av_response (), // (terminated)
|
||||||
|
.uav_writeresponsevalid (1'b0), // (terminated)
|
||||||
|
.av_writeresponsevalid () // (terminated)
|
||||||
|
);
|
||||||
|
|
||||||
|
altera_merlin_slave_translator #(
|
||||||
|
.AV_ADDRESS_W (32),
|
||||||
|
.AV_DATA_W (32),
|
||||||
|
.UAV_DATA_W (32),
|
||||||
|
.AV_BURSTCOUNT_W (1),
|
||||||
|
.AV_BYTEENABLE_W (4),
|
||||||
|
.UAV_BYTEENABLE_W (4),
|
||||||
|
.UAV_ADDRESS_W (32),
|
||||||
|
.UAV_BURSTCOUNT_W (3),
|
||||||
|
.AV_READLATENCY (0),
|
||||||
|
.USE_READDATAVALID (1),
|
||||||
|
.USE_WAITREQUEST (1),
|
||||||
|
.USE_UAV_CLKEN (0),
|
||||||
|
.USE_READRESPONSE (0),
|
||||||
|
.USE_WRITERESPONSE (0),
|
||||||
|
.AV_SYMBOLS_PER_WORD (4),
|
||||||
|
.AV_ADDRESS_SYMBOLS (1),
|
||||||
|
.AV_BURSTCOUNT_SYMBOLS (0),
|
||||||
|
.AV_CONSTANT_BURST_BEHAVIOR (0),
|
||||||
|
.UAV_CONSTANT_BURST_BEHAVIOR (0),
|
||||||
|
.AV_REQUIRE_UNALIGNED_ADDRESSES (0),
|
||||||
|
.CHIPSELECT_THROUGH_READLATENCY (0),
|
||||||
|
.AV_READ_WAIT_CYCLES (1),
|
||||||
|
.AV_WRITE_WAIT_CYCLES (0),
|
||||||
|
.AV_SETUP_WAIT_CYCLES (0),
|
||||||
|
.AV_DATA_HOLD_CYCLES (0)
|
||||||
|
) s0_seq_debug_translator (
|
||||||
|
.clk (p0_avl_clk_clk), // clk.clk
|
||||||
|
.reset (dmaster_master_translator_reset_reset_bridge_in_reset_reset), // reset.reset
|
||||||
|
.uav_address (dmaster_master_translator_avalon_universal_master_0_address), // avalon_universal_slave_0.address
|
||||||
|
.uav_burstcount (dmaster_master_translator_avalon_universal_master_0_burstcount), // .burstcount
|
||||||
|
.uav_read (dmaster_master_translator_avalon_universal_master_0_read), // .read
|
||||||
|
.uav_write (dmaster_master_translator_avalon_universal_master_0_write), // .write
|
||||||
|
.uav_waitrequest (dmaster_master_translator_avalon_universal_master_0_waitrequest), // .waitrequest
|
||||||
|
.uav_readdatavalid (dmaster_master_translator_avalon_universal_master_0_readdatavalid), // .readdatavalid
|
||||||
|
.uav_byteenable (dmaster_master_translator_avalon_universal_master_0_byteenable), // .byteenable
|
||||||
|
.uav_readdata (dmaster_master_translator_avalon_universal_master_0_readdata), // .readdata
|
||||||
|
.uav_writedata (dmaster_master_translator_avalon_universal_master_0_writedata), // .writedata
|
||||||
|
.uav_lock (dmaster_master_translator_avalon_universal_master_0_lock), // .lock
|
||||||
|
.uav_debugaccess (dmaster_master_translator_avalon_universal_master_0_debugaccess), // .debugaccess
|
||||||
|
.av_address (s0_seq_debug_address), // avalon_anti_slave_0.address
|
||||||
|
.av_write (s0_seq_debug_write), // .write
|
||||||
|
.av_read (s0_seq_debug_read), // .read
|
||||||
|
.av_readdata (s0_seq_debug_readdata), // .readdata
|
||||||
|
.av_writedata (s0_seq_debug_writedata), // .writedata
|
||||||
|
.av_burstcount (s0_seq_debug_burstcount), // .burstcount
|
||||||
|
.av_byteenable (s0_seq_debug_byteenable), // .byteenable
|
||||||
|
.av_readdatavalid (s0_seq_debug_readdatavalid), // .readdatavalid
|
||||||
|
.av_waitrequest (s0_seq_debug_waitrequest), // .waitrequest
|
||||||
|
.av_begintransfer (), // (terminated)
|
||||||
|
.av_beginbursttransfer (), // (terminated)
|
||||||
|
.av_writebyteenable (), // (terminated)
|
||||||
|
.av_lock (), // (terminated)
|
||||||
|
.av_chipselect (), // (terminated)
|
||||||
|
.av_clken (), // (terminated)
|
||||||
|
.uav_clken (1'b0), // (terminated)
|
||||||
|
.av_debugaccess (), // (terminated)
|
||||||
|
.av_outputenable (), // (terminated)
|
||||||
|
.uav_response (), // (terminated)
|
||||||
|
.av_response (2'b00), // (terminated)
|
||||||
|
.uav_writeresponsevalid (), // (terminated)
|
||||||
|
.av_writeresponsevalid (1'b0) // (terminated)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
1227
ip/altera/ddr3/ddr3_mm_interconnect_2.v
Normal file
1227
ip/altera/ddr3/ddr3_mm_interconnect_2.v
Normal file
File diff suppressed because it is too large
Load Diff
202
ip/altera/ddr3/ddr3_mm_interconnect_2_avalon_st_adapter.v
Normal file
202
ip/altera/ddr3/ddr3_mm_interconnect_2_avalon_st_adapter.v
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
// ddr3_mm_interconnect_2_avalon_st_adapter.v
|
||||||
|
|
||||||
|
// This file was auto-generated from altera_avalon_st_adapter_hw.tcl. If you edit it your changes
|
||||||
|
// will probably be lost.
|
||||||
|
//
|
||||||
|
// Generated using ACDS version 15.1 185
|
||||||
|
|
||||||
|
`timescale 1 ps / 1 ps
|
||||||
|
module ddr3_mm_interconnect_2_avalon_st_adapter #(
|
||||||
|
parameter inBitsPerSymbol = 34,
|
||||||
|
parameter inUsePackets = 0,
|
||||||
|
parameter inDataWidth = 34,
|
||||||
|
parameter inChannelWidth = 0,
|
||||||
|
parameter inErrorWidth = 0,
|
||||||
|
parameter inUseEmptyPort = 0,
|
||||||
|
parameter inUseValid = 1,
|
||||||
|
parameter inUseReady = 1,
|
||||||
|
parameter inReadyLatency = 0,
|
||||||
|
parameter outDataWidth = 34,
|
||||||
|
parameter outChannelWidth = 0,
|
||||||
|
parameter outErrorWidth = 1,
|
||||||
|
parameter outUseEmptyPort = 0,
|
||||||
|
parameter outUseValid = 1,
|
||||||
|
parameter outUseReady = 1,
|
||||||
|
parameter outReadyLatency = 0
|
||||||
|
) (
|
||||||
|
input wire in_clk_0_clk, // in_clk_0.clk
|
||||||
|
input wire in_rst_0_reset, // in_rst_0.reset
|
||||||
|
input wire [33:0] in_0_data, // in_0.data
|
||||||
|
input wire in_0_valid, // .valid
|
||||||
|
output wire in_0_ready, // .ready
|
||||||
|
output wire [33:0] out_0_data, // out_0.data
|
||||||
|
output wire out_0_valid, // .valid
|
||||||
|
input wire out_0_ready, // .ready
|
||||||
|
output wire [0:0] out_0_error // .error
|
||||||
|
);
|
||||||
|
|
||||||
|
generate
|
||||||
|
// If any of the display statements (or deliberately broken
|
||||||
|
// instantiations) within this generate block triggers then this module
|
||||||
|
// has been instantiated this module with a set of parameters different
|
||||||
|
// from those it was generated for. This will usually result in a
|
||||||
|
// non-functioning system.
|
||||||
|
if (inBitsPerSymbol != 34)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inbitspersymbol_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUsePackets != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inusepackets_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inDataWidth != 34)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
indatawidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inChannelWidth != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inchannelwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inErrorWidth != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inerrorwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUseEmptyPort != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inuseemptyport_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUseValid != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inusevalid_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUseReady != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inuseready_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inReadyLatency != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inreadylatency_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outDataWidth != 34)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outdatawidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outChannelWidth != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outchannelwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outErrorWidth != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outerrorwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outUseEmptyPort != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outuseemptyport_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outUseValid != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outusevalid_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outUseReady != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outuseready_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outReadyLatency != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outreadylatency_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
ddr3_mm_interconnect_2_avalon_st_adapter_error_adapter_0 error_adapter_0 (
|
||||||
|
.clk (in_clk_0_clk), // clk.clk
|
||||||
|
.reset_n (~in_rst_0_reset), // reset.reset_n
|
||||||
|
.in_data (in_0_data), // in.data
|
||||||
|
.in_valid (in_0_valid), // .valid
|
||||||
|
.in_ready (in_0_ready), // .ready
|
||||||
|
.out_data (out_0_data), // out.data
|
||||||
|
.out_valid (out_0_valid), // .valid
|
||||||
|
.out_ready (out_0_ready), // .ready
|
||||||
|
.out_error (out_0_error) // .error
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
202
ip/altera/ddr3/ddr3_mm_interconnect_2_avalon_st_adapter_001.v
Normal file
202
ip/altera/ddr3/ddr3_mm_interconnect_2_avalon_st_adapter_001.v
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
// ddr3_mm_interconnect_2_avalon_st_adapter_001.v
|
||||||
|
|
||||||
|
// This file was auto-generated from altera_avalon_st_adapter_hw.tcl. If you edit it your changes
|
||||||
|
// will probably be lost.
|
||||||
|
//
|
||||||
|
// Generated using ACDS version 15.1 185
|
||||||
|
|
||||||
|
`timescale 1 ps / 1 ps
|
||||||
|
module ddr3_mm_interconnect_2_avalon_st_adapter_001 #(
|
||||||
|
parameter inBitsPerSymbol = 10,
|
||||||
|
parameter inUsePackets = 0,
|
||||||
|
parameter inDataWidth = 10,
|
||||||
|
parameter inChannelWidth = 0,
|
||||||
|
parameter inErrorWidth = 0,
|
||||||
|
parameter inUseEmptyPort = 0,
|
||||||
|
parameter inUseValid = 1,
|
||||||
|
parameter inUseReady = 1,
|
||||||
|
parameter inReadyLatency = 0,
|
||||||
|
parameter outDataWidth = 10,
|
||||||
|
parameter outChannelWidth = 0,
|
||||||
|
parameter outErrorWidth = 1,
|
||||||
|
parameter outUseEmptyPort = 0,
|
||||||
|
parameter outUseValid = 1,
|
||||||
|
parameter outUseReady = 1,
|
||||||
|
parameter outReadyLatency = 0
|
||||||
|
) (
|
||||||
|
input wire in_clk_0_clk, // in_clk_0.clk
|
||||||
|
input wire in_rst_0_reset, // in_rst_0.reset
|
||||||
|
input wire [9:0] in_0_data, // in_0.data
|
||||||
|
input wire in_0_valid, // .valid
|
||||||
|
output wire in_0_ready, // .ready
|
||||||
|
output wire [9:0] out_0_data, // out_0.data
|
||||||
|
output wire out_0_valid, // .valid
|
||||||
|
input wire out_0_ready, // .ready
|
||||||
|
output wire [0:0] out_0_error // .error
|
||||||
|
);
|
||||||
|
|
||||||
|
generate
|
||||||
|
// If any of the display statements (or deliberately broken
|
||||||
|
// instantiations) within this generate block triggers then this module
|
||||||
|
// has been instantiated this module with a set of parameters different
|
||||||
|
// from those it was generated for. This will usually result in a
|
||||||
|
// non-functioning system.
|
||||||
|
if (inBitsPerSymbol != 10)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inbitspersymbol_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUsePackets != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inusepackets_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inDataWidth != 10)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
indatawidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inChannelWidth != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inchannelwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inErrorWidth != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inerrorwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUseEmptyPort != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inuseemptyport_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUseValid != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inusevalid_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inUseReady != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inuseready_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (inReadyLatency != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
inreadylatency_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outDataWidth != 10)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outdatawidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outChannelWidth != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outchannelwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outErrorWidth != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outerrorwidth_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outUseEmptyPort != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outuseemptyport_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outUseValid != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outusevalid_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outUseReady != 1)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outuseready_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
if (outReadyLatency != 0)
|
||||||
|
begin
|
||||||
|
initial begin
|
||||||
|
$display("Generated module instantiated with wrong parameters");
|
||||||
|
$stop;
|
||||||
|
end
|
||||||
|
instantiated_with_wrong_parameters_error_see_comment_above
|
||||||
|
outreadylatency_check ( .error(1'b1) );
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
ddr3_mm_interconnect_2_avalon_st_adapter_001_error_adapter_0 error_adapter_0 (
|
||||||
|
.clk (in_clk_0_clk), // clk.clk
|
||||||
|
.reset_n (~in_rst_0_reset), // reset.reset_n
|
||||||
|
.in_data (in_0_data), // in.data
|
||||||
|
.in_valid (in_0_valid), // .valid
|
||||||
|
.in_ready (in_0_ready), // .ready
|
||||||
|
.out_data (out_0_data), // out.data
|
||||||
|
.out_valid (out_0_valid), // .valid
|
||||||
|
.out_ready (out_0_ready), // .ready
|
||||||
|
.out_error (out_0_error) // .error
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
@ -0,0 +1,107 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2013 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/13.1/ip/.../avalon-st_error_adapter.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2013/09/09 $
|
||||||
|
// $Author: dmunday $
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon Streaming Error Adapter
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_mm_interconnect_2_avalon_st_adapter_001_error_adapter_0
|
||||||
|
// use_ready: true
|
||||||
|
// use_packets: false
|
||||||
|
// use_empty: 0
|
||||||
|
// empty_width: 0
|
||||||
|
// data_width: 10
|
||||||
|
// channel_width: 0
|
||||||
|
// in_error_width: 0
|
||||||
|
// out_error_width: 1
|
||||||
|
// in_errors_list
|
||||||
|
// in_errors_indices 0
|
||||||
|
// out_errors_list
|
||||||
|
// has_in_error_desc: FALSE
|
||||||
|
// has_out_error_desc: FALSE
|
||||||
|
// out_has_other: FALSE
|
||||||
|
// out_other_index: -1
|
||||||
|
// dumpVar:
|
||||||
|
// inString: in_error[
|
||||||
|
// closeString: ] |
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_avalon_st_adapter_001_error_adapter_0
|
||||||
|
(
|
||||||
|
// Interface: in
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [10-1: 0] in_data,
|
||||||
|
// Interface: out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [10-1: 0] out_data,
|
||||||
|
output reg [0:0] out_error,
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
// Interface: reset
|
||||||
|
input reset_n
|
||||||
|
|
||||||
|
/*AUTOARG*/);
|
||||||
|
|
||||||
|
reg in_error = 0;
|
||||||
|
initial in_error = 0;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Pass-through Mapping
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
in_ready = out_ready;
|
||||||
|
out_valid = in_valid;
|
||||||
|
out_data = in_data;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Error Mapping
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
out_error = 0;
|
||||||
|
|
||||||
|
out_error = in_error;
|
||||||
|
|
||||||
|
end //always @*
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,107 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2013 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/13.1/ip/.../avalon-st_error_adapter.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2013/09/09 $
|
||||||
|
// $Author: dmunday $
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
//| Avalon Streaming Error Adapter
|
||||||
|
// --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1ns / 100ps
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_mm_interconnect_2_avalon_st_adapter_error_adapter_0
|
||||||
|
// use_ready: true
|
||||||
|
// use_packets: false
|
||||||
|
// use_empty: 0
|
||||||
|
// empty_width: 0
|
||||||
|
// data_width: 34
|
||||||
|
// channel_width: 0
|
||||||
|
// in_error_width: 0
|
||||||
|
// out_error_width: 1
|
||||||
|
// in_errors_list
|
||||||
|
// in_errors_indices 0
|
||||||
|
// out_errors_list
|
||||||
|
// has_in_error_desc: FALSE
|
||||||
|
// has_out_error_desc: FALSE
|
||||||
|
// out_has_other: FALSE
|
||||||
|
// out_other_index: -1
|
||||||
|
// dumpVar:
|
||||||
|
// inString: in_error[
|
||||||
|
// closeString: ] |
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_avalon_st_adapter_error_adapter_0
|
||||||
|
(
|
||||||
|
// Interface: in
|
||||||
|
output reg in_ready,
|
||||||
|
input in_valid,
|
||||||
|
input [34-1: 0] in_data,
|
||||||
|
// Interface: out
|
||||||
|
input out_ready,
|
||||||
|
output reg out_valid,
|
||||||
|
output reg [34-1: 0] out_data,
|
||||||
|
output reg [0:0] out_error,
|
||||||
|
// Interface: clk
|
||||||
|
input clk,
|
||||||
|
// Interface: reset
|
||||||
|
input reset_n
|
||||||
|
|
||||||
|
/*AUTOARG*/);
|
||||||
|
|
||||||
|
reg in_error = 0;
|
||||||
|
initial in_error = 0;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Pass-through Mapping
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
in_ready = out_ready;
|
||||||
|
out_valid = in_valid;
|
||||||
|
out_data = in_data;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
//| Error Mapping
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
always_comb begin
|
||||||
|
out_error = 0;
|
||||||
|
|
||||||
|
out_error = in_error;
|
||||||
|
|
||||||
|
end //always @*
|
||||||
|
endmodule
|
||||||
|
|
116
ip/altera/ddr3/ddr3_mm_interconnect_2_cmd_demux.sv
Normal file
116
ip/altera/ddr3/ddr3_mm_interconnect_2_cmd_demux.sv
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_demultiplexer/altera_merlin_demultiplexer.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Merlin Demultiplexer
|
||||||
|
//
|
||||||
|
// Asserts valid on the appropriate output
|
||||||
|
// given a one-hot channel signal.
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_mm_interconnect_2_cmd_demux
|
||||||
|
// ST_DATA_W: 102
|
||||||
|
// ST_CHANNEL_W: 2
|
||||||
|
// NUM_OUTPUTS: 2
|
||||||
|
// VALID_WIDTH: 2
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
// Message Supression Used
|
||||||
|
// QIS Warnings
|
||||||
|
// 15610 - Warning: Design contains x input pin(s) that do not drive logic
|
||||||
|
//------------------------------------------
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_cmd_demux
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Sink
|
||||||
|
// -------------------
|
||||||
|
input [2-1 : 0] sink_valid,
|
||||||
|
input [102-1 : 0] sink_data, // ST_DATA_W=102
|
||||||
|
input [2-1 : 0] sink_channel, // ST_CHANNEL_W=2
|
||||||
|
input sink_startofpacket,
|
||||||
|
input sink_endofpacket,
|
||||||
|
output sink_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Sources
|
||||||
|
// -------------------
|
||||||
|
output reg src0_valid,
|
||||||
|
output reg [102-1 : 0] src0_data, // ST_DATA_W=102
|
||||||
|
output reg [2-1 : 0] src0_channel, // ST_CHANNEL_W=2
|
||||||
|
output reg src0_startofpacket,
|
||||||
|
output reg src0_endofpacket,
|
||||||
|
input src0_ready,
|
||||||
|
|
||||||
|
output reg src1_valid,
|
||||||
|
output reg [102-1 : 0] src1_data, // ST_DATA_W=102
|
||||||
|
output reg [2-1 : 0] src1_channel, // ST_CHANNEL_W=2
|
||||||
|
output reg src1_startofpacket,
|
||||||
|
output reg src1_endofpacket,
|
||||||
|
input src1_ready,
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
(*altera_attribute = "-name MESSAGE_DISABLE 15610" *) // setting message suppression on clk
|
||||||
|
input clk,
|
||||||
|
(*altera_attribute = "-name MESSAGE_DISABLE 15610" *) // setting message suppression on reset
|
||||||
|
input reset
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam NUM_OUTPUTS = 2;
|
||||||
|
wire [NUM_OUTPUTS - 1 : 0] ready_vector;
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Demux
|
||||||
|
// -------------------
|
||||||
|
always @* begin
|
||||||
|
src0_data = sink_data;
|
||||||
|
src0_startofpacket = sink_startofpacket;
|
||||||
|
src0_endofpacket = sink_endofpacket;
|
||||||
|
src0_channel = sink_channel >> NUM_OUTPUTS;
|
||||||
|
|
||||||
|
src0_valid = sink_channel[0] && sink_valid[0];
|
||||||
|
|
||||||
|
src1_data = sink_data;
|
||||||
|
src1_startofpacket = sink_startofpacket;
|
||||||
|
src1_endofpacket = sink_endofpacket;
|
||||||
|
src1_channel = sink_channel >> NUM_OUTPUTS;
|
||||||
|
|
||||||
|
src1_valid = sink_channel[1] && sink_valid[1];
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Backpressure
|
||||||
|
// -------------------
|
||||||
|
assign ready_vector[0] = src0_ready;
|
||||||
|
assign ready_vector[1] = src1_ready;
|
||||||
|
|
||||||
|
assign sink_ready = |(sink_channel & ready_vector);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
97
ip/altera/ddr3/ddr3_mm_interconnect_2_cmd_mux.sv
Normal file
97
ip/altera/ddr3/ddr3_mm_interconnect_2_cmd_mux.sv
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2014 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_multiplexer/altera_merlin_multiplexer.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Merlin Multiplexer
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_mm_interconnect_2_cmd_mux
|
||||||
|
// NUM_INPUTS: 1
|
||||||
|
// ARBITRATION_SHARES: 1
|
||||||
|
// ARBITRATION_SCHEME "round-robin"
|
||||||
|
// PIPELINE_ARB: 0
|
||||||
|
// PKT_TRANS_LOCK: 72 (arbitration locking enabled)
|
||||||
|
// ST_DATA_W: 102
|
||||||
|
// ST_CHANNEL_W: 2
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_cmd_mux
|
||||||
|
(
|
||||||
|
// ----------------------
|
||||||
|
// Sinks
|
||||||
|
// ----------------------
|
||||||
|
input sink0_valid,
|
||||||
|
input [102-1 : 0] sink0_data,
|
||||||
|
input [2-1: 0] sink0_channel,
|
||||||
|
input sink0_startofpacket,
|
||||||
|
input sink0_endofpacket,
|
||||||
|
output sink0_ready,
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// Source
|
||||||
|
// ----------------------
|
||||||
|
output src_valid,
|
||||||
|
output [102-1 : 0] src_data,
|
||||||
|
output [2-1 : 0] src_channel,
|
||||||
|
output src_startofpacket,
|
||||||
|
output src_endofpacket,
|
||||||
|
input src_ready,
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// ----------------------
|
||||||
|
input clk,
|
||||||
|
input reset
|
||||||
|
);
|
||||||
|
localparam PAYLOAD_W = 102 + 2 + 2;
|
||||||
|
localparam NUM_INPUTS = 1;
|
||||||
|
localparam SHARE_COUNTER_W = 1;
|
||||||
|
localparam PIPELINE_ARB = 0;
|
||||||
|
localparam ST_DATA_W = 102;
|
||||||
|
localparam ST_CHANNEL_W = 2;
|
||||||
|
localparam PKT_TRANS_LOCK = 72;
|
||||||
|
|
||||||
|
assign src_valid = sink0_valid;
|
||||||
|
assign src_data = sink0_data;
|
||||||
|
assign src_channel = sink0_channel;
|
||||||
|
assign src_startofpacket = sink0_startofpacket;
|
||||||
|
assign src_endofpacket = sink0_endofpacket;
|
||||||
|
assign sink0_ready = src_ready;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
227
ip/altera/ddr3/ddr3_mm_interconnect_2_router.sv
Normal file
227
ip/altera/ddr3/ddr3_mm_interconnect_2_router.sv
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_router/altera_merlin_router.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Merlin Router
|
||||||
|
//
|
||||||
|
// Asserts the appropriate one-hot encoded channel based on
|
||||||
|
// either (a) the address or (b) the dest id. The DECODER_TYPE
|
||||||
|
// parameter controls this behaviour. 0 means address decoder,
|
||||||
|
// 1 means dest id decoder.
|
||||||
|
//
|
||||||
|
// In the case of (a), it also sets the destination id.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_router_default_decode
|
||||||
|
#(
|
||||||
|
parameter DEFAULT_CHANNEL = 0,
|
||||||
|
DEFAULT_WR_CHANNEL = -1,
|
||||||
|
DEFAULT_RD_CHANNEL = -1,
|
||||||
|
DEFAULT_DESTID = 1
|
||||||
|
)
|
||||||
|
(output [88 - 88 : 0] default_destination_id,
|
||||||
|
output [2-1 : 0] default_wr_channel,
|
||||||
|
output [2-1 : 0] default_rd_channel,
|
||||||
|
output [2-1 : 0] default_src_channel
|
||||||
|
);
|
||||||
|
|
||||||
|
assign default_destination_id =
|
||||||
|
DEFAULT_DESTID[88 - 88 : 0];
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (DEFAULT_CHANNEL == -1) begin : no_default_channel_assignment
|
||||||
|
assign default_src_channel = '0;
|
||||||
|
end
|
||||||
|
else begin : default_channel_assignment
|
||||||
|
assign default_src_channel = 2'b1 << DEFAULT_CHANNEL;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (DEFAULT_RD_CHANNEL == -1) begin : no_default_rw_channel_assignment
|
||||||
|
assign default_wr_channel = '0;
|
||||||
|
assign default_rd_channel = '0;
|
||||||
|
end
|
||||||
|
else begin : default_rw_channel_assignment
|
||||||
|
assign default_wr_channel = 2'b1 << DEFAULT_WR_CHANNEL;
|
||||||
|
assign default_rd_channel = 2'b1 << DEFAULT_RD_CHANNEL;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_router
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Sink (Input)
|
||||||
|
// -------------------
|
||||||
|
input sink_valid,
|
||||||
|
input [102-1 : 0] sink_data,
|
||||||
|
input sink_startofpacket,
|
||||||
|
input sink_endofpacket,
|
||||||
|
output sink_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Source (Output)
|
||||||
|
// -------------------
|
||||||
|
output src_valid,
|
||||||
|
output reg [102-1 : 0] src_data,
|
||||||
|
output reg [2-1 : 0] src_channel,
|
||||||
|
output src_startofpacket,
|
||||||
|
output src_endofpacket,
|
||||||
|
input src_ready
|
||||||
|
);
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Local parameters and variables
|
||||||
|
// -------------------------------------------------------
|
||||||
|
localparam PKT_ADDR_H = 67;
|
||||||
|
localparam PKT_ADDR_L = 36;
|
||||||
|
localparam PKT_DEST_ID_H = 88;
|
||||||
|
localparam PKT_DEST_ID_L = 88;
|
||||||
|
localparam PKT_PROTECTION_H = 92;
|
||||||
|
localparam PKT_PROTECTION_L = 90;
|
||||||
|
localparam ST_DATA_W = 102;
|
||||||
|
localparam ST_CHANNEL_W = 2;
|
||||||
|
localparam DECODER_TYPE = 0;
|
||||||
|
|
||||||
|
localparam PKT_TRANS_WRITE = 70;
|
||||||
|
localparam PKT_TRANS_READ = 71;
|
||||||
|
|
||||||
|
localparam PKT_ADDR_W = PKT_ADDR_H-PKT_ADDR_L + 1;
|
||||||
|
localparam PKT_DEST_ID_W = PKT_DEST_ID_H-PKT_DEST_ID_L + 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Figure out the number of bits to mask off for each slave span
|
||||||
|
// during address decoding
|
||||||
|
// -------------------------------------------------------
|
||||||
|
localparam PAD0 = log2ceil(64'h400 - 64'h0);
|
||||||
|
localparam PAD1 = log2ceil(64'h800 - 64'h400);
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Work out which address bits are significant based on the
|
||||||
|
// address range of the slaves. If the required width is too
|
||||||
|
// large or too small, we use the address field width instead.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
localparam ADDR_RANGE = 64'h800;
|
||||||
|
localparam RANGE_ADDR_WIDTH = log2ceil(ADDR_RANGE);
|
||||||
|
localparam OPTIMIZED_ADDR_H = (RANGE_ADDR_WIDTH > PKT_ADDR_W) ||
|
||||||
|
(RANGE_ADDR_WIDTH == 0) ?
|
||||||
|
PKT_ADDR_H :
|
||||||
|
PKT_ADDR_L + RANGE_ADDR_WIDTH - 1;
|
||||||
|
|
||||||
|
localparam RG = RANGE_ADDR_WIDTH-1;
|
||||||
|
localparam REAL_ADDRESS_RANGE = OPTIMIZED_ADDR_H - PKT_ADDR_L;
|
||||||
|
|
||||||
|
reg [PKT_ADDR_W-1 : 0] address;
|
||||||
|
always @* begin
|
||||||
|
address = {PKT_ADDR_W{1'b0}};
|
||||||
|
address [REAL_ADDRESS_RANGE:0] = sink_data[OPTIMIZED_ADDR_H : PKT_ADDR_L];
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Pass almost everything through, untouched
|
||||||
|
// -------------------------------------------------------
|
||||||
|
assign sink_ready = src_ready;
|
||||||
|
assign src_valid = sink_valid;
|
||||||
|
assign src_startofpacket = sink_startofpacket;
|
||||||
|
assign src_endofpacket = sink_endofpacket;
|
||||||
|
wire [PKT_DEST_ID_W-1:0] default_destid;
|
||||||
|
wire [2-1 : 0] default_src_channel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ddr3_mm_interconnect_2_router_default_decode the_default_decode(
|
||||||
|
.default_destination_id (default_destid),
|
||||||
|
.default_wr_channel (),
|
||||||
|
.default_rd_channel (),
|
||||||
|
.default_src_channel (default_src_channel)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
src_data = sink_data;
|
||||||
|
src_channel = default_src_channel;
|
||||||
|
src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = default_destid;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Address Decoder
|
||||||
|
// Sets the channel and destination ID based on the address
|
||||||
|
// --------------------------------------------------
|
||||||
|
|
||||||
|
// ( 0x0 .. 0x400 )
|
||||||
|
if ( {address[RG:PAD0],{PAD0{1'b0}}} == 11'h0 ) begin
|
||||||
|
src_channel = 2'b01;
|
||||||
|
src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// ( 0x400 .. 0x800 )
|
||||||
|
if ( {address[RG:PAD1],{PAD1{1'b0}}} == 11'h400 ) begin
|
||||||
|
src_channel = 2'b10;
|
||||||
|
src_data[PKT_DEST_ID_H:PKT_DEST_ID_L] = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Ceil(log2()) function
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input reg[65:0] val;
|
||||||
|
reg [65:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
215
ip/altera/ddr3/ddr3_mm_interconnect_2_router_001.sv
Normal file
215
ip/altera/ddr3/ddr3_mm_interconnect_2_router_001.sv
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_router/altera_merlin_router.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Merlin Router
|
||||||
|
//
|
||||||
|
// Asserts the appropriate one-hot encoded channel based on
|
||||||
|
// either (a) the address or (b) the dest id. The DECODER_TYPE
|
||||||
|
// parameter controls this behaviour. 0 means address decoder,
|
||||||
|
// 1 means dest id decoder.
|
||||||
|
//
|
||||||
|
// In the case of (a), it also sets the destination id.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_router_001_default_decode
|
||||||
|
#(
|
||||||
|
parameter DEFAULT_CHANNEL = 0,
|
||||||
|
DEFAULT_WR_CHANNEL = -1,
|
||||||
|
DEFAULT_RD_CHANNEL = -1,
|
||||||
|
DEFAULT_DESTID = 0
|
||||||
|
)
|
||||||
|
(output [88 - 88 : 0] default_destination_id,
|
||||||
|
output [2-1 : 0] default_wr_channel,
|
||||||
|
output [2-1 : 0] default_rd_channel,
|
||||||
|
output [2-1 : 0] default_src_channel
|
||||||
|
);
|
||||||
|
|
||||||
|
assign default_destination_id =
|
||||||
|
DEFAULT_DESTID[88 - 88 : 0];
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (DEFAULT_CHANNEL == -1) begin : no_default_channel_assignment
|
||||||
|
assign default_src_channel = '0;
|
||||||
|
end
|
||||||
|
else begin : default_channel_assignment
|
||||||
|
assign default_src_channel = 2'b1 << DEFAULT_CHANNEL;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (DEFAULT_RD_CHANNEL == -1) begin : no_default_rw_channel_assignment
|
||||||
|
assign default_wr_channel = '0;
|
||||||
|
assign default_rd_channel = '0;
|
||||||
|
end
|
||||||
|
else begin : default_rw_channel_assignment
|
||||||
|
assign default_wr_channel = 2'b1 << DEFAULT_WR_CHANNEL;
|
||||||
|
assign default_rd_channel = 2'b1 << DEFAULT_RD_CHANNEL;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_router_001
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Sink (Input)
|
||||||
|
// -------------------
|
||||||
|
input sink_valid,
|
||||||
|
input [102-1 : 0] sink_data,
|
||||||
|
input sink_startofpacket,
|
||||||
|
input sink_endofpacket,
|
||||||
|
output sink_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Source (Output)
|
||||||
|
// -------------------
|
||||||
|
output src_valid,
|
||||||
|
output reg [102-1 : 0] src_data,
|
||||||
|
output reg [2-1 : 0] src_channel,
|
||||||
|
output src_startofpacket,
|
||||||
|
output src_endofpacket,
|
||||||
|
input src_ready
|
||||||
|
);
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Local parameters and variables
|
||||||
|
// -------------------------------------------------------
|
||||||
|
localparam PKT_ADDR_H = 67;
|
||||||
|
localparam PKT_ADDR_L = 36;
|
||||||
|
localparam PKT_DEST_ID_H = 88;
|
||||||
|
localparam PKT_DEST_ID_L = 88;
|
||||||
|
localparam PKT_PROTECTION_H = 92;
|
||||||
|
localparam PKT_PROTECTION_L = 90;
|
||||||
|
localparam ST_DATA_W = 102;
|
||||||
|
localparam ST_CHANNEL_W = 2;
|
||||||
|
localparam DECODER_TYPE = 1;
|
||||||
|
|
||||||
|
localparam PKT_TRANS_WRITE = 70;
|
||||||
|
localparam PKT_TRANS_READ = 71;
|
||||||
|
|
||||||
|
localparam PKT_ADDR_W = PKT_ADDR_H-PKT_ADDR_L + 1;
|
||||||
|
localparam PKT_DEST_ID_W = PKT_DEST_ID_H-PKT_DEST_ID_L + 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Figure out the number of bits to mask off for each slave span
|
||||||
|
// during address decoding
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Work out which address bits are significant based on the
|
||||||
|
// address range of the slaves. If the required width is too
|
||||||
|
// large or too small, we use the address field width instead.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
localparam ADDR_RANGE = 64'h0;
|
||||||
|
localparam RANGE_ADDR_WIDTH = log2ceil(ADDR_RANGE);
|
||||||
|
localparam OPTIMIZED_ADDR_H = (RANGE_ADDR_WIDTH > PKT_ADDR_W) ||
|
||||||
|
(RANGE_ADDR_WIDTH == 0) ?
|
||||||
|
PKT_ADDR_H :
|
||||||
|
PKT_ADDR_L + RANGE_ADDR_WIDTH - 1;
|
||||||
|
|
||||||
|
localparam RG = RANGE_ADDR_WIDTH;
|
||||||
|
localparam REAL_ADDRESS_RANGE = OPTIMIZED_ADDR_H - PKT_ADDR_L;
|
||||||
|
|
||||||
|
reg [PKT_DEST_ID_W-1 : 0] destid;
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Pass almost everything through, untouched
|
||||||
|
// -------------------------------------------------------
|
||||||
|
assign sink_ready = src_ready;
|
||||||
|
assign src_valid = sink_valid;
|
||||||
|
assign src_startofpacket = sink_startofpacket;
|
||||||
|
assign src_endofpacket = sink_endofpacket;
|
||||||
|
wire [2-1 : 0] default_src_channel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ddr3_mm_interconnect_2_router_001_default_decode the_default_decode(
|
||||||
|
.default_destination_id (),
|
||||||
|
.default_wr_channel (),
|
||||||
|
.default_rd_channel (),
|
||||||
|
.default_src_channel (default_src_channel)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
src_data = sink_data;
|
||||||
|
src_channel = default_src_channel;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// DestinationID Decoder
|
||||||
|
// Sets the channel based on the destination ID.
|
||||||
|
// --------------------------------------------------
|
||||||
|
destid = sink_data[PKT_DEST_ID_H : PKT_DEST_ID_L];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (destid == 0 ) begin
|
||||||
|
src_channel = 2'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Ceil(log2()) function
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input reg[65:0] val;
|
||||||
|
reg [65:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
215
ip/altera/ddr3/ddr3_mm_interconnect_2_router_002.sv
Normal file
215
ip/altera/ddr3/ddr3_mm_interconnect_2_router_002.sv
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_router/altera_merlin_router.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Merlin Router
|
||||||
|
//
|
||||||
|
// Asserts the appropriate one-hot encoded channel based on
|
||||||
|
// either (a) the address or (b) the dest id. The DECODER_TYPE
|
||||||
|
// parameter controls this behaviour. 0 means address decoder,
|
||||||
|
// 1 means dest id decoder.
|
||||||
|
//
|
||||||
|
// In the case of (a), it also sets the destination id.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_router_002_default_decode
|
||||||
|
#(
|
||||||
|
parameter DEFAULT_CHANNEL = 0,
|
||||||
|
DEFAULT_WR_CHANNEL = -1,
|
||||||
|
DEFAULT_RD_CHANNEL = -1,
|
||||||
|
DEFAULT_DESTID = 0
|
||||||
|
)
|
||||||
|
(output [61 - 61 : 0] default_destination_id,
|
||||||
|
output [2-1 : 0] default_wr_channel,
|
||||||
|
output [2-1 : 0] default_rd_channel,
|
||||||
|
output [2-1 : 0] default_src_channel
|
||||||
|
);
|
||||||
|
|
||||||
|
assign default_destination_id =
|
||||||
|
DEFAULT_DESTID[61 - 61 : 0];
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (DEFAULT_CHANNEL == -1) begin : no_default_channel_assignment
|
||||||
|
assign default_src_channel = '0;
|
||||||
|
end
|
||||||
|
else begin : default_channel_assignment
|
||||||
|
assign default_src_channel = 2'b1 << DEFAULT_CHANNEL;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (DEFAULT_RD_CHANNEL == -1) begin : no_default_rw_channel_assignment
|
||||||
|
assign default_wr_channel = '0;
|
||||||
|
assign default_rd_channel = '0;
|
||||||
|
end
|
||||||
|
else begin : default_rw_channel_assignment
|
||||||
|
assign default_wr_channel = 2'b1 << DEFAULT_WR_CHANNEL;
|
||||||
|
assign default_rd_channel = 2'b1 << DEFAULT_RD_CHANNEL;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_router_002
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
input clk,
|
||||||
|
input reset,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Sink (Input)
|
||||||
|
// -------------------
|
||||||
|
input sink_valid,
|
||||||
|
input [75-1 : 0] sink_data,
|
||||||
|
input sink_startofpacket,
|
||||||
|
input sink_endofpacket,
|
||||||
|
output sink_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Command Source (Output)
|
||||||
|
// -------------------
|
||||||
|
output src_valid,
|
||||||
|
output reg [75-1 : 0] src_data,
|
||||||
|
output reg [2-1 : 0] src_channel,
|
||||||
|
output src_startofpacket,
|
||||||
|
output src_endofpacket,
|
||||||
|
input src_ready
|
||||||
|
);
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Local parameters and variables
|
||||||
|
// -------------------------------------------------------
|
||||||
|
localparam PKT_ADDR_H = 40;
|
||||||
|
localparam PKT_ADDR_L = 9;
|
||||||
|
localparam PKT_DEST_ID_H = 61;
|
||||||
|
localparam PKT_DEST_ID_L = 61;
|
||||||
|
localparam PKT_PROTECTION_H = 65;
|
||||||
|
localparam PKT_PROTECTION_L = 63;
|
||||||
|
localparam ST_DATA_W = 75;
|
||||||
|
localparam ST_CHANNEL_W = 2;
|
||||||
|
localparam DECODER_TYPE = 1;
|
||||||
|
|
||||||
|
localparam PKT_TRANS_WRITE = 43;
|
||||||
|
localparam PKT_TRANS_READ = 44;
|
||||||
|
|
||||||
|
localparam PKT_ADDR_W = PKT_ADDR_H-PKT_ADDR_L + 1;
|
||||||
|
localparam PKT_DEST_ID_W = PKT_DEST_ID_H-PKT_DEST_ID_L + 1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Figure out the number of bits to mask off for each slave span
|
||||||
|
// during address decoding
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Work out which address bits are significant based on the
|
||||||
|
// address range of the slaves. If the required width is too
|
||||||
|
// large or too small, we use the address field width instead.
|
||||||
|
// -------------------------------------------------------
|
||||||
|
localparam ADDR_RANGE = 64'h0;
|
||||||
|
localparam RANGE_ADDR_WIDTH = log2ceil(ADDR_RANGE);
|
||||||
|
localparam OPTIMIZED_ADDR_H = (RANGE_ADDR_WIDTH > PKT_ADDR_W) ||
|
||||||
|
(RANGE_ADDR_WIDTH == 0) ?
|
||||||
|
PKT_ADDR_H :
|
||||||
|
PKT_ADDR_L + RANGE_ADDR_WIDTH - 1;
|
||||||
|
|
||||||
|
localparam RG = RANGE_ADDR_WIDTH;
|
||||||
|
localparam REAL_ADDRESS_RANGE = OPTIMIZED_ADDR_H - PKT_ADDR_L;
|
||||||
|
|
||||||
|
reg [PKT_DEST_ID_W-1 : 0] destid;
|
||||||
|
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Pass almost everything through, untouched
|
||||||
|
// -------------------------------------------------------
|
||||||
|
assign sink_ready = src_ready;
|
||||||
|
assign src_valid = sink_valid;
|
||||||
|
assign src_startofpacket = sink_startofpacket;
|
||||||
|
assign src_endofpacket = sink_endofpacket;
|
||||||
|
wire [2-1 : 0] default_src_channel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ddr3_mm_interconnect_2_router_002_default_decode the_default_decode(
|
||||||
|
.default_destination_id (),
|
||||||
|
.default_wr_channel (),
|
||||||
|
.default_rd_channel (),
|
||||||
|
.default_src_channel (default_src_channel)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
src_data = sink_data;
|
||||||
|
src_channel = default_src_channel;
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// DestinationID Decoder
|
||||||
|
// Sets the channel based on the destination ID.
|
||||||
|
// --------------------------------------------------
|
||||||
|
destid = sink_data[PKT_DEST_ID_H : PKT_DEST_ID_L];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (destid == 0 ) begin
|
||||||
|
src_channel = 2'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------
|
||||||
|
// Ceil(log2()) function
|
||||||
|
// --------------------------------------------------
|
||||||
|
function integer log2ceil;
|
||||||
|
input reg[65:0] val;
|
||||||
|
reg [65:0] i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i = 1;
|
||||||
|
log2ceil = 0;
|
||||||
|
|
||||||
|
while (i < val) begin
|
||||||
|
log2ceil = log2ceil + 1;
|
||||||
|
i = i << 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
101
ip/altera/ddr3/ddr3_mm_interconnect_2_rsp_demux.sv
Normal file
101
ip/altera/ddr3/ddr3_mm_interconnect_2_rsp_demux.sv
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_demultiplexer/altera_merlin_demultiplexer.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
// Merlin Demultiplexer
|
||||||
|
//
|
||||||
|
// Asserts valid on the appropriate output
|
||||||
|
// given a one-hot channel signal.
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_mm_interconnect_2_rsp_demux
|
||||||
|
// ST_DATA_W: 102
|
||||||
|
// ST_CHANNEL_W: 2
|
||||||
|
// NUM_OUTPUTS: 1
|
||||||
|
// VALID_WIDTH: 1
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
// Message Supression Used
|
||||||
|
// QIS Warnings
|
||||||
|
// 15610 - Warning: Design contains x input pin(s) that do not drive logic
|
||||||
|
//------------------------------------------
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_rsp_demux
|
||||||
|
(
|
||||||
|
// -------------------
|
||||||
|
// Sink
|
||||||
|
// -------------------
|
||||||
|
input [1-1 : 0] sink_valid,
|
||||||
|
input [102-1 : 0] sink_data, // ST_DATA_W=102
|
||||||
|
input [2-1 : 0] sink_channel, // ST_CHANNEL_W=2
|
||||||
|
input sink_startofpacket,
|
||||||
|
input sink_endofpacket,
|
||||||
|
output sink_ready,
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Sources
|
||||||
|
// -------------------
|
||||||
|
output reg src0_valid,
|
||||||
|
output reg [102-1 : 0] src0_data, // ST_DATA_W=102
|
||||||
|
output reg [2-1 : 0] src0_channel, // ST_CHANNEL_W=2
|
||||||
|
output reg src0_startofpacket,
|
||||||
|
output reg src0_endofpacket,
|
||||||
|
input src0_ready,
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// -------------------
|
||||||
|
(*altera_attribute = "-name MESSAGE_DISABLE 15610" *) // setting message suppression on clk
|
||||||
|
input clk,
|
||||||
|
(*altera_attribute = "-name MESSAGE_DISABLE 15610" *) // setting message suppression on reset
|
||||||
|
input reset
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam NUM_OUTPUTS = 1;
|
||||||
|
wire [NUM_OUTPUTS - 1 : 0] ready_vector;
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Demux
|
||||||
|
// -------------------
|
||||||
|
always @* begin
|
||||||
|
src0_data = sink_data;
|
||||||
|
src0_startofpacket = sink_startofpacket;
|
||||||
|
src0_endofpacket = sink_endofpacket;
|
||||||
|
src0_channel = sink_channel >> NUM_OUTPUTS;
|
||||||
|
|
||||||
|
src0_valid = sink_channel[0] && sink_valid;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
// -------------------
|
||||||
|
// Backpressure
|
||||||
|
// -------------------
|
||||||
|
assign ready_vector[0] = src0_ready;
|
||||||
|
|
||||||
|
assign sink_ready = |(sink_channel & {{1{1'b0}},{ready_vector[NUM_OUTPUTS - 1 : 0]}});
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
346
ip/altera/ddr3/ddr3_mm_interconnect_2_rsp_mux.sv
Normal file
346
ip/altera/ddr3/ddr3_mm_interconnect_2_rsp_mux.sv
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
// (C) 2001-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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// (C) 2001-2014 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 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, 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.
|
||||||
|
|
||||||
|
|
||||||
|
// $Id: //acds/rel/15.1/ip/merlin/altera_merlin_multiplexer/altera_merlin_multiplexer.sv.terp#1 $
|
||||||
|
// $Revision: #1 $
|
||||||
|
// $Date: 2015/08/09 $
|
||||||
|
// $Author: swbranch $
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Merlin Multiplexer
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Generation parameters:
|
||||||
|
// output_name: ddr3_mm_interconnect_2_rsp_mux
|
||||||
|
// NUM_INPUTS: 2
|
||||||
|
// ARBITRATION_SHARES: 1 1
|
||||||
|
// ARBITRATION_SCHEME "no-arb"
|
||||||
|
// PIPELINE_ARB: 0
|
||||||
|
// PKT_TRANS_LOCK: 72 (arbitration locking enabled)
|
||||||
|
// ST_DATA_W: 102
|
||||||
|
// ST_CHANNEL_W: 2
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
module ddr3_mm_interconnect_2_rsp_mux
|
||||||
|
(
|
||||||
|
// ----------------------
|
||||||
|
// Sinks
|
||||||
|
// ----------------------
|
||||||
|
input sink0_valid,
|
||||||
|
input [102-1 : 0] sink0_data,
|
||||||
|
input [2-1: 0] sink0_channel,
|
||||||
|
input sink0_startofpacket,
|
||||||
|
input sink0_endofpacket,
|
||||||
|
output sink0_ready,
|
||||||
|
|
||||||
|
input sink1_valid,
|
||||||
|
input [102-1 : 0] sink1_data,
|
||||||
|
input [2-1: 0] sink1_channel,
|
||||||
|
input sink1_startofpacket,
|
||||||
|
input sink1_endofpacket,
|
||||||
|
output sink1_ready,
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// Source
|
||||||
|
// ----------------------
|
||||||
|
output src_valid,
|
||||||
|
output [102-1 : 0] src_data,
|
||||||
|
output [2-1 : 0] src_channel,
|
||||||
|
output src_startofpacket,
|
||||||
|
output src_endofpacket,
|
||||||
|
input src_ready,
|
||||||
|
|
||||||
|
// ----------------------
|
||||||
|
// Clock & Reset
|
||||||
|
// ----------------------
|
||||||
|
input clk,
|
||||||
|
input reset
|
||||||
|
);
|
||||||
|
localparam PAYLOAD_W = 102 + 2 + 2;
|
||||||
|
localparam NUM_INPUTS = 2;
|
||||||
|
localparam SHARE_COUNTER_W = 1;
|
||||||
|
localparam PIPELINE_ARB = 0;
|
||||||
|
localparam ST_DATA_W = 102;
|
||||||
|
localparam ST_CHANNEL_W = 2;
|
||||||
|
localparam PKT_TRANS_LOCK = 72;
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Signals
|
||||||
|
// ------------------------------------------
|
||||||
|
wire [NUM_INPUTS - 1 : 0] request;
|
||||||
|
wire [NUM_INPUTS - 1 : 0] valid;
|
||||||
|
wire [NUM_INPUTS - 1 : 0] grant;
|
||||||
|
wire [NUM_INPUTS - 1 : 0] next_grant;
|
||||||
|
reg [NUM_INPUTS - 1 : 0] saved_grant;
|
||||||
|
reg [PAYLOAD_W - 1 : 0] src_payload;
|
||||||
|
wire last_cycle;
|
||||||
|
reg packet_in_progress;
|
||||||
|
reg update_grant;
|
||||||
|
|
||||||
|
wire [PAYLOAD_W - 1 : 0] sink0_payload;
|
||||||
|
wire [PAYLOAD_W - 1 : 0] sink1_payload;
|
||||||
|
|
||||||
|
assign valid[0] = sink0_valid;
|
||||||
|
assign valid[1] = sink1_valid;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// ------------------------------------------
|
||||||
|
// Grant Logic & Updates
|
||||||
|
// ------------------------------------------
|
||||||
|
// ------------------------------------------
|
||||||
|
reg [NUM_INPUTS - 1 : 0] lock;
|
||||||
|
always @* begin
|
||||||
|
lock[0] = sink0_data[72];
|
||||||
|
lock[1] = sink1_data[72];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign last_cycle = src_valid & src_ready & src_endofpacket & ~(|(lock & grant));
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// We're working on a packet at any time valid is high, except
|
||||||
|
// when this is the endofpacket.
|
||||||
|
// ------------------------------------------
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
packet_in_progress <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (last_cycle)
|
||||||
|
packet_in_progress <= 1'b0;
|
||||||
|
else if (src_valid)
|
||||||
|
packet_in_progress <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Shares
|
||||||
|
//
|
||||||
|
// Special case: all-equal shares _should_ be optimized into assigning a
|
||||||
|
// constant to next_grant_share.
|
||||||
|
// Special case: all-1's shares _should_ result in the share counter
|
||||||
|
// being optimized away.
|
||||||
|
// ------------------------------------------
|
||||||
|
// Input | arb shares | counter load value
|
||||||
|
// 0 | 1 | 0
|
||||||
|
// 1 | 1 | 0
|
||||||
|
wire [SHARE_COUNTER_W - 1 : 0] share_0 = 1'd0;
|
||||||
|
wire [SHARE_COUNTER_W - 1 : 0] share_1 = 1'd0;
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Choose the share value corresponding to the grant.
|
||||||
|
// ------------------------------------------
|
||||||
|
reg [SHARE_COUNTER_W - 1 : 0] next_grant_share;
|
||||||
|
always @* begin
|
||||||
|
next_grant_share =
|
||||||
|
share_0 & { SHARE_COUNTER_W {next_grant[0]} } |
|
||||||
|
share_1 & { SHARE_COUNTER_W {next_grant[1]} };
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Flag to indicate first packet of an arb sequence.
|
||||||
|
// ------------------------------------------
|
||||||
|
wire grant_changed = ~packet_in_progress && ~(|(saved_grant & valid));
|
||||||
|
reg first_packet_r;
|
||||||
|
wire first_packet = grant_changed | first_packet_r;
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
first_packet_r <= 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (update_grant)
|
||||||
|
first_packet_r <= 1'b1;
|
||||||
|
else if (last_cycle)
|
||||||
|
first_packet_r <= 1'b0;
|
||||||
|
else if (grant_changed)
|
||||||
|
first_packet_r <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Compute the next share-count value.
|
||||||
|
// ------------------------------------------
|
||||||
|
reg [SHARE_COUNTER_W - 1 : 0] p1_share_count;
|
||||||
|
reg [SHARE_COUNTER_W - 1 : 0] share_count;
|
||||||
|
reg share_count_zero_flag;
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
if (first_packet) begin
|
||||||
|
p1_share_count = next_grant_share;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
// Update the counter, but don't decrement below 0.
|
||||||
|
p1_share_count = share_count_zero_flag ? '0 : share_count - 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Update the share counter and share-counter=zero flag.
|
||||||
|
// ------------------------------------------
|
||||||
|
always @(posedge clk or posedge reset) begin
|
||||||
|
if (reset) begin
|
||||||
|
share_count <= '0;
|
||||||
|
share_count_zero_flag <= 1'b1;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (last_cycle) begin
|
||||||
|
share_count <= p1_share_count;
|
||||||
|
share_count_zero_flag <= (p1_share_count == '0);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// For each input, maintain a final_packet signal which goes active for the
|
||||||
|
// last packet of a full-share packet sequence. Example: if I have 4
|
||||||
|
// shares and I'm continuously requesting, final_packet is active in the
|
||||||
|
// 4th packet.
|
||||||
|
// ------------------------------------------
|
||||||
|
wire final_packet_0 = 1'b1;
|
||||||
|
|
||||||
|
wire final_packet_1 = 1'b1;
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Concatenate all final_packet signals (wire or reg) into a handy vector.
|
||||||
|
// ------------------------------------------
|
||||||
|
wire [NUM_INPUTS - 1 : 0] final_packet = {
|
||||||
|
final_packet_1,
|
||||||
|
final_packet_0
|
||||||
|
};
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// ------------------------------------------
|
||||||
|
wire p1_done = |(final_packet & grant);
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Flag for the first cycle of packets within an
|
||||||
|
// arb sequence
|
||||||
|
// ------------------------------------------
|
||||||
|
reg first_cycle;
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
first_cycle <= 0;
|
||||||
|
else
|
||||||
|
first_cycle <= last_cycle && ~p1_done;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
update_grant = 0;
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// No arbitration pipeline, update grant whenever
|
||||||
|
// the current arb winner has consumed all shares,
|
||||||
|
// or all requests are low
|
||||||
|
// ------------------------------------------
|
||||||
|
update_grant = (last_cycle && p1_done) || (first_cycle && ~(|valid));
|
||||||
|
update_grant = last_cycle;
|
||||||
|
end
|
||||||
|
|
||||||
|
wire save_grant;
|
||||||
|
assign save_grant = 1;
|
||||||
|
assign grant = next_grant;
|
||||||
|
|
||||||
|
always @(posedge clk, posedge reset) begin
|
||||||
|
if (reset)
|
||||||
|
saved_grant <= '0;
|
||||||
|
else if (save_grant)
|
||||||
|
saved_grant <= next_grant;
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// ------------------------------------------
|
||||||
|
// Arbitrator
|
||||||
|
// ------------------------------------------
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Create a request vector that stays high during
|
||||||
|
// the packet for unpipelined arbitration.
|
||||||
|
//
|
||||||
|
// The pipelined arbitration scheme does not require
|
||||||
|
// request to be held high during the packet.
|
||||||
|
// ------------------------------------------
|
||||||
|
assign request = valid;
|
||||||
|
|
||||||
|
wire [NUM_INPUTS - 1 : 0] next_grant_from_arb;
|
||||||
|
|
||||||
|
altera_merlin_arbitrator
|
||||||
|
#(
|
||||||
|
.NUM_REQUESTERS(NUM_INPUTS),
|
||||||
|
.SCHEME ("no-arb"),
|
||||||
|
.PIPELINE (0)
|
||||||
|
) arb (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.request (request),
|
||||||
|
.grant (next_grant_from_arb),
|
||||||
|
.save_top_priority (src_valid),
|
||||||
|
.increment_top_priority (update_grant)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign next_grant = next_grant_from_arb;
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// ------------------------------------------
|
||||||
|
// Mux
|
||||||
|
//
|
||||||
|
// Implemented as a sum of products.
|
||||||
|
// ------------------------------------------
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
assign sink0_ready = src_ready && grant[0];
|
||||||
|
assign sink1_ready = src_ready && grant[1];
|
||||||
|
|
||||||
|
assign src_valid = |(grant & valid);
|
||||||
|
|
||||||
|
always @* begin
|
||||||
|
src_payload =
|
||||||
|
sink0_payload & {PAYLOAD_W {grant[0]} } |
|
||||||
|
sink1_payload & {PAYLOAD_W {grant[1]} };
|
||||||
|
end
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Mux Payload Mapping
|
||||||
|
// ------------------------------------------
|
||||||
|
|
||||||
|
assign sink0_payload = {sink0_channel,sink0_data,
|
||||||
|
sink0_startofpacket,sink0_endofpacket};
|
||||||
|
assign sink1_payload = {sink1_channel,sink1_data,
|
||||||
|
sink1_startofpacket,sink1_endofpacket};
|
||||||
|
|
||||||
|
assign {src_channel,src_data,src_startofpacket,src_endofpacket} = src_payload;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user