Commit 7626c8fe authored by Evangelia Gousiou's avatar Evangelia Gousiou

svec_pts_dac_vcxo_pll: updated to the latest version of VMEcore (ProgramID: 5a);…

svec_pts_dac_vcxo_pll: updated to the latest version of VMEcore (ProgramID: 5a); added initialization reset logic
parent d87dc794
fetchto = "ip_cores"
modules = {
"git" : [ "git://ohwr.org/hdl-core-lib/wr-cores.git" ],
"svn" : [ "http://svn.ohwr.org/vme64x-core/trunk/hdl/vme64x-core/rtl" ]
}
*.*\#
\#*
.\#*
*.*~
work
*.wlf
*.vstf
*.patch
modelsim.ini
*.html
*.h
*.o
*.bin
*.elf
syn/
\ No newline at end of file
modules = {
"local" : [
"modules/common",
"modules/genrams",
"modules/wishbone"
]
}
\ No newline at end of file
OHWR general-cores VHDL library
--------------------------------
TEST RELEASE - NOT READY FOR USE!
files = [ "gencores_pkg.vhd",
"gc_crc_gen.vhd",
"gc_moving_average.vhd",
"gc_extend_pulse.vhd",
"gc_delay_gen.vhd",
"gc_dual_pi_controller.vhd",
"gc_serial_dac.vhd",
"gc_sync_ffs.vhd",
"gc_arbitrated_mux.vhd",
"gc_pulse_synchronizer.vhd",
"gc_frequency_meter.vhd",
"gc_dual_clock_ram.vhd",
"gc_wfifo.vhd",
"gc_rr_arbiter.vhd",
"gc_prio_encoder.vhd",
"gc_word_packer.vhd"];
-------------------------------------------------------------------------------
-- Title : Multiplexer with round-robin arbitration
-- Project : General Cores Collection library
-------------------------------------------------------------------------------
-- File : gc_arbitrated_mux.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-24
-- Last update: 2012-02-21
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: An N-channel time-division multiplexer with round robin
-- arbitration.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-08-24 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
use work.genram_pkg.all;
entity gc_arbitrated_mux is
generic (
-- number of arbitrated inputs
g_num_inputs : integer;
-- data width
g_width : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- data (all inputs joined together)
d_i : in std_logic_vector(g_num_inputs * g_width-1 downto 0);
-- 1: data word on input N is valid. Can be asserted only if corresponding
-- d_req_o(N) == 1
d_valid_i : in std_logic_vector(g_num_inputs-1 downto 0);
-- 1: input N is ready to accept next data word
d_req_o : out std_logic_vector(g_num_inputs-1 downto 0);
-- Mux output
q_o : out std_logic_vector(g_width-1 downto 0);
-- 1: q_o contains valid data word
q_valid_o : out std_logic;
-- Index of the input, to which came the currently outputted data word.
q_input_id_o : out std_logic_vector(f_log2_size(g_num_inputs)-1 downto 0)
);
end gc_arbitrated_mux;
architecture rtl of gc_arbitrated_mux is
function f_onehot_decode
(x : std_logic_vector) return integer is
begin
for i in 0 to x'length-1 loop
if(x(i) = '1') then
return i;
end if;
end loop; -- i
return 0;
end f_onehot_decode;
type t_data_array is array(0 to g_num_inputs-1) of std_logic_vector(g_width-1 downto 0);
signal req_masked, req, grant : std_logic_vector(g_num_inputs-1 downto 0);
signal dregs : t_data_array;
begin -- rtl
gen_inputs : for i in 0 to g_num_inputs-1 generate
p_input_reg : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
req(i) <= '0';
else
if(grant(i) = '1') then
req(i) <= '0';
elsif(d_valid_i(i) = '1') then
dregs(i) <= d_i(g_width * (i+1) - 1 downto g_width * i);
req(i) <= '1';
end if;
end if;
end if;
end process;
d_req_o(i) <= not req(i);
end generate gen_inputs;
req_masked <= req and not grant;
p_arbitrate : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
q_valid_o <= '0';
grant <= (others => '0');
else
f_rr_arbitrate(req_masked , grant, grant);
if(unsigned(grant) /= 0) then
q_o <= dregs(f_onehot_decode(grant));
q_input_id_o <= std_logic_vector(to_unsigned(f_onehot_decode(grant), f_log2_size(g_num_inputs)));
q_valid_o <= '1';
else
q_o <= (others => 'X');
q_input_id_o <= (others => 'X');
q_valid_o <= '0';
end if;
end if;
end if;
end process;
end rtl;
-------------------------------------------------------------------------------
-- Title : Simple delay line generator
-- Project : White Rabbit
-------------------------------------------------------------------------------
-- File : gc_delay_gen.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-02-25
-- Last update: 2011-04-29
-- Platform : FPGA-generic
-- Standard : VHDL '87
------------------------------------------------------------------------------
-- Description: Simple N-bit delay line with programmable delay.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009 - 2010 CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-02-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.gencores_pkg.all;
entity gc_delay_gen is
generic(
g_delay_cycles : in natural;
g_data_width : in natural
);
port(clk_i : in std_logic;
rst_n_i : in std_logic;
d_i : in std_logic_vector(g_data_width - 1 downto 0);
q_o : out std_logic_vector(g_data_width - 1 downto 0)
);
end gc_delay_gen;
architecture behavioral of gc_delay_gen is
type t_dly_array is array (0 to g_delay_cycles) of std_logic_vector(g_data_width -1 downto 0);
signal dly : t_dly_array;
begin -- behavioral
p_delay_proc : process (clk_i, rst_n_i)
begin -- process delay_proc
if rst_n_i = '0' then -- asynchronous reset (active low)
genrst : for i in 1 to g_delay_cycles loop
dly(i) <= (others => '0');
end loop;
elsif rising_edge(clk_i) then -- rising clock edge
dly(0) <= d_i;
gendly : for i in 0 to g_delay_cycles-1 loop
dly(i+1) <= dly(i);
end loop;
end if;
end process p_delay_proc;
q_o <= dly(g_delay_cycles);
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- Read during write has an undefined result
entity gc_dual_clock_ram is
generic(
addr_width : natural := 4;
data_width : natural := 32);
port(
-- write port
w_clk_i : in std_logic;
w_en_i : in std_logic;
w_addr_i : in std_logic_vector(addr_width-1 downto 0);
w_data_i : in std_logic_vector(data_width-1 downto 0);
-- read port
r_clk_i : in std_logic;
r_en_i : in std_logic;
r_addr_i : in std_logic_vector(addr_width-1 downto 0);
r_data_o : out std_logic_vector(data_width-1 downto 0));
end gc_dual_clock_ram;
architecture rtl of gc_dual_clock_ram is
type ram_t is array(2**addr_width-1 downto 0) of std_logic_vector(data_width-1 downto 0);
signal ram : ram_t := (others => (others => '0'));
-- Tell synthesizer we do not care about read during write behaviour
attribute ramstyle : string;
attribute ramstyle of ram : signal is "no_rw_check";
begin
write : process(w_clk_i)
begin
if rising_edge(w_clk_i) then
if w_en_i = '1' then
ram(to_integer(unsigned(w_addr_i))) <= w_data_i;
end if;
end if;
end process;
read : process(r_clk_i)
begin
if rising_edge(r_clk_i) then
if r_en_i = '1' then
r_data_o <= ram(to_integer(unsigned(r_addr_i)));
end if;
end if;
end process;
end rtl;
-------------------------------------------------------------------------------
-- Title : Pulse width extender
-- Project : General Cores library
-------------------------------------------------------------------------------
-- File : gc_extend_pulse.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2009-09-01
-- Last update: 2012-06-19
-- Platform : FPGA-generic
-- Standard : VHDL '93
-------------------------------------------------------------------------------
-- Description:
-- Synchronous pulse extender. Generates a pulse of programmable width upon
-- detection of a rising edge in the input.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009-2011 CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009-09-01 0.9 twlostow Created
-- 2011-04-18 1.0 twlostow Added comments & header
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.NUMERIC_STD.all;
library work;
use work.gencores_pkg.all;
entity gc_extend_pulse is
generic (
-- output pulse width in clk_i cycles
g_width : natural := 1000
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
-- input pulse (synchronou to clk_i)
pulse_i : in std_logic;
-- extended output pulse
extended_o : out std_logic := '0');
end gc_extend_pulse;
architecture rtl of gc_extend_pulse is
signal cntr : unsigned(31 downto 0);
signal extended_int : std_logic;
begin -- rtl
extend : process (clk_i, rst_n_i)
begin -- process extend
if rst_n_i = '0' then -- asynchronous reset (active low)
extended_int <= '0';
cntr <= (others => '0');
elsif clk_i'event and clk_i = '1' then -- rising clock edge
if(pulse_i = '1') then
extended_int <= '1';
cntr <= to_unsigned(g_width - 2, cntr'length);
elsif cntr /= to_unsigned(0, cntr'length) then
cntr <= cntr - 1;
else
extended_int <= '0';
end if;
end if;
end process extend;
extended_o <= pulse_i or extended_int;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.gencores_pkg.all;
entity gc_frequency_meter is
generic(
g_with_internal_timebase : boolean := true;
g_clk_sys_freq : integer;
g_counter_bits : integer := 32);
port(
clk_sys_i : in std_logic;
clk_in_i : in std_logic;
rst_n_i : in std_logic;
pps_p1_i : in std_logic;
freq_o : out std_logic_vector(g_counter_bits-1 downto 0);
freq_valid_o : out std_logic
);
end gc_frequency_meter;
architecture behavioral of gc_frequency_meter is
signal gate_pulse, gate_pulse_synced : std_logic;
signal cntr_gate : unsigned(g_counter_bits-1 downto 0);
signal cntr_meas : unsigned(g_counter_bits-1 downto 0);
signal freq_reg : std_logic_vector(g_counter_bits-1 downto 0);
begin
gen_internal_timebase : if(g_with_internal_timebase = true) generate
p_gate_counter : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
cntr_gate <= (others => '0');
gate_pulse <= '0';
else
if(cntr_gate = g_clk_sys_freq-1) then
cntr_gate <= (others => '0');
gate_pulse <= '1';
else
cntr_gate <= cntr_gate + 1;
gate_pulse <= '0';
end if;
end if;
end if;
end process;
end generate gen_internal_timebase;
gen_external_timebase : if(g_with_internal_timebase = false) generate
gate_pulse <= pps_p1_i;
end generate gen_external_timebase;
U_Sync_Gate : gc_pulse_synchronizer
port map (
clk_in_i => clk_sys_i,
clk_out_i => clk_in_i,
rst_n_i => rst_n_i,
d_ready_o => freq_valid_o,
d_p_i => gate_pulse,
q_p_o => gate_pulse_synced);
p_freq_counter : process (clk_in_i, rst_n_i)
begin
if rst_n_i = '0' then -- asynchronous reset (active low)
cntr_meas <= (others => '0');
freq_reg <= (others => '0');
elsif rising_edge(clk_in_i) then
if(gate_pulse_synced = '1') then
freq_reg <= std_logic_vector(cntr_meas);
cntr_meas <= (others => '0');
else
cntr_meas <= cntr_meas + 1;
end if;
end if;
end process p_freq_counter;
freq_o <= freq_reg;
end behavioral;
-------------------------------------------------------------------------------
-- Title : Moving average filter
-- Project : General Cores library
-------------------------------------------------------------------------------
-- File : gc_moving_average.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2009-09-01
-- Last update: 2011-04-29
-- Platform : FPGA-generic
-- Standard : VHDL '93
-------------------------------------------------------------------------------
-- Description:
-- Simple averaging filter.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009-2011 CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009-09-01 0.9 twlostow Created
-- 2011-04-18 1.0 twlostow Added comments & header
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.NUMERIC_STD.all;
library work;
use work.gencores_pkg.all;
entity gc_moving_average is
generic (
-- input/output data width
g_data_width : natural := 24;
-- averaging window, expressed as 2 ** g_avg_log2
g_avg_log2 : natural range 1 to 8 := 4
);
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
din_i : in std_logic_vector(g_data_width-1 downto 0);
din_stb_i : in std_logic;
dout_o : out std_logic_vector(g_data_width-1 downto 0);
dout_stb_o : out std_logic
);
end gc_moving_average;
architecture rtl of gc_moving_average is
component generic_ssram_dp_rw_rw
generic (
g_width : integer;
g_addr_bits : integer;
g_size : integer);
port (
clk_i : in std_logic;
wr_en_a_i : in std_logic;
addr_a_i : in std_logic_vector(g_addr_bits-1 downto 0);
data_a_i : in std_logic_vector(g_width-1 downto 0);
q_a_o : out std_logic_vector(g_width-1 downto 0);
wr_en_b_i : in std_logic;
addr_b_i : in std_logic_vector(g_addr_bits-1 downto 0);
data_b_i : in std_logic_vector(g_width-1 downto 0);
q_b_o : out std_logic_vector(g_width-1 downto 0));
end component;
constant avg_steps : natural := 2**g_avg_log2;
signal read_cntr, write_cntr : unsigned(g_avg_log2-1 downto 0);
signal mem_dout : std_logic_vector(g_data_width-1 downto 0);
signal ready : std_logic;
signal acc : signed(g_data_width+g_avg_log2 downto 0);
signal stb_d0, stb_d1, stb_d2, stb_d3 : std_logic;
signal s_dummy : std_logic_vector(g_data_width-1 downto 0);
begin -- rtl
delay_buf : generic_ssram_dp_rw_rw
generic map (
g_width => g_data_width,
g_addr_bits => g_avg_log2,
g_size => 2**g_avg_log2
)
port map (
clk_i => clk_i,
wr_en_a_i => '0',
addr_a_i => std_logic_vector(read_cntr),
data_a_i => s_dummy,
q_a_o => mem_dout,
wr_en_b_i => din_stb_i,
addr_b_i => std_logic_vector(write_cntr),
data_b_i => din_i,
q_b_o => open);
--delay_buf : generic_ssram_dualport_singleclock
-- generic map (
-- g_width => g_data_width,
-- g_addr_bits => g_avg_log2,
-- g_size => 2**g_avg_log2)
-- port map (
-- data_i => din_i,
-- rd_addr_i => std_logic_vector(read_cntr),
-- clk_i => clk_i,
-- wr_addr_i => std_logic_vector(write_cntr),
-- wr_en_i => din_stb_i,
-- q_o => mem_dout);
avg : process (clk_i, rst_n_i)
begin -- process avg
if clk_i'event and clk_i = '1' then -- rising clock edge
if(rst_n_i = '0') then
read_cntr <= to_unsigned(1, read_cntr'length);
write_cntr <= to_unsigned(avg_steps, write_cntr'length);
ready <= '0';
stb_d0 <= '0';
stb_d1 <= '0';
stb_d2 <= '0';
stb_d3 <= '0';
acc <= (others => '0');
else
if(read_cntr = to_unsigned(avg_steps, read_cntr'length)) then
ready <= '1';
end if;
if(din_stb_i = '1') then
acc <= acc + signed(din_i);
write_cntr <= write_cntr + 1;
else
if stb_d3 = '1' then
read_cntr <= read_cntr + 1;
if(ready = '1') then
acc <= acc - signed(mem_dout);
dout_o <= std_logic_vector(acc (g_avg_log2 + g_data_width - 1 downto g_avg_log2));
end if;
end if;
end if;
dout_stb_o <= stb_d3 and ready;
stb_d0 <= din_stb_i;
stb_d1 <= stb_d0;
stb_d2 <= stb_d1;
stb_d3 <= stb_d2;
end if;
end if;
end process avg;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity gc_prio_encoder is
generic (
g_width : integer
);
port (
d_i : in std_logic_vector(g_width-1 downto 0);
therm_o : out std_logic_vector(g_width-1 downto 0)
);
end gc_prio_encoder;
architecture rtl of gc_prio_encoder is
function f_count_stages(width : integer) return integer is
begin
if(width <= 2) then
return 2;
elsif(width <= 4) then
return 3;
elsif(width <= 8) then
return 4;
elsif(width <= 16) then
return 5;
elsif(width <= 32) then
return 6;
elsif(width <= 64) then
return 7;
elsif(width <= 128) then
return 8;
else
return 0;
end if;
end f_count_stages;
constant c_n_stages : integer := f_count_stages(g_width);
type t_stage_array is array(0 to c_n_stages) of std_logic_vector(g_width-1 downto 0);
signal stages : t_stage_array;
begin -- rtl
stages(0) <= d_i;
gen1 : for i in 1 to c_n_stages generate
gen2 : for j in 0 to g_width-1 generate
gen3 : if(j mod (2 ** i) >= (2 ** (i-1))) generate
stages(i)(j) <= stages(i-1)(j) or stages(i-1) (j - (j mod (2**i)) + (2**(i-1)) - 1);
end generate gen3;
gen4 : if not (j mod (2 ** i) >= (2 ** (i-1))) generate
stages(i)(j) <= stages(i-1)(j);
end generate gen4;
end generate gen2;
end generate gen1;
therm_o <= stages(c_n_stages);
end rtl;
-------------------------------------------------------------------------------
-- Title : Pulse synchronizer
-- Project : General Cores Library
-------------------------------------------------------------------------------
-- File : gc_pulse_synchronizer.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2012-01-10
-- Last update: 2012-01-10
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Full feedback pulse synchronizer (works independently of the
-- input/output clock domain frequency ratio)
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2012-01-12 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.gencores_pkg.all;
entity gc_pulse_synchronizer is
port (
-- pulse input clock
clk_in_i : in std_logic;
-- pulse output clock
clk_out_i : in std_logic;
-- system reset (clk_in_i domain)
rst_n_i : in std_logic;
-- pulse input ready (clk_in_i domain). When HI, a pulse coming to d_p_i will be
-- correctly transferred to q_p_o.
d_ready_o : out std_logic;
-- pulse input (clk_in_i domain)
d_p_i : in std_logic;
-- pulse output (clk_out_i domain)
q_p_o : out std_logic);
end gc_pulse_synchronizer;
architecture rtl of gc_pulse_synchronizer is
constant c_sync_stages : integer := 3;
signal ready : std_logic;
signal in_ext, out_ext : std_logic;
signal out_feedback : std_logic;
signal d_in2out : std_logic_vector(c_sync_stages-1 downto 0);
signal d_out2in : std_logic_vector(c_sync_stages-1 downto 0);
begin -- rtl
process(clk_out_i, rst_n_i)
begin
if rst_n_i = '0' then
d_in2out <= (others => '0');
out_ext <= '0';
elsif rising_edge(clk_out_i) then
d_in2out <= d_in2out(c_sync_stages-2 downto 0) & in_ext;
out_ext <= d_in2out(c_sync_stages-1);
end if;
end process;
process(clk_in_i, rst_n_i)
begin
if rst_n_i = '0' then
d_out2in <= (others => '0');
elsif rising_edge(clk_in_i) then
d_out2in <= d_out2in(c_sync_stages-2 downto 0) & out_ext;
end if;
end process;
out_feedback <= d_out2in(c_sync_stages-1);
p_input_ack : process(clk_in_i, rst_n_i)
begin
if rst_n_i = '0' then
ready <= '1';
in_ext <= '0';
elsif rising_edge(clk_in_i) then
if(ready = '1' and d_p_i = '1') then
in_ext <= '1';
ready <= '0';
elsif(in_ext = '1' and out_feedback = '1') then
in_ext <= '0';
elsif(in_ext = '0' and out_feedback = '0') then
ready <= '1';
end if;
end if;
end process;
p_drive_output : process(clk_out_i, rst_n_i)
begin
if rst_n_i = '0' then
q_p_o <= '0';
elsif rising_edge(clk_out_i) then
q_p_o <= not out_ext and d_in2out(c_sync_stages-1);
end if;
end process;
d_ready_o <= ready;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity gc_rr_arbiter is
generic (
g_size : integer := 19);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
req_i : in std_logic_vector(g_size-1 downto 0);
grant_o : out std_logic_vector(g_size-1 downto 0);
grant_comb_o: out std_logic_vector(g_size-1 downto 0)
);
attribute opt_mode: string;
attribute opt_mode of gc_rr_arbiter: entity is "speed";
attribute resource_sharing: string;
attribute resource_sharing of gc_rr_arbiter: entity is "no";
end gc_rr_arbiter;
architecture rtl of gc_rr_arbiter is
component gc_prio_encoder
generic (
g_width : integer);
port (
d_i : in std_logic_vector(g_width-1 downto 0);
therm_o : out std_logic_vector(g_width-1 downto 0));
end component;
signal req_m, th_m, th_u, mux_out, mask : std_logic_vector(g_size-1 downto 0);
begin -- rtl
req_m<=req_i and mask;
U_PE1 : gc_prio_encoder
generic map (
g_width => g_size)
port map (
d_i => req_m,
therm_o => th_m);
U_PE2 : gc_prio_encoder
generic map (
g_width => g_size)
port map (
d_i => req_i,
therm_o => th_u);
process(th_u, th_m)
begin
if(th_m(th_m'length - 1) = '0') then
mux_out <= th_u;
else
mux_out <= th_m;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
mask <= (others => '0');
grant_o <= (others => '0');
else
mask <= mux_out(g_size-2 downto 0) & '0';
grant_o <= not (mux_out(g_size-2 downto 0) & '0') and mux_out;
end if;
end if;
end process;
grant_comb_o <= not (mux_out(g_size-2 downto 0) & '0') and mux_out;
end rtl;
-------------------------------------------------------------------------------
-- Title : Serial DAC interface
-- Project : White Rabbit
-------------------------------------------------------------------------------
-- File : gc_serial_dac.vhd
-- Author : Pablo Alvarez Sanchez
-- Company : CERN BE-Co-HT
-- Created : 2010-02-25
-- Last update: 2011-04-29
-- Platform : FPGA-generic
-- Standard : VHDL '87
-------------------------------------------------------------------------------
-- Description: The DAC unit provides an interface to a 16 bit serial Digital
-- to Analogue converter (MAX5441, AD5662, SPI/QSPI/MICROWIRE compatible)
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009 - 2010 CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2009-01-24 1.0 paas Created
-- 2010-02-25 1.1 twlostow Modified for rev 1.1 switch
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity gc_serial_dac is
generic (
-- number of DAC data word bits (LSBs)
g_num_data_bits : integer := 16;
-- number of padding MSBs, sent as zeros
g_num_extra_bits : integer := 8;
-- number of chip select inputs
g_num_cs_select : integer := 2;
-- serial clock polarity: 0 - data is outputted on rising-,
-- 1 - on falling edge of SCLK
g_sclk_polarity : integer := 1
);
port (
-- clock & reset
clk_i : in std_logic;
rst_n_i : in std_logic;
-- value to be written to the DAC
value_i : in std_logic_vector(g_num_data_bits-1 downto 0);
-- chip select vector. Setting bits to 1 enables writing to the corresponding
-- DAC
cs_sel_i : in std_logic_vector(g_num_cs_select-1 downto 0);
-- when 1, value_i is valid.
load_i : in std_logic;
-- SCLK divider: 000 = clk_i/8 ... 111 = clk_i/1024
sclk_divsel_i : in std_logic_vector(2 downto 0);
-- DAC I/F
dac_cs_n_o : out std_logic_vector(g_num_cs_select-1 downto 0);
dac_sclk_o : out std_logic;
dac_sdata_o : out std_logic;
-- when 1, the SPI interface is busy sending data to the DAC.
busy_o : out std_logic
);
end gc_serial_dac;
architecture syn of gc_serial_dac is
signal divider : unsigned(11 downto 0);
signal dataSh : std_logic_vector(g_num_data_bits + g_num_extra_bits-1 downto 0);
signal bitCounter : std_logic_vector(g_num_data_bits + g_num_extra_bits+1 downto 0);
signal endSendingData : std_logic;
signal sendingData : std_logic;
signal iDacClk : std_logic;
signal iValidValue : std_logic;
signal divider_muxed : std_logic;
signal cs_sel_reg : std_logic_vector(g_num_cs_select-1 downto 0);
begin
select_divider : process (divider, sclk_divsel_i)
begin -- process
case sclk_divsel_i is
when "000" => divider_muxed <= divider(1); -- sclk = clk_i/8
when "001" => divider_muxed <= divider(2); -- sclk = clk_i/16
when "010" => divider_muxed <= divider(3); -- sclk = clk_i/32
when "011" => divider_muxed <= divider(4); -- sclk = clk_i/64
when "100" => divider_muxed <= divider(5); -- sclk = clk_i/128
when "101" => divider_muxed <= divider(6); -- sclk = clk_i/256
when "110" => divider_muxed <= divider(7); -- sclk = clk_i/512
when "111" => divider_muxed <= divider(8); -- sclk = clk_i/1024
when others => null;
end case;
end process;
iValidValue <= load_i;
process(clk_i, rst_n_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
sendingData <= '0';
else
if iValidValue = '1' and sendingData = '0' then
sendingData <= '1';
elsif endSendingData = '1' then
sendingData <= '0';
end if;
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if iValidValue = '1' then
divider <= (others => '0');
elsif sendingData = '1' then
if(divider_muxed = '1') then
divider <= (others => '0');
else
divider <= divider + 1;
end if;
elsif endSendingData = '1' then
divider <= (others => '0');
end if;
end if;
end process;
process(clk_i, rst_n_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
iDacClk <= '1'; -- 0
else
if iValidValue = '1' then
iDacClk <= '1'; -- 0
elsif divider_muxed = '1' then
iDacClk <= not(iDacClk);
elsif endSendingData = '1' then
iDacClk <= '1'; -- 0
end if;
end if;
end if;
end process;
process(clk_i, rst_n_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
dataSh <= (others => '0');
else
if iValidValue = '1' and sendingData = '0' then
cs_sel_reg <= cs_sel_i;
dataSh(g_num_data_bits-1 downto 0) <= value_i;
dataSh(dataSh'left downto g_num_data_bits) <= (others => '0');
elsif sendingData = '1' and divider_muxed = '1' and iDacClk = '0' then
dataSh(0) <= dataSh(dataSh'left);
dataSh(dataSh'left downto 1) <= dataSh(dataSh'left - 1 downto 0);
end if;
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if iValidValue = '1' and sendingData = '0' then
bitCounter(0) <= '1';
bitCounter(bitCounter'left downto 1) <= (others => '0');
elsif sendingData = '1' and to_integer(divider) = 0 and iDacClk = '1' then
bitCounter(0) <= '0';
bitCounter(bitCounter'left downto 1) <= bitCounter(bitCounter'left - 1 downto 0);
end if;
end if;
end process;
endSendingData <= bitCounter(bitCounter'left);
busy_o <= SendingData;
dac_sdata_o <= dataSh(dataSh'left);
gen_cs_out : for i in 0 to g_num_cs_select-1 generate
dac_cs_n_o(i) <= not(sendingData) or (not cs_sel_reg(i));
end generate gen_cs_out;
p_drive_sclk : process(iDacClk)
begin
if(g_sclk_polarity = 0) then
dac_sclk_o <= iDacClk;
else
dac_sclk_o <= not iDacClk;
end if;
end process;
end syn;
-------------------------------------------------------------------------------
-- Title : Synchronizer chain
-- Project : White Rabbit
-------------------------------------------------------------------------------
-- File : gc_sync_ffs.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-06-14
-- Last update: 2011-04-29
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Synchronizer chain and edge detector.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009 - 2010 CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-06-14 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity gc_sync_ffs is
generic(
g_sync_edge : string := "positive"
);
port(
clk_i : in std_logic; -- clock from the destination clock domain
rst_n_i : in std_logic; -- reset
data_i : in std_logic; -- async input
synced_o : out std_logic; -- synchronized output
npulse_o : out std_logic; -- negative edge detect output (single-clock
-- pulse)
ppulse_o : out std_logic -- positive edge detect output (single-clock
-- pulse)
);
end gc_sync_ffs;
architecture behavioral of gc_sync_ffs is
signal sync0, sync1, sync2 : std_logic;
begin
sync_posedge : if (g_sync_edge = "positive") generate
process(clk_i, rst_n_i)
begin
if(rst_n_i = '0') then
sync0 <= '0';
sync1 <= '0';
sync2 <= '0';
synced_o <= '0';
npulse_o <= '0';
ppulse_o <= '0';
elsif rising_edge(clk_i) then
sync0 <= data_i;
sync1 <= sync0;
sync2 <= sync1;
synced_o <= sync1;
npulse_o <= sync2 and not sync1;
ppulse_o <= not sync2 and sync1;
end if;
end process;
end generate sync_posedge;
sync_negedge : if(g_sync_edge = "negative") generate
process(clk_i, rst_n_i)
begin
if(rst_n_i = '0') then
sync0 <= '0';
sync1 <= '0';
sync2 <= '0';
synced_o <= '0';
npulse_o <= '0';
ppulse_o <= '0';
elsif falling_edge(clk_i) then
sync0 <= data_i;
sync1 <= sync0;
sync2 <= sync1;
synced_o <= sync1;
npulse_o <= sync2 and not sync1;
ppulse_o <= not sync2 and sync1;
end if;
end process;
end generate sync_negedge;
end behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
entity gc_wfifo is
generic(
sync_depth : natural := 3;
gray_code : boolean := true;
addr_width : natural := 4;
data_width : natural := 32);
port(
rst_n_i : in std_logic;
-- write port, only set w_en when w_rdy
w_clk_i : in std_logic;
w_rdy_o : out std_logic;
w_en_i : in std_logic;
w_data_i : in std_logic_vector(data_width-1 downto 0);
-- (pre)alloc port, can be unused
a_clk_i : in std_logic;
a_rdy_o : out std_logic;
a_en_i : in std_logic;
-- read port, only set r_en when r_rdy
-- data is valid the cycle after r_en raised
r_clk_i : in std_logic;
r_rdy_o : out std_logic;
r_en_i : in std_logic;
r_data_o : out std_logic_vector(data_width-1 downto 0));
end gc_wfifo;
architecture rtl of gc_wfifo is
subtype counter is unsigned(addr_width downto 0);
type counter_shift is array(sync_depth downto 0) of counter;
signal r_idx_bnry : counter;
signal r_idx_gray : counter;
signal w_idx_bnry : counter;
signal w_idx_gray : counter;
signal a_idx_bnry : counter;
signal a_idx_gray : counter;
signal r_idx_shift_w : counter_shift; -- r_idx_gray in w_clk
signal r_idx_shift_a : counter_shift; -- r_idx_gray in a_clk
signal w_idx_shift_r : counter_shift; -- w_idx_gray in r_clk
attribute altera_attribute : string;
-- Quartus 11 sometimes goes crazy and infers an altshift_taps! Stop it.
attribute altera_attribute of r_idx_shift_w : signal is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
attribute altera_attribute of r_idx_shift_a : signal is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
attribute altera_attribute of w_idx_shift_r : signal is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
function bin2gray(a : unsigned) return unsigned is
variable o : unsigned(a'length downto 0);
begin
if gray_code then
o := (a & '0') xor ('0' & a);
else
o := (a & '0');
end if;
return o(a'length downto 1);
end bin2gray;
function index(a : counter) return std_logic_vector is
begin
return std_logic_vector(a(addr_width-1 downto 0));
end index;
function empty(a, b : counter) return std_logic is
begin
if a = b then
return '1';
else
return '0';
end if;
end empty;
function full(a, b : counter) return std_logic is
variable mask : counter := (others => '0');
begin
-- In binary a full FIFO has indexes (a XOR 1000...00) = b
-- bin2gray is a linear function, thus:
-- a XOR 1000..00 = b iff
-- bin2gray(a XOR 1000...00) = bin2gray(b) iff
-- bin2gray(a) XOR bin2gray(1000...00) = bin2gray(b) iif
-- bin2gray(a) XOR 1100..00 = bin2gray(b)
mask(addr_width) := '1';
mask := bin2gray(mask);
if (a xor mask) = b then
return '1';
else
return '0';
end if;
end full;
begin
ram : gc_dual_clock_ram
generic map(addr_width => addr_width, data_width => data_width)
port map(w_clk_i => w_clk_i, w_en_i => w_en_i, w_addr_i => index(w_idx_bnry), w_data_i => w_data_i,
r_clk_i => r_clk_i, r_en_i => r_en_i, r_addr_i => index(r_idx_bnry), r_data_o => r_data_o);
read : process(r_clk_i)
variable idx : counter;
begin
if rising_edge(r_clk_i) then
if rst_n_i = '0' then
idx := (others => '0');
elsif r_en_i = '1' then
idx := r_idx_bnry + 1;
else
idx := r_idx_bnry;
end if;
r_idx_bnry <= idx;
r_idx_gray <= bin2gray(idx);
w_idx_shift_r(sync_depth downto 1) <= w_idx_shift_r(sync_depth-1 downto 0);
end if;
end process;
w_idx_shift_r(0) <= w_idx_gray;
r_rdy_o <= not empty(r_idx_gray, w_idx_shift_r(sync_depth));
write : process(w_clk_i)
variable idx : counter;
begin
if rising_edge(w_clk_i) then
if rst_n_i = '0' then
idx := (others => '0');
elsif w_en_i = '1' then
idx := w_idx_bnry + 1;
else
idx := w_idx_bnry;
end if;
w_idx_bnry <= idx;
w_idx_gray <= bin2gray(idx);
r_idx_shift_w(sync_depth downto 1) <= r_idx_shift_w(sync_depth-1 downto 0);
end if;
end process;
r_idx_shift_w(0) <= r_idx_gray;
w_rdy_o <= not full(w_idx_gray, r_idx_shift_w(sync_depth));
alloc : process(a_clk_i)
variable idx : counter;
begin
if rising_edge(a_clk_i) then
if rst_n_i = '0' then
idx := (others => '0');
elsif a_en_i = '1' then
idx := a_idx_bnry + 1;
else
idx := a_idx_bnry;
end if;
a_idx_bnry <= idx;
a_idx_gray <= bin2gray(idx);
r_idx_shift_a(sync_depth downto 1) <= r_idx_shift_a(sync_depth-1 downto 0);
end if;
end process;
r_idx_shift_a(0) <= r_idx_gray;
a_rdy_o <= not full(a_idx_gray, r_idx_shift_a(sync_depth));
end rtl;
-------------------------------------------------------------------------------
-- Title : Word packer/unpacker
-- Project : General Cores Collection library
-------------------------------------------------------------------------------
-- File : gc_word_packer.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2012-09-13
-- Last update: 2012-09-13
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Packs/unpacks g_input_width-sized word(s) into g_output_width-
-- sized word(s). Data is packed starting from the least significant word.
-- Packet width must be integer multiple of the unpacked width.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
entity gc_word_packer is
generic(
-- width of the input words
g_input_width : integer;
-- width of the output words
g_output_width : integer);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
-- input data
d_i : in std_logic_vector(g_input_width-1 downto 0);
-- input data valid
d_valid_i : in std_logic;
-- synchronous input data request, when active, the source
-- is allowed to assert d_valid_i in next clock cycle.
d_req_o : out std_logic;
-- flushes packer input, immediately outputting (incomplete) packed word to q_o
-- even if the number of input words is less than g_output_width.
-- Unused when g_input_width > g_output_width (unpacking)
flush_i : in std_logic := '0';
-- data output
q_o : out std_logic_vector(g_output_width-1 downto 0);
-- data output valid
q_valid_o : out std_logic;
-- synchronous data request: if active, packer can output data in following
-- clock cycle.
q_req_i : in std_logic
);
end gc_word_packer;
architecture rtl of gc_word_packer is
function f_max(a : integer; b : integer) return integer is
begin
if(a > b) then
return a;
else
return b;
end if;
end f_max;
function f_min(a : integer; b : integer) return integer is
begin
if(a < b) then
return a;
else
return b;
end if;
end f_min;
constant c_sreg_size : integer := f_max(g_input_width, g_output_width);
constant c_sreg_entries : integer := c_sreg_size / f_min(g_input_width, g_output_width);
signal sreg : std_logic_vector(c_sreg_size-1 downto 0);
signal count : unsigned(f_log2_size(c_sreg_entries + 1) - 1 downto 0);
signal empty : std_logic;
signal q_valid_comb, q_valid_reg, q_req_d0 : std_logic;
begin -- rtl
-- Fixme: flush functionality.
gen_grow : if(g_output_width > g_input_width) generate
p_grow : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
count <= (others => '0');
else
if(d_valid_i = '1') then
if(q_valid_reg = '0') then
sreg(to_integer(count) * g_input_width + g_input_width-1 downto to_integer(count) * g_input_width) <= d_i;
else
sreg(g_input_width-1 downto 0) <= d_i;
end if;
end if;
if(q_valid_comb = '1') then
count <= (others => '0');
elsif(d_valid_i = '1') then
count <= count + 1;
end if;
q_valid_reg <= q_valid_comb;
end if;
end if;
end process;
q_valid_o <= q_valid_reg;
q_valid_comb <= '1' when (q_req_i = '1' and (count = c_sreg_entries or (count = c_sreg_entries-1 and d_valid_i = '1'))) else '0';
d_req_o <= '1' when q_req_i = '1' and (count /= c_sreg_entries) else '0';
q_o <= sreg;
end generate gen_grow;
gen_shrink : if(g_output_width < g_input_width) generate
p_shrink : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
count <= (others => '0');
empty <= '1';
q_req_d0 <= '0';
else
q_req_d0 <= q_req_i;
if(d_valid_i = '1') then
sreg <= d_i;
end if;
if(count = c_sreg_entries-1 and d_valid_i = '0' and q_valid_comb = '1') then
empty <= '1';
elsif(d_valid_i = '1') then
empty <= '0';
end if;
if(q_valid_comb = '1') then
if(count = c_sreg_entries-1) then
count <= (others => '0');
else
count <= count + 1;
end if;
end if;
end if;
end if;
end process;
q_valid_o <= q_valid_comb;
d_req_o <= '1' when d_valid_i = '0' and (empty = '1' or (q_req_i = '1' and count = c_sreg_entries-1)) else '0';
p_gen_output : process(count, sreg, empty, d_i, d_valid_i, q_req_d0)
begin
if (q_req_d0 = '1' and empty = '0') then
q_valid_comb <= '1';
q_o <= sreg(to_integer(count) * g_output_width + g_output_width-1 downto to_integer(count) * g_output_width);
elsif (empty = '1' and d_valid_i = '1' and q_req_d0 = '1') then
q_valid_comb <= '1';
q_o <= d_i(g_output_width-1 downto 0);
else
q_valid_comb <= '0';
q_o <= (others => 'X');
end if;
end process;
end generate gen_shrink;
gen_equal : if(g_output_width = g_input_width) generate
q_o <= d_i;
q_valid_o <= d_valid_i;
d_req_o <= q_req_i;
end generate gen_equal;
end rtl;
files = [
"genram_pkg.vhd",
"memory_loader_pkg.vhd",
"generic_shiftreg_fifo.vhd",
"inferred_sync_fifo.vhd",
"inferred_async_fifo.vhd"];
if (target == "altera"):
modules = {"local" : "altera"}
elif (target == "xilinx" and syn_device[0:4].upper()=="XC6V"):
modules = {"local" : ["xilinx", "xilinx/virtex6"]}
elif (target == "xilinx"):
modules = {"local" : ["xilinx", "generic"]}
files = [
"generic_async_fifo.vhd",
"generic_dpram.vhd",
"generic_spram.vhd",
"generic_sync_fifo.vhd"]
-------------------------------------------------------------------------------
-- Title : Parametrizable asynchronous FIFO (Altera version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_async_fifo.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2011-01-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Dual-clock asynchronous FIFO.
-- - configurable data width and size
-- - "show ahead" mode
-- - configurable full/empty/almost full/almost empty/word count signals
-- Todo:
-- - optimize almost empty / almost full flags generation for speed
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library altera_mf;
use altera_mf.all;
use work.genram_pkg.all;
entity generic_async_fifo is
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
-- Read-side flag selection
g_with_rd_empty : boolean := true; -- with empty flag
g_with_rd_full : boolean := false; -- with full flag
g_with_rd_almost_empty : boolean := false;
g_with_rd_almost_full : boolean := false;
g_with_rd_count : boolean := false; -- with words counter
g_with_wr_empty : boolean := false;
g_with_wr_full : boolean := true;
g_with_wr_almost_empty : boolean := false;
g_with_wr_almost_full : boolean := false;
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer -- threshold for almost full flag
);
port (
rst_n_i : in std_logic := '1';
-- write port
clk_wr_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_almost_empty_o : out std_logic;
wr_almost_full_o : out std_logic;
wr_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-- read port
clk_rd_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_almost_empty_o : out std_logic;
rd_almost_full_o : out std_logic;
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
end generic_async_fifo;
architecture syn of generic_async_fifo is
component dcfifo
generic (
lpm_numwords : natural;
lpm_showahead : string;
lpm_type : string;
lpm_width : natural;
lpm_widthu : natural;
overflow_checking : string;
rdsync_delaypipe : natural;
underflow_checking : string;
use_eab : string;
write_aclr_synch : string;
wrsync_delaypipe : natural
);
port (
wrclk : in std_logic;
rdempty : out std_logic;
wrempty : out std_logic;
rdreq : in std_logic;
aclr : in std_logic;
rdfull : out std_logic;
wrfull : out std_logic;
rdclk : in std_logic;
q : out std_logic_vector (g_data_width-1 downto 0);
wrreq : in std_logic;
data : in std_logic_vector (g_data_width-1 downto 0);
wrusedw : out std_logic_vector (f_log2_size(g_size)-1downto 0);
rdusedw : out std_logic_vector (f_log2_size(g_size)-1 downto 0)
);
end component;
function f_bool_2_string (x : boolean) return string is
begin
if(x) then
return "ON";
else
return "OFF";
end if;
end f_bool_2_string;
signal rdempty : std_logic;
signal wrempty : std_logic;
signal aclr : std_logic;
signal rdfull : std_logic;
signal wrfull : std_logic;
signal wrusedw : std_logic_vector (f_log2_size(g_size)-1 downto 0);
signal rdusedw : std_logic_vector (f_log2_size(g_size)-1 downto 0);
begin -- syn
aclr <= not rst_n_i;
dcfifo_inst : dcfifo
generic map (
lpm_numwords => g_size,
lpm_showahead => f_bool_2_string(g_show_ahead),
lpm_type => "dcfifo",
lpm_width => g_data_width,
lpm_widthu => f_log2_size(g_size),
overflow_checking => "ON",
rdsync_delaypipe => 5, -- 2 sync stages
underflow_checking => "ON",
use_eab => "ON",
write_aclr_synch => "ON",
wrsync_delaypipe => 5 -- 2 sync stages
)
port map (
wrclk => clk_wr_i,
rdempty => rdempty,
wrempty => wrempty,
rdreq => rd_i,
aclr => aclr,
rdfull => rdfull,
wrfull => wrfull,
rdclk => clk_rd_i,
q => q_o,
wrreq => we_i,
data => d_i,
wrusedw => wrusedw,
rdusedw => rdusedw);
gen_with_wr_count : if(g_with_wr_count) generate
wr_count_o <= wrusedw;
end generate gen_with_wr_count;
gen_with_rd_count : if(g_with_rd_count) generate
rd_count_o <= rdusedw;
end generate gen_with_rd_count;
gen_with_wr_empty : if(g_with_wr_empty) generate
wr_empty_o <= wrempty;
end generate gen_with_wr_empty;
gen_with_rd_empty : if(g_with_rd_empty) generate
rd_empty_o <= rdempty;
end generate gen_with_rd_empty;
gen_with_wr_full : if(g_with_wr_full) generate
wr_full_o <= wrfull;
end generate gen_with_wr_full;
gen_with_rd_full : if(g_with_rd_full) generate
rd_full_o <= rdfull;
end generate gen_with_rd_full;
gen_with_wr_almost_empty : if(g_with_wr_almost_empty) generate
wr_almost_empty_o <= '1' when unsigned(wrusedw) < to_unsigned(g_almost_empty_threshold, wrusedw'length) else '0';
end generate gen_with_wr_almost_empty;
gen_with_rd_almost_empty : if(g_with_rd_almost_empty) generate
rd_almost_empty_o <= '1' when unsigned(rdusedw) < to_unsigned(g_almost_empty_threshold, rdusedw'length) else '0';
end generate gen_with_rd_almost_empty;
gen_with_wr_almost_full : if(g_with_wr_almost_full) generate
wr_almost_full_o <= '1' when unsigned(wrusedw) > to_unsigned(g_almost_full_threshold, wrusedw'length) else '0';
end generate gen_with_wr_almost_full;
gen_with_rd_almost_full : if(g_with_rd_almost_full) generate
rd_almost_full_o <= '1' when unsigned(rdusedw) > to_unsigned(g_almost_full_threshold,rdusedw'length) else '0';
end generate gen_with_rd_almost_full;
end syn;
-------------------------------------------------------------------------------
-- Title : Parametrizable dual-port synchronous RAM (Altera version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_dpram.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2012-01-20
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: True dual-port synchronous RAM for Altera FPGAs with:
-- - configurable address and data bus width
-- - byte-addressing mode (data bus width restricted to multiple of 8 bits)
-- Todo:
-- - loading initial contents from file
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-- 2012-03-13 1.1 wterpstra Added initial value as array
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.genram_pkg.all;
use work.memory_loader_pkg.all;
entity generic_dpram is
generic (
-- standard parameters
g_data_width : natural;
g_size : natural;
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_init_value : t_generic_ram_init := c_generic_ram_nothing;
g_dual_clock : boolean := true;
g_fail_if_file_not_found : boolean := true
);
port (
rst_n_i : in std_logic := '1'; -- synchronous reset, active LO
-- Port A
clka_i : in std_logic;
bwea_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
wea_i : in std_logic;
aa_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
da_i : in std_logic_vector(g_data_width-1 downto 0);
qa_o : out std_logic_vector(g_data_width-1 downto 0);
-- Port B
clkb_i : in std_logic;
bweb_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
web_i : in std_logic;
ab_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
db_i : in std_logic_vector(g_data_width-1 downto 0);
qb_o : out std_logic_vector(g_data_width-1 downto 0)
);
end generic_dpram;
architecture syn of generic_dpram is
constant c_num_bytes : integer := g_data_width/8;
type t_ram_type is array(0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
type t_ram_word_bs is array (0 to 7) of std_logic_vector(7 downto 0);
type t_ram_type_bs is array (0 to g_size - 1) of t_ram_word_bs;
function f_memarray_to_ramtype(arr : t_meminit_array) return t_ram_type is
variable tmp : t_ram_type;
variable n, pos : integer;
begin
pos := 0;
while(pos < g_size)loop
n := 0;
-- avoid ISE loop iteration limit
while (pos < g_size and n < 4096) loop
for i in 0 to g_data_width-1 loop
tmp(pos)(i) := arr(pos, i);
end loop; -- i
n := n+1;
pos := pos + 1;
end loop;
end loop;
return tmp;
end f_memarray_to_ramtype;
function f_memarray_to_ramtype_bs(arr : t_meminit_array) return t_ram_type_bs is
variable tmp : t_ram_type_bs;
variable n, pos : integer;
begin
pos := 0;
while(pos < g_size)loop
n := 0;
-- avoid ISE loop iteration limit
while (pos < g_size and n < 4096) loop
for i in 0 to g_data_width-1 loop
tmp(pos)(i/8)(i mod 8) := arr(pos, i);
end loop; -- i
n := n+1;
pos := pos + 1;
end loop;
end loop;
return tmp;
end f_memarray_to_ramtype_bs;
function f_file_contents return t_meminit_array is
begin
if g_init_value'length > 0 then
return g_init_value;
else
return f_load_mem_from_file(g_init_file, g_size, g_data_width, g_fail_if_file_not_found);
end if;
end f_file_contents;
shared variable ram : t_ram_type := f_memarray_to_ramtype(f_file_contents);
shared variable ram_bs : t_ram_type_bs:=f_memarray_to_ramtype_bs(f_file_contents);
signal q_local_a : t_ram_word_bs;
signal q_local_b : t_ram_word_bs;
signal bwe_int_a : std_logic_vector(7 downto 0);
signal bwe_int_b : std_logic_vector(7 downto 0);
signal clka_int : std_logic;
signal clkb_int : std_logic;
begin
assert (g_addr_conflict_resolution = "read_first")
report "generic_dpram: Altera template supports only read-first mode." severity failure;
assert (((g_data_width / 8) * 8) = g_data_width) or (g_with_byte_enable = false)
report "generic_dpram: in byte-enabled mode the data width must be a multiple of 8" severity failure;
assert(g_data_width <= 64 or g_with_byte_enable = false)
report "generic_dpram: byte-selectable memories can be have 64-bit data width due to synthesis tool limitation" severity failure;
--gen_single_clock : if(g_dual_clock = false) generate
-- clka_int <= clka_i after 1ns;
-- clkb_int <= clka_i after 1ns;
--end generate gen_single_clock;
--gen_dual_clock : if(g_dual_clock = true) generate
-- clka_int <= clka_i after 1ns;
-- clkb_int <= clkb_i after 1ns;
--end generate gen_dual_clock;
gen_with_byte_enable : if(g_with_byte_enable = true) generate
bwe_int_a <= std_logic_vector(to_unsigned(0, 8-bwea_i'length)) & bwea_i;
bwe_int_b <= std_logic_vector(to_unsigned(0, 8-bweb_i'length)) & bweb_i;
unpack : for i in 0 to c_num_bytes - 1 generate
qa_o(8*(i+1) - 1 downto 8*i) <= q_local_a(i);
qb_o(8*(i+1) - 1 downto 8*i) <= q_local_b(i);
end generate unpack;
process(clka_i)
begin
if(rising_edge(clka_i)) then
if(wea_i = '1') then
-- I know the code below is stupid, but it's the only way to make Quartus
-- recongnize it as a memory block
if(bwe_int_a(0) = '1' and g_data_width >= 8) then
ram_bs(to_integer(unsigned(aa_i)))(0) := da_i(7 downto 0);
end if;
if(bwe_int_a(1) = '1' and g_data_width >= 16) then
ram_bs(to_integer(unsigned(aa_i)))(1) := da_i(15 downto 8);
end if;
if(bwe_int_a(2) = '1' and g_data_width >= 24) then
ram_bs(to_integer(unsigned(aa_i)))(2) := da_i(23 downto 16);
end if;
if(bwe_int_a(3) = '1' and g_data_width >= 32) then
ram_bs(to_integer(unsigned(aa_i)))(3) := da_i(31 downto 24);
end if;
if(bwe_int_a(4) = '1' and g_data_width >= 40) then
ram_bs(to_integer(unsigned(aa_i)))(4) := da_i(39 downto 32);
end if;
if(bwe_int_a(5) = '1' and g_data_width >= 48) then
ram_bs(to_integer(unsigned(aa_i)))(5) := da_i(47 downto 40);
end if;
if(bwe_int_a(6) = '1' and g_data_width >= 56) then
ram_bs(to_integer(unsigned(aa_i)))(6) := da_i(55 downto 48);
end if;
if(bwe_int_a(7) = '1' and g_data_width = 64) then
ram_bs(to_integer(unsigned(aa_i)))(7) := da_i(64 downto 57);
end if;
end if;
q_local_a <= ram_bs(to_integer(unsigned(aa_i)));
end if;
end process;
process(clkb_i)
begin
if(rising_edge(clkb_i)) then
if(web_i = '1') then
-- I know the code below is stupid, but it's the only way to make Quartus
-- recongnize it as a memory block
if(bwe_int_b(0) = '1' and g_data_width >= 8) then
ram_bs(to_integer(unsigned(ab_i)))(0) := db_i(7 downto 0);
end if;
if(bwe_int_b(1) = '1' and g_data_width >= 16) then
ram_bs(to_integer(unsigned(ab_i)))(1) := db_i(15 downto 8);
end if;
if(bwe_int_b(2) = '1' and g_data_width >= 24) then
ram_bs(to_integer(unsigned(ab_i)))(2) := db_i(23 downto 16);
end if;
if(bwe_int_b(3) = '1' and g_data_width >= 32) then
ram_bs(to_integer(unsigned(ab_i)))(3) := db_i(31 downto 24);
end if;
if(bwe_int_b(4) = '1' and g_data_width >= 40) then
ram_bs(to_integer(unsigned(ab_i)))(4) := db_i(39 downto 32);
end if;
if(bwe_int_b(5) = '1' and g_data_width >= 48) then
ram_bs(to_integer(unsigned(ab_i)))(5) := db_i(47 downto 40);
end if;
if(bwe_int_b(6) = '1' and g_data_width >= 56) then
ram_bs(to_integer(unsigned(ab_i)))(6) := db_i(55 downto 48);
end if;
if(bwe_int_b(7) = '1' and g_data_width = 64) then
ram_bs(to_integer(unsigned(ab_i)))(7) := db_i(64 downto 57);
end if;
end if;
q_local_b <= ram_bs(to_integer(unsigned(ab_i)));
end if;
end process;
end generate gen_with_byte_enable;
gen_without_byte_enable_readfirst : if(g_with_byte_enable = false) generate
process(clka_i)
begin
if rising_edge(clka_i) then
if(wea_i = '1') then
ram(to_integer(unsigned(aa_i))) := da_i;
end if;
qa_o <= ram(to_integer(unsigned(aa_i)));
end if;
end process;
process(clkb_i)
begin
if rising_edge(clkb_i) then
if(web_i = '1') then
ram(to_integer(unsigned(ab_i))) := db_i;
end if;
qb_o <= ram(to_integer(unsigned(ab_i)));
end if;
end process;
end generate gen_without_byte_enable_readfirst;
end syn;
-------------------------------------------------------------------------------
-- Title : Parametrizable single-port synchronous RAM (Altera version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_spram.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2011-01-25
-- Last update: 2011-01-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Single-port synchronous RAM for Altera FPGAs with:
-- - configurable address and data bus width
-- - byte-addressing mode (data bus width restricted to multiple of 8 bits)
-- Todo:
-- - loading initial contents from file
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.genram_pkg.all;
entity generic_spram is
generic (
-- standard parameters
g_data_width : natural := 32;
g_size : natural := 1024;
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := ""
);
port (
rst_n_i : in std_logic := '1'; -- synchronous reset, active LO
clk_i : in std_logic; -- clock input
-- byte write enable, actiwe when g_with_byte_enable == true
bwe_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
-- global write enable (masked by bwe_i if g_with_byte_enable = true)
we_i : in std_logic;
-- address input
a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
-- data input
d_i : in std_logic_vector(g_data_width-1 downto 0);
-- data output
q_o : out std_logic_vector(g_data_width-1 downto 0)
);
end generic_spram;
architecture syn of generic_spram is
constant c_num_bytes : integer := g_data_width/8;
type t_ram_type is array(0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
type t_ram_word_bs is array (0 to 7) of std_logic_vector(7 downto 0);
type t_ram_type_bs is array (0 to g_size - 1) of t_ram_word_bs;
signal ram : t_ram_type;
signal ram_bs : t_ram_type_bs;
signal q_local : t_ram_word_bs;
signal bwe_int : std_logic_vector(7 downto 0);
begin
assert (g_init_file = "") report "generic_spram: Memory initialization files not supported yet. Sorry :(" severity failure;
assert (g_addr_conflict_resolution = "read_first") report "generic_spram: Altera template supports only read-first mode." severity failure;
assert (((g_data_width / 8) * 8) = g_data_width) or (g_with_byte_enable = false) report "generic_spram: in byte-enabled mode the data width must be a multiple of 8" severity failure;
assert(g_data_width <= 64 or g_with_byte_enable = false) report "generic_spram: byte-selectable memories can be have 64-bit data width due to synthesis tool limitation" severity failure;
bwe_int <= std_logic_vector(to_unsigned(0, 8-bwe_i'length)) & bwe_i;
gen_with_byte_enable : if(g_with_byte_enable = true) generate
unpack : for i in 0 to c_num_bytes - 1 generate
q_o(8*(i+1) - 1 downto 8*i) <= q_local(i);
end generate unpack;
process(clk_i)
begin
if(rising_edge(clk_i)) then
if(we_i = '1') then
-- I know the code below is stupid, but it's the only way to make Quartus
-- recongnize it as a memory block
if(bwe_int(0) = '1' and g_data_width >= 8) then
ram_bs(to_integer(unsigned(a_i)))(0) <= d_i(7 downto 0);
end if;
if(bwe_int(1) = '1' and g_data_width >= 16) then
ram_bs(to_integer(unsigned(a_i)))(1) <= d_i(15 downto 8);
end if;
if(bwe_int(2) = '1' and g_data_width >= 24) then
ram_bs(to_integer(unsigned(a_i)))(2) <= d_i(23 downto 16);
end if;
if(bwe_int(3) = '1' and g_data_width >= 32) then
ram_bs(to_integer(unsigned(a_i)))(3) <= d_i(31 downto 24);
end if;
if(bwe_int(4) = '1' and g_data_width >= 40) then
ram_bs(to_integer(unsigned(a_i)))(4) <= d_i(39 downto 32);
end if;
if(bwe_int(5) = '1' and g_data_width >= 48) then
ram_bs(to_integer(unsigned(a_i)))(5) <= d_i(47 downto 40);
end if;
if(bwe_int(6) = '1' and g_data_width >= 56) then
ram_bs(to_integer(unsigned(a_i)))(6) <= d_i(55 downto 48);
end if;
if(bwe_int(7) = '1' and g_data_width >= 64) then
ram_bs(to_integer(unsigned(a_i)))(7) <= d_i(64 downto 57);
end if;
end if;
q_local <= ram_bs(to_integer(unsigned(a_i)));
end if;
end process;
end generate gen_with_byte_enable;
gen_without_byte_enable_readfirst : if(g_with_byte_enable = false) generate
process(clk_i)
begin
if rising_edge(clk_i) then
if(we_i = '1') then
ram(to_integer(unsigned(a_i))) <= d_i;
end if;
q_o <= ram(to_integer(unsigned(a_i)));
end if;
end process;
end generate gen_without_byte_enable_readfirst;
end syn;
-------------------------------------------------------------------------------
-- Title : Parametrizable synchronous FIFO (Altera version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_sync_fifo.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2011-01-25
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Single-clock FIFO.
-- - configurable data width and size
-- - "show ahead" mode
-- - configurable full/empty/almost full/almost empty/word count signals
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library altera_mf;
use altera_mf.all;
use work.genram_pkg.all;
entity generic_sync_fifo is
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
-- Read-side flag selection
g_with_empty : boolean := true; -- with empty flag
g_with_full : boolean := true; -- with full flag
g_with_almost_empty : boolean := false;
g_with_almost_full : boolean := false;
g_with_count : boolean := false; -- with words counter
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer -- threshold for almost full flag
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
empty_o : out std_logic;
full_o : out std_logic;
almost_empty_o : out std_logic;
almost_full_o : out std_logic;
count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
end generic_sync_fifo;
architecture syn of generic_sync_fifo is
component scfifo
generic (
add_ram_output_register : string;
almost_empty_value : natural;
almost_full_value : natural;
lpm_numwords : natural;
lpm_showahead : string;
lpm_type : string;
lpm_width : natural;
lpm_widthu : natural;
overflow_checking : string;
underflow_checking : string;
use_eab : string);
port (
clock : in std_logic;
sclr : in std_logic;
usedw : out std_logic_vector (f_log2_size(g_size)-1 downto 0);
empty : out std_logic;
full : out std_logic;
q : out std_logic_vector (g_data_width-1 downto 0);
wrreq : in std_logic;
almost_empty : out std_logic;
almost_full : out std_logic;
data : in std_logic_vector (g_data_width-1 downto 0);
rdreq : in std_logic);
end component;
function f_bool_2_string (x : boolean) return string is
begin
if(x) then
return "ON";
else
return "OFF";
end if;
end f_bool_2_string;
signal empty : std_logic;
signal almost_empty : std_logic;
signal almost_full : std_logic;
signal sclr : std_logic;
signal full : std_logic;
signal usedw : std_logic_vector (f_log2_size(g_size)-1 downto 0);
begin -- syn
sclr <= not rst_n_i;
scfifo_inst: scfifo
generic map (
add_ram_output_register => "OFF",
almost_empty_value => g_almost_empty_threshold,
almost_full_value => g_almost_full_threshold,
lpm_numwords => g_size,
lpm_showahead => f_bool_2_string(g_show_ahead),
lpm_type => "scfifo",
lpm_width => g_data_width,
lpm_widthu => f_log2_size(g_size),
overflow_checking => "ON",
underflow_checking => "ON",
use_eab => "ON" )
port map (
clock => clk_i,
sclr => sclr,
usedw => usedw,
empty => empty,
full => full,
q => q_o,
wrreq => we_i,
almost_empty => almost_empty,
almost_full => almost_full,
data => d_i,
rdreq => rd_i);
gen_with_count : if(g_with_count) generate
count_o <= usedw;
end generate gen_with_count;
gen_with_empty : if(g_with_empty) generate
empty_o <= empty;
end generate gen_with_empty;
gen_with_full : if(g_with_full) generate
full_o <= full;
end generate gen_with_full;
gen_with_almost_empty : if(g_with_almost_empty) generate
almost_empty_o <= almost_empty;
end generate gen_with_almost_empty;
gen_with_almost_full : if(g_with_almost_full) generate
almost_full_o <= almost_full;
end generate gen_with_almost_full;
end syn;
-------------------------------------------------------------------------------
-- Title : Parametrizable asynchronous FIFO (Generic version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_async_fifo.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2012-07-03
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Dual-clock asynchronous FIFO.
-- - configurable data width and size
-- - configurable full/empty/almost full/almost empty/word count signals
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
entity generic_async_fifo is
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
-- Read-side flag selection
g_with_rd_empty : boolean := true; -- with empty flag
g_with_rd_full : boolean := false; -- with full flag
g_with_rd_almost_empty : boolean := false;
g_with_rd_almost_full : boolean := false;
g_with_rd_count : boolean := false; -- with words counter
g_with_wr_empty : boolean := false;
g_with_wr_full : boolean := true;
g_with_wr_almost_empty : boolean := false;
g_with_wr_almost_full : boolean := false;
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer -- threshold for almost full flag
);
port (
rst_n_i : in std_logic := '1';
-- write port
clk_wr_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_almost_empty_o : out std_logic;
wr_almost_full_o : out std_logic;
wr_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-- read port
clk_rd_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_almost_empty_o : out std_logic;
rd_almost_full_o : out std_logic;
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
end generic_async_fifo;
architecture syn of generic_async_fifo is
component inferred_async_fifo
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean;
g_with_rd_empty : boolean;
g_with_rd_full : boolean;
g_with_rd_almost_empty : boolean;
g_with_rd_almost_full : boolean;
g_with_rd_count : boolean;
g_with_wr_empty : boolean;
g_with_wr_full : boolean;
g_with_wr_almost_empty : boolean;
g_with_wr_almost_full : boolean;
g_with_wr_count : boolean;
g_almost_empty_threshold : integer;
g_almost_full_threshold : integer);
port (
rst_n_i : in std_logic := '1';
clk_wr_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_almost_empty_o : out std_logic;
wr_almost_full_o : out std_logic;
wr_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
clk_rd_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_almost_empty_o : out std_logic;
rd_almost_full_o : out std_logic;
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0));
end component;
begin -- syn
U_Inferred_FIFO : inferred_async_fifo
generic map (
g_data_width => g_data_width,
g_size => g_size,
g_show_ahead => g_show_ahead,
g_with_rd_empty => g_with_rd_empty,
g_with_rd_full => g_with_rd_full,
g_with_rd_almost_empty => g_with_rd_almost_empty,
g_with_rd_almost_full => g_with_rd_almost_full,
g_with_rd_count => g_with_rd_count,
g_with_wr_empty => g_with_wr_empty,
g_with_wr_full => g_with_wr_full,
g_with_wr_almost_empty => g_with_wr_almost_empty,
g_with_wr_almost_full => g_with_wr_almost_full,
g_with_wr_count => g_with_wr_count,
g_almost_empty_threshold => g_almost_empty_threshold,
g_almost_full_threshold => g_almost_full_threshold)
port map (
rst_n_i => rst_n_i,
clk_wr_i => clk_wr_i,
d_i => d_i,
we_i => we_i,
wr_empty_o => wr_empty_o,
wr_full_o => wr_full_o,
wr_almost_empty_o => wr_almost_empty_o,
wr_almost_full_o => wr_almost_full_o,
wr_count_o => wr_count_o,
clk_rd_i => clk_rd_i,
q_o => q_o,
rd_i => rd_i,
rd_empty_o => rd_empty_o,
rd_full_o => rd_full_o,
rd_almost_empty_o => rd_almost_empty_o,
rd_almost_full_o => rd_almost_full_o,
rd_count_o => rd_count_o);
end syn;
-------------------------------------------------------------------------------
-- Title : Parametrizable synchronous FIFO (Xilinx version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_sync_fifo.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2012-07-03
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Single-clock FIFO.
-- - configurable data width and size
-- - "show ahead" mode
-- - configurable full/empty/almost full/almost empty/word count signals
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
entity generic_sync_fifo is
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
-- Read-side flag selection
g_with_empty : boolean := true; -- with empty flag
g_with_full : boolean := true; -- with full flag
g_with_almost_empty : boolean := false;
g_with_almost_full : boolean := false;
g_with_count : boolean := false; -- with words counter
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer; -- threshold for almost full flag
g_register_flag_outputs : boolean := true
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
empty_o : out std_logic;
full_o : out std_logic;
almost_empty_o : out std_logic;
almost_full_o : out std_logic;
count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
end generic_sync_fifo;
architecture syn of generic_sync_fifo is
component inferred_sync_fifo
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean;
g_with_empty : boolean;
g_with_full : boolean;
g_with_almost_empty : boolean;
g_with_almost_full : boolean;
g_with_count : boolean;
g_almost_empty_threshold : integer;
g_almost_full_threshold : integer;
g_register_flag_outputs : boolean);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
empty_o : out std_logic;
full_o : out std_logic;
almost_empty_o : out std_logic;
almost_full_o : out std_logic;
count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0));
end component;
begin -- syn
U_Inferred_FIFO : inferred_sync_fifo
generic map (
g_data_width => g_data_width,
g_size => g_size,
g_show_ahead => g_show_ahead,
g_with_empty => g_with_empty,
g_with_full => g_with_full,
g_with_almost_empty => g_with_almost_empty,
g_with_almost_full => g_with_almost_full,
g_with_count => g_with_count,
g_almost_empty_threshold => g_almost_empty_threshold,
g_almost_full_threshold => g_almost_full_threshold,
g_register_flag_outputs => g_register_flag_outputs)
port map (
rst_n_i => rst_n_i,
clk_i => clk_i,
d_i => d_i,
we_i => we_i,
q_o => q_o,
rd_i => rd_i,
empty_o => empty_o,
full_o => full_o,
almost_empty_o => almost_empty_o,
almost_full_o => almost_full_o,
count_o => count_o);
end syn;
----------------------------------------------------------------------------
---- ----
---- ----
---- This file is part of the srl_fifo project ----
---- http://www.opencores.org/cores/srl_fifo ----
---- ----
---- Description ----
---- Implementation of srl_fifo IP core according to ----
---- srl_fifo IP core specification document. ----
---- ----
---- To Do: ----
---- NA ----
---- ----
---- Author(s): ----
---- Andrew Mulcock, amulcock@opencores.org ----
---- ----
---- Modified for WR Project by Tomasz Wlostowski ----
----------------------------------------------------------------------------
---- ----
---- Copyright (C) 2008 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU Lesser General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.1 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU Lesser General Public License for more ----
---- details. ----
---- ----
---- You should have received a copy of the GNU Lesser General ----
---- Public License along with this source; if not, download it ----
---- from http://www.opencores.org/lgpl.shtml ----
---- ----
----------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.genram_pkg.all;
entity generic_shiftreg_fifo is
generic (
g_data_width : integer := 128;
g_size : integer := 32
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
full_o : out std_logic;
almost_full_o : out std_logic;
q_valid_o : out std_logic
);
end generic_shiftreg_fifo;
architecture rtl of generic_shiftreg_fifo is
component gc_shiftreg
generic (
g_size : integer);
port (
clk_i : in std_logic;
en_i : in std_logic;
d_i : in std_logic;
q_o : out std_logic;
a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0));
end component;
signal pointer : integer range 0 to g_size-1;
signal srl_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal pointer_zero : std_logic;
signal pointer_full : std_logic;
signal pointer_almost_full : std_logic;
signal empty : std_logic := '1';
signal valid_count : std_logic;
signal do_write : std_logic;
begin
-- Valid write, high when valid to write data to the store.
do_write <= '1' when (rd_i = '1' and we_i = '1')
or (we_i = '1' and pointer_full = '0') else '0';
gen_sregs: for i in 0 to g_data_width-1 generate
U_SRLx: gc_shiftreg
generic map (
g_size => g_size)
port map (
clk_i => clk_i,
en_i => do_write,
d_i => d_i(i),
q_o => q_o(i),
a_i => srl_addr);
end generate gen_sregs;
srl_addr <= std_logic_vector(to_unsigned(pointer, srl_addr'length));
p_empty_logic : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
empty <= '1';
elsif empty = '1' and we_i = '1' then
empty <= '0';
elsif pointer_zero = '1' and rd_i = '1' and we_i = '0' then
empty <= '1';
end if;
end if;
end process;
-- W R Action
-- 0 0 pointer <= pointer
-- 0 1 pointer <= pointer - 1 Read, but no write, so less data in counter
-- 1 0 pointer <= pointer + 1 Write, but no read, so more data in fifo
-- 1 1 pointer <= pointer Read and write, so same number of words in fifo
--
valid_count <= '1' when (
(we_i = '1' and rd_i = '0' and pointer_full = '0' and empty = '0')
or
(we_i = '0' and rd_i = '1' and pointer_zero = '0')
) else '0';
p_gen_address : process(clk_i)
begin
if rising_edge(clk_i) then
if valid_count = '1' then
if we_i = '1' then
pointer <= pointer + 1;
else
pointer <= pointer - 1;
end if;
end if;
end if;
end process;
-- Detect when pointer is zero and maximum
pointer_zero <= '1' when pointer = 0 else '0';
pointer_full <= '1' when pointer = g_size - 1 else '0';
pointer_almost_full <= '1' when pointer_full = '1' or pointer = g_size - 2 else '0';
-- assign internal signals to outputs
full_o <= pointer_full;
almost_full_o <= pointer_almost_full;
q_valid_o <= not empty;
end rtl;
-------------------------------------------------------------------------------
-- Title : Main package file
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : genram_pkg.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2012-01-24
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package genram_pkg is
function f_log2_size (A : natural) return natural;
function f_gen_dummy_vec (val : std_logic; size : natural) return std_logic_vector;
type t_generic_ram_init is array (integer range <>, integer range <>) of std_logic;
-- Generic RAM initialized with nothing.
constant c_generic_ram_nothing : t_generic_ram_init(-1 downto 0, -1 downto 0) :=
(others => (others => '0'));
-- Single-port synchronous RAM
component generic_spram
generic (
g_data_width : natural;
g_size : natural;
g_with_byte_enable : boolean := false;
g_init_file : string := "";
g_addr_conflict_resolution : string := "read_first") ;
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
bwe_i : in std_logic_vector((g_data_width+7)/8-1 downto 0):= f_gen_dummy_vec('1', (g_data_width+7)/8);
we_i : in std_logic;
a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
d_i : in std_logic_vector(g_data_width-1 downto 0) := f_gen_dummy_vec('0', g_data_width);
q_o : out std_logic_vector(g_data_width-1 downto 0));
end component;
component generic_dpram
generic (
g_data_width : natural;
g_size : natural;
g_with_byte_enable : boolean := false;
g_addr_conflict_resolution : string := "read_first";
g_init_file : string := "";
g_init_value : t_generic_ram_init := c_generic_ram_nothing;
g_dual_clock : boolean := true);
port (
rst_n_i : in std_logic := '1';
clka_i : in std_logic;
bwea_i : in std_logic_vector((g_data_width+7)/8-1 downto 0) := f_gen_dummy_vec('1', (g_data_width+7)/8);
wea_i : in std_logic := '0';
aa_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
da_i : in std_logic_vector(g_data_width-1 downto 0) := f_gen_dummy_vec('0', g_data_width);
qa_o : out std_logic_vector(g_data_width-1 downto 0);
clkb_i : in std_logic;
bweb_i : in std_logic_vector((g_data_width+7)/8-1 downto 0) := f_gen_dummy_vec('1', (g_data_width+7)/8);
web_i : in std_logic := '0';
ab_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
db_i : in std_logic_vector(g_data_width-1 downto 0) := f_gen_dummy_vec('0', g_data_width);
qb_o : out std_logic_vector(g_data_width-1 downto 0));
end component;
component generic_async_fifo
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
g_with_rd_empty : boolean := true;
g_with_rd_full : boolean := false;
g_with_rd_almost_empty : boolean := false;
g_with_rd_almost_full : boolean := false;
g_with_rd_count : boolean := false;
g_with_wr_empty : boolean := false;
g_with_wr_full : boolean := true;
g_with_wr_almost_empty : boolean := false;
g_with_wr_almost_full : boolean := false;
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer := 0;
g_almost_full_threshold : integer := 0);
port (
rst_n_i : in std_logic := '1';
clk_wr_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_almost_empty_o : out std_logic;
wr_almost_full_o : out std_logic;
wr_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
clk_rd_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_almost_empty_o : out std_logic;
rd_almost_full_o : out std_logic;
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0));
end component;
component generic_sync_fifo
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
g_with_empty : boolean := true;
g_with_full : boolean := true;
g_with_almost_empty : boolean := false;
g_with_almost_full : boolean := false;
g_with_count : boolean := false;
g_almost_empty_threshold : integer := 0;
g_almost_full_threshold : integer := 0);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
empty_o : out std_logic;
full_o : out std_logic;
almost_empty_o : out std_logic;
almost_full_o : out std_logic;
count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0));
end component;
component generic_shiftreg_fifo
generic (
g_data_width : integer;
g_size : integer);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
full_o : out std_logic;
almost_full_o : out std_logic;
q_valid_o : out std_logic
);
end component;
end genram_pkg;
package body genram_pkg is
function f_log2_size (A : natural) return natural is
begin
for I in 1 to 64 loop -- Works for up to 64 bits
if (2**I >= A) then
return(I);
end if;
end loop;
return(63);
end function f_log2_size;
function f_gen_dummy_vec (val : std_logic; size : natural) return std_logic_vector is
variable tmp : std_logic_vector(size-1 downto 0);
begin
for i in 0 to size-1 loop
tmp(i) := val;
end loop; -- i
return tmp;
end f_gen_dummy_vec;
end genram_pkg;
-------------------------------------------------------------------------------
-- Title : Parametrizable asynchronous FIFO (Generic version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_async_fifo.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2012-07-13
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Dual-clock asynchronous FIFO.
-- - configurable data width and size
-- - configurable full/empty/almost full/almost empty/word count signals
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
entity inferred_async_fifo is
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
-- Read-side flag selection
g_with_rd_empty : boolean := true; -- with empty flag
g_with_rd_full : boolean := false; -- with full flag
g_with_rd_almost_empty : boolean := false;
g_with_rd_almost_full : boolean := false;
g_with_rd_count : boolean := false; -- with words counter
g_with_wr_empty : boolean := false;
g_with_wr_full : boolean := true;
g_with_wr_almost_empty : boolean := false;
g_with_wr_almost_full : boolean := false;
g_with_wr_count : boolean := false;
g_almost_empty_threshold : integer; -- threshold for almost empty flag
g_almost_full_threshold : integer -- threshold for almost full flag
);
port (
rst_n_i : in std_logic := '1';
-- write port
clk_wr_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
wr_empty_o : out std_logic;
wr_full_o : out std_logic;
wr_almost_empty_o : out std_logic;
wr_almost_full_o : out std_logic;
wr_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-- read port
clk_rd_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
rd_empty_o : out std_logic;
rd_full_o : out std_logic;
rd_almost_empty_o : out std_logic;
rd_almost_full_o : out std_logic;
rd_count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
end inferred_async_fifo;
architecture syn of inferred_async_fifo is
function f_bin2gray(bin : unsigned) return unsigned is
begin
return bin(bin'left) & (bin(bin'left-1 downto 0) xor bin(bin'left downto 1));
end f_bin2gray;
function f_gray2bin(gray : unsigned) return unsigned is
variable bin : unsigned(gray'left downto 0);
begin
-- gray to binary
for i in 0 to gray'left loop
bin(i) := '0';
for j in i to gray'left loop
bin(i) := bin(i) xor gray(j);
end loop; -- j
end loop; -- i
return bin;
end f_gray2bin;
subtype t_counter is unsigned(f_log2_size(g_size) downto 0);
type t_counter_block is record
bin, bin_next, gray, gray_next : t_counter;
bin_x, gray_x, gray_xm : t_counter;
end record;
type t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
signal mem : t_mem_type;
signal rcb, wcb : t_counter_block;
attribute ASYNC_REG : string;
attribute ASYNC_REG of wcb: signal is "TRUE";
attribute ASYNC_REG of rcb: signal is "TRUE";
signal full_int, empty_int : std_logic;
signal almost_full_int, almost_empty_int : std_logic;
signal going_full : std_logic;
signal wr_count, rd_count : t_counter;
signal we : std_logic;
begin -- syn
we <= we_i and not full_int;
p_mem_write : process(clk_wr_i)
begin
if rising_edge(clk_wr_i) then
if(we = '1') then
mem(to_integer(wcb.bin(wcb.bin'left-1 downto 0))) <= d_i;
end if;
end if;
end process;
p_mem_read : process(clk_rd_i)
begin
if rising_edge(clk_rd_i) then
if(rd_i = '1' and empty_int = '0') then
q_o <= mem(to_integer(rcb.bin(rcb.bin'left-1 downto 0)));
end if;
end if;
end process;
wcb.bin_next <= wcb.bin + 1;
wcb.gray_next <= f_bin2gray(wcb.bin_next);
p_write_ptr : process(clk_wr_i, rst_n_i)
begin
if rst_n_i = '0' then
wcb.bin <= (others => '0');
wcb.gray <= (others => '0');
elsif rising_edge(clk_wr_i) then
if(we_i = '1' and full_int = '0') then
wcb.bin <= wcb.bin_next;
wcb.gray <= wcb.gray_next;
end if;
end if;
end process;
rcb.bin_next <= rcb.bin + 1;
rcb.gray_next <= f_bin2gray(rcb.bin_next);
p_read_ptr : process(clk_rd_i, rst_n_i)
begin
if rst_n_i = '0' then
rcb.bin <= (others => '0');
rcb.gray <= (others => '0');
elsif rising_edge(clk_rd_i) then
if(rd_i = '1' and empty_int = '0') then
rcb.bin <= rcb.bin_next;
rcb.gray <= rcb.gray_next;
end if;
end if;
end process;
p_sync_read_ptr : process(clk_wr_i)
begin
if rising_edge(clk_wr_i) then
rcb.gray_xm <= rcb.gray;
rcb.gray_x <= rcb.gray_xm;
end if;
end process;
p_sync_write_ptr : process(clk_rd_i)
begin
if rising_edge(clk_rd_i) then
wcb.gray_xm <= wcb.gray;
wcb.gray_x <= wcb.gray_xm;
end if;
end process;
wcb.bin_x <= f_gray2bin(wcb.gray_x);
rcb.bin_x <= f_gray2bin(rcb.gray_x);
p_gen_empty : process(clk_rd_i, rst_n_i)
begin
if rst_n_i = '0' then
empty_int <= '1';
elsif rising_edge (clk_rd_i) then
if(rcb.gray = wcb.gray_x or (rd_i = '1' and (wcb.gray_x = rcb.gray_next))) then
empty_int <= '1';
else
empty_int <= '0';
end if;
end if;
end process;
p_gen_going_full : process(we_i, wcb, rcb)
begin
if ((wcb.bin (wcb.bin'left-1 downto 0) = rcb.bin_x(rcb.bin_x'left-1 downto 0))
and (wcb.bin(wcb.bin'left) /= rcb.bin_x(wcb.bin_x'left))) then
going_full <= '1';
elsif (we_i = '1'
and (wcb.bin_next(wcb.bin'left-1 downto 0) = rcb.bin_x(rcb.bin_x'left-1 downto 0))
and (wcb.bin_next(wcb.bin'left) /= rcb.bin_x(rcb.bin_x'left))) then
going_full <= '1';
else
going_full <= '0';
end if;
end process;
p_register_full : process(clk_wr_i, rst_n_i)
begin
if rst_n_i = '0' then
full_int <= '0';
elsif rising_edge (clk_wr_i) then
full_int <= going_full;
end if;
end process;
wr_full_o <= full_int;
rd_empty_o <= empty_int;
p_reg_almost_full : process(clk_wr_i, rst_n_i)
begin
if rst_n_i = '0' then
almost_full_int <= '0';
elsif rising_edge(clk_wr_i) then
wr_count <= wcb.bin - rcb.bin_x;
if (wr_count >= g_almost_full_threshold) then
almost_full_int <= '1';
else
almost_full_int <= '0';
end if;
end if;
end process;
p_reg_almost_empty : process(clk_rd_i, rst_n_i)
begin
if rst_n_i = '0' then
almost_empty_int <= '1';
elsif rising_edge(clk_rd_i) then
rd_count <= wcb.bin_x - rcb.bin;
if (rd_count <= g_almost_empty_threshold) then
almost_empty_int <= '1';
else
almost_empty_int <= '0';
end if;
end if;
end process;
rd_almost_empty_o <= almost_empty_int;
wr_almost_full_o <= almost_full_int;
wr_count_o <= std_logic_vector(wr_count(f_log2_size(g_size)-1 downto 0));
rd_count_o <= std_logic_vector(rd_count(f_log2_size(g_size)-1 downto 0));
end syn;
-------------------------------------------------------------------------------
-- Title : Parametrizable synchronous FIFO (Generic version)
-- Project : Generics RAMs and FIFOs collection
-------------------------------------------------------------------------------
-- File : generic_sync_fifo_std.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2011-01-25
-- Last update: 2012-09-18
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Single-clock FIFO.
-- - configurable data width and size
-- - configurable full/empty/almost full/almost empty/word count signals
-------------------------------------------------------------------------------
-- Copyright (c) 2011 CERN
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2011-01-25 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
entity inferred_sync_fifo is
generic (
g_data_width : natural;
g_size : natural;
g_show_ahead : boolean := false;
-- Read-side flag selection
g_with_empty : boolean := true; -- with empty flag
g_with_full : boolean := true; -- with full flag
g_with_almost_empty : boolean := false;
g_with_almost_full : boolean := false;
g_with_count : boolean := false; -- with words counter
g_almost_empty_threshold : integer := 0; -- threshold for almost empty flag
g_almost_full_threshold : integer := 0; -- threshold for almost full flag
g_register_flag_outputs : boolean := true
);
port (
rst_n_i : in std_logic := '1';
clk_i : in std_logic;
d_i : in std_logic_vector(g_data_width-1 downto 0);
we_i : in std_logic;
q_o : out std_logic_vector(g_data_width-1 downto 0);
rd_i : in std_logic;
empty_o : out std_logic;
full_o : out std_logic;
almost_empty_o : out std_logic;
almost_full_o : out std_logic;
count_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
);
end inferred_sync_fifo;
architecture syn of inferred_sync_fifo is
constant c_pointer_width : integer := f_log2_size(g_size);
signal rd_ptr, wr_ptr, wr_ptr_d0, rd_ptr_muxed : unsigned(c_pointer_width-1 downto 0);
signal usedw : unsigned(c_pointer_width downto 0);
signal full, empty : std_logic;
signal q_int : std_logic_vector(g_data_width-1 downto 0);
signal we : std_logic;
signal guard_bit : std_logic;
signal q_reg, q_comb : std_logic_vector(g_data_width-1 downto 0);
begin -- syn
--assert g_show_ahead = false report "Show ahead mode not implemented (yet). Sorry" severity failure;
we <= we_i and not full;
U_FIFO_Ram : generic_dpram
generic map (
g_data_width => g_data_width,
g_size => g_size,
g_with_byte_enable => false,
g_addr_conflict_resolution => "read_first",
g_dual_clock => false)
port map (
rst_n_i => rst_n_i,
clka_i => clk_i,
wea_i => we,
aa_i => std_logic_vector(wr_ptr(c_pointer_width-1 downto 0)),
da_i => d_i,
clkb_i => '0',
ab_i => std_logic_vector(rd_ptr_muxed(c_pointer_width-1 downto 0)),
qb_o => q_comb);
p_output_reg : process(clk_i)
begin
if rising_edge(clk_i) then
if rd_i = '1' then
q_reg <= q_comb;
end if;
end if;
end process;
process(rd_ptr, rd_i)
begin
if(rd_i = '1' and g_show_ahead) then
rd_ptr_muxed <= rd_ptr + 1;
elsif((rd_i = '1' and not g_show_ahead) or (g_show_ahead)) then
rd_ptr_muxed <= rd_ptr;
else
rd_ptr_muxed <= rd_ptr - 1;
end if;
end process;
-- q_o <= q_comb when g_show_ahead = true else q_reg;
q_o <= q_comb;
p_pointers : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
wr_ptr <= (others => '0');
rd_ptr <= (others => '0');
else
if(we_i = '1' and full = '0') then
wr_ptr <= wr_ptr + 1;
end if;
if(rd_i = '1' and empty = '0') then
rd_ptr <= rd_ptr + 1;
end if;
end if;
end if;
end process;
gen_comb_flags_showahead : if(g_show_ahead = true) generate
process(clk_i)
begin
if rising_edge(clk_i) then
if ((rd_ptr + 1 = wr_ptr and rd_i = '1') or (rd_ptr = wr_ptr)) then
empty <= '1';
else
empty <= '0';
end if;
end if;
end process;
full <= '1' when (wr_ptr + 1 = rd_ptr) else '0';
end generate gen_comb_flags_showahead;
gen_comb_flags : if(g_register_flag_outputs = false and g_show_ahead = false) generate
empty <= '1' when (wr_ptr = rd_ptr and guard_bit = '0') else '0';
full <= '1' when (wr_ptr = rd_ptr and guard_bit = '1') else '0';
p_guard_bit : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
guard_bit <= '0';
elsif(wr_ptr + 1 = rd_ptr and we_i = '1') then
guard_bit <= '1';
elsif(rd_i = '1') then
guard_bit <= '0';
end if;
end if;
end process;
end generate gen_comb_flags;
gen_registered_flags : if(g_register_flag_outputs = true and g_show_ahead = false) generate
p_reg_flags : process(clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
full <= '0';
empty <= '1';
else
if(usedw = 1 and rd_i = '1' and we_i = '0') then
empty <= '1';
elsif(we_i = '1' and rd_i = '0') then
empty <= '0';
end if;
if(usedw = g_size-2 and we_i = '1' and rd_i = '0') then
full <= '1';
elsif(usedw = g_size-1 and rd_i = '1' and we_i = '0') then
full <= '0';
end if;
end if;
end if;
end process;
end generate gen_registered_flags;
gen_with_word_counter : if(g_with_count or g_with_almost_empty or g_with_almost_full or g_register_flag_outputs) generate
p_usedw_counter : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
usedw <= (others => '0');
else
if(we_i = '1' and rd_i = '0' and full = '0') then
usedw <= usedw + 1;
elsif(we_i = '0' and rd_i = '1' and empty = '0') then
usedw <= usedw - 1;
end if;
end if;
end if;
end process;
count_o <= std_logic_vector(usedw(c_pointer_width-1 downto 0));
end generate gen_with_word_counter;
gen_with_almost_full : if(g_with_almost_full) generate
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
almost_full_o <= '0';
else
if(usedw = g_almost_full_threshold-1) then
if(we_i = '1' and rd_i = '0') then
almost_full_o <= '1';
elsif(rd_i = '1' and we_i = '0') then
almost_full_o <= '0';
end if;
end if;
end if;
end if;
end process;
end generate gen_with_almost_full;
gen_with_almost_empty : if(g_with_almost_empty) generate
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
almost_empty_o <= '1';
else
if(usedw = g_almost_empty_threshold+1) then
if(rd_i = '1' and we_i = '0') then
almost_empty_o <= '1';
elsif(we_i = '1' and rd_i = '0') then
almost_empty_o <= '0';
end if;
end if;
end if;
end if;
end process;
end generate gen_with_almost_empty;
full_o <= full;
empty_o <= empty;
end syn;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.textio.all;
library work;
use work.genram_pkg.all;
package memory_loader_pkg is
subtype t_meminit_array is t_generic_ram_init;
function f_hexchar_to_slv (c : character) return std_logic_vector;
function f_hexstring_to_slv (s : string; n_digits : integer) return std_logic_vector;
function f_get_token(s : string; n : integer) return string;
function f_load_mem_from_file
(file_name : string;
mem_size : integer;
mem_width : integer;
fail_if_notfound : boolean)
return t_meminit_array;
end memory_loader_pkg;
package body memory_loader_pkg is
function f_hexchar_to_slv (c : character) return std_logic_vector is
variable t : std_logic_vector(3 downto 0);
begin
case c is
when '0' => t := x"0";
when '1' => t := x"1";
when '2' => t := x"2";
when '3' => t := x"3";
when '4' => t := x"4";
when '5' => t := x"5";
when '6' => t := x"6";
when '7' => t := x"7";
when '8' => t := x"8";
when '9' => t := x"9";
when 'a' => t := x"a";
when 'A' => t := x"a";
when 'b' => t := x"b";
when 'B' => t := x"b";
when 'c' => t := x"c";
when 'C' => t := x"c";
when 'd' => t := x"d";
when 'D' => t := x"d";
when 'e' => t := x"e";
when 'E' => t := x"e";
when 'f' => t := x"f";
when 'F' => t := x"f";
when others =>
report "f_hexchar_to_slv(): unrecognized character '" &c&" in hex text string" severity failure;
end case;
return t;
end f_hexchar_to_slv;
function f_hexstring_to_slv (s : string; n_digits : integer) return std_logic_vector is
variable tmp : std_logic_vector(255 downto 0) := (others => '0');
begin
if s'length > tmp'length then
report "f_hexstring_to_slv(): string length exceeds the limit" severity failure;
end if;
for i in 0 to s'length-1 loop
tmp(4 * (s'length - i) - 1 downto 4 * (s'length - 1 - i)) := f_hexchar_to_slv(s(i+1));
end loop; -- i
return tmp(n_digits * 4 - 1 downto 0);
end f_hexstring_to_slv;
function f_get_token(s : string; n : integer) return string is
variable cur_pos : integer;
variable tmp : string (1 to 128);
variable cur_token : integer;
variable tmp_pos : integer;
begin
cur_pos := 1;
cur_token := 1;
tmp_pos := 1;
loop
if(cur_pos >= s'length) then
return "";
end if;
while cur_pos <= s'length and (s(cur_pos) = ' ' or s(cur_pos) = character'val(9) or s(cur_pos) = character'val(0)) loop
cur_pos := cur_pos + 1;
end loop;
if(cur_pos >= s'length) then
return "";
end if;
while(cur_pos <= s'length and s(cur_pos) /= ' ' and s(cur_pos) /= character'val(9) and s(cur_pos) /= character'val(0)) loop
if(cur_token = n) then
tmp(tmp_pos) := s(cur_pos);
tmp_pos := tmp_pos + 1;
end if;
cur_pos := cur_pos + 1;
end loop;
if(cur_token = n) then
return tmp(1 to tmp_pos-1);
end if;
cur_token := cur_token + 1;
if(cur_pos >= s'length) then
return "";
end if;
end loop;
return "";
end f_get_token;
function f_load_mem_from_file
(file_name : string;
mem_size : integer;
mem_width : integer;
fail_if_notfound : boolean)
return t_meminit_array is
file f_in : text;
variable l : line;
variable ls : string(1 to 128);
variable cmd : string(1 to 128);
variable line_len : integer;
variable status : file_open_status;
variable mem : t_meminit_array(0 to mem_size-1, mem_width-1 downto 0);
variable i : integer;
variable c : character;
variable good : boolean;
variable addr : integer;
variable data_tmp : unsigned(mem_width-1 downto 0);
variable data_int : integer;
begin
if(file_name = "") then
mem := (others => (others => '0'));
return mem;
end if;
file_open(status, f_in, file_name, read_mode);
if(status /= open_ok) then
if(fail_if_notfound) then
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity failure;
else
report "f_load_mem_from_file(): can't open file '"&file_name&"'" severity warning;
end if;
end if;
while true loop
i := 0;
while (i < 4096) loop
-- stupid ISE restricts the loop length
readline(f_in, l);
line_len := 0;
loop
read(l, ls(line_len+1), good);
exit when good = false;
line_len := line_len + 1;
end loop;
if(line_len /= 0 and f_get_token(ls, 1) = "write") then
addr := to_integer(unsigned(f_hexstring_to_slv(f_get_token(ls, 2), 8)));
data_tmp := resize(unsigned(f_hexstring_to_slv(f_get_token(ls, 3), 8)), mem_width);
data_int := to_integer(data_tmp);
-- report "addr: " & integer'image(addr) & " data: " & integer'image(data_int);
for i in 0 to mem_width-1 loop
mem(addr, i) := std_logic(data_tmp(i));
end loop; -- i in 0 to mem_width-1
-- report "addr: " & integer'image(addr) & " data: " & integer'image(data_int);
end if;
if endfile(f_in) then
file_close(f_in);
return mem;
end if;
i := i+1;
end loop;
end loop;
return mem;
end f_load_mem_from_file;
end memory_loader_pkg;
files = [
"generic_dpram.vhd",
"generic_dpram_sameclock.vhd",
"generic_dpram_dualclock.vhd",
"generic_spram.vhd",
"gc_shiftreg.vhd"]
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.genram_pkg.all;
entity gc_shiftreg is
generic (
g_size : integer);
port (
clk_i : in std_logic;
en_i : in std_logic;
d_i : in std_logic;
q_o : out std_logic;
a_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0));
end gc_shiftreg;
architecture wrapper of gc_shiftreg is
component SRLC32E
port (
Q : out std_ulogic;
A : in std_logic_vector (4 downto 0);
CE : in std_ulogic;
CLK : in std_ulogic;
D : in std_ulogic);
end component;
signal a : std_logic_vector(4 downto 0);
signal sr : std_logic_vector(g_size-1 downto 0);
begin -- wrapper
assert (g_size <= 32) report "gc_shiftreg[xilinx]: forced SRL32 implementation can be done only for 32-bit or smaller shift registers" severity warning;
a <= std_logic_vector(resize(unsigned(a_i), 5));
gen_srl32 : if(g_size <= 32) generate
U_SRLC32 : SRLC32E
port map (
Q => q_o,
A => a,
CE => en_i,
CLK => clk_i,
D => d_i);
end generate gen_srl32;
gen_inferred : if(g_size > 32) generate
p_srl : process(clk_i)
begin
if rising_edge(clk_i) then
if en_i = '1' then
sr <= sr(sr'left - 1 downto 0) & d_i;
end if;
end if;
end process;
q_o <= sr(TO_INTEGER(unsigned(a_i)));
end generate gen_inferred;
end wrapper;
files =["v6_fifo_pkg.vhd", "v6_hwfifo_wrapper.vhd", "generic_async_fifo.vhd", "generic_sync_fifo.vhd"];
package v6_fifo_pkg is
type t_v6_fifo_mapping is record
d_width : integer;
dp_width : integer;
entries : integer;
is_36 : boolean;
end record;
type t_v6_fifo_mapping_array is array(integer range <>) of t_v6_fifo_mapping;
constant c_v6_fifo_mappings : t_v6_fifo_mapping_array (0 to 9) := (
0 => (d_width => 4, dp_width => 0, entries => 4096, is_36 => false),
1 => (d_width => 8, dp_width => 1, entries => 2048, is_36 => false),
2 => (d_width => 16, dp_width => 2, entries => 1024, is_36 => false),
3 => (d_width => 32, dp_width => 4, entries => 512, is_36 => false),
4 => (d_width => 32, dp_width => 4, entries => 1024, is_36 => true),
5 => (d_width => 4, dp_width => 0, entries => 8192, is_36 => true),
6 => (d_width => 8, dp_width => 1, entries => 4096, is_36 => true),
7 => (d_width => 16, dp_width => 2, entries => 2048, is_36 => true),
8 => (d_width => 32, dp_width => 4, entries => 1024, is_36 => true),
9 => (d_width => 64, dp_width => 8, entries => 512, is_36 => true));
impure function f_v6_fifo_find_mapping
(data_width : integer; size : integer) return t_v6_fifo_mapping;
function f_v6_fifo_mode (m : t_v6_fifo_mapping) return string;
end v6_fifo_pkg;
package body v6_fifo_pkg is
impure function f_v6_fifo_find_mapping
(data_width : integer; size : integer) return t_v6_fifo_mapping is
variable tmp : t_v6_fifo_mapping;
begin
for i in 0 to c_v6_fifo_mappings'length-1 loop
if(c_v6_fifo_mappings(i).d_width + c_v6_fifo_mappings(i).dp_width >= data_width and c_v6_fifo_mappings(i).entries >= size) then
return c_v6_fifo_mappings(i);
end if;
end loop;
tmp.d_width := 0;
return tmp;
end f_v6_fifo_find_mapping;
function f_v6_fifo_mode (m : t_v6_fifo_mapping) return string is
begin
if(m.d_width = 64 and m.is_36 = true) then
return "FIFO36_72";
elsif(m.d_width = 32 and m.is_36 = false) then
return "FIFO18_36";
elsif(m.is_36 = true) then
return "FIFO36";
else
return "FIFO18";
end if;
return "";
end f_v6_fifo_mode;
end v6_fifo_pkg;
modules = { "local" :
[
"wb_async_bridge",
"wb_onewire_master",
"wb_i2c_master",
"wb_bus_fanout",
"wb_dpram",
"wb_gpio_port",
"wb_simple_timer",
"wb_uart",
"wb_vic",
"wb_spi",
"wb_crossbar",
"wb_lm32",
"wb_slave_adapter",
"wb_xilinx_fpga_loader",
"wb_clock_crossing",
"wb_dma",
"wbgen2"
]};
files = ["wishbone_pkg.vhd"];
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment