Commit 608b336b authored by egousiou's avatar egousiou

added missing ip_cores/genrams folder

git-svn-id: http://svn.ohwr.org/fmc-tdc@133 85dfdc96-de2c-444c-878d-45b388be74a9
parent 7b2e72d4
----------------------------------------------------------------------------
---- ----
---- ----
---- 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
constant c_srl_length : integer := g_size; -- set to srl 'type' 16 or 32 bit length
type t_srl_array is array (c_srl_length - 1 downto 0) of std_logic_vector (g_data_width - 1 downto 0);
signal fifo_store : t_srl_array;
signal pointer : integer range 0 to c_srl_length - 1;
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';
-- data store SRL's
p_data_srl : process(clk_i)
begin
if rising_edge(clk_i) then
-- if rst_n_i = '0'then
-- for i in 0 to c_srl_length-1 loop
-- fifo_store(i) <= (others => '0');
-- end loop; -- i
if do_write = '1' then
fifo_store <= fifo_store(fifo_store'left - 1 downto 0) & d_i;
end if;
end if;
end process;
q_o <= fifo_store(pointer);
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 = c_srl_length - 1 else '0';
pointer_almost_full <= '1' when pointer_full = '1' or pointer = c_srl_length - 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;
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