Initial commit

master
Markus Koch 2016-08-04 19:22:38 +02:00
commit a1efcf62c4
257 changed files with 167528 additions and 0 deletions

5
.gitignore vendored 100644
View File

@ -0,0 +1,5 @@
*.wlf
wlf*
*.vstf
transcript

View 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 100644
View 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>

View 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

View 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;

View 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;

View 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;

View 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;

View 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 100644
View 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

View 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;

View 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;

View 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;

View 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;

View 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;

View 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;

View 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 100644
View 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;

View 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;

View 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;

View 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;

View 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;

View 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

View 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 100644
View 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;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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 100644
View 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 100644
View 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 100644
View 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 100644

File diff suppressed because it is too large Load Diff

View 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"]

File diff suppressed because it is too large Load Diff

13
ip/altera/ddr3.spd 100644
View 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 100644
View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

View 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

View 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*]

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View 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

View 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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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]
}

View 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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View File

@ -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

View File

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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