Commit f852caa9 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

modules/wrsw_swcore/async_mpm: wip

parent 057eba7d
files = ["swc_async_grow_fifo.vhd",
"swc_async_fifo_ctrl.vhd",
"swc_fifo_mem_cell.vhd",
"swc_async_shrink_fifo.vhd",
"swc_private_pkg.vhd",
"swc_pipelined_mux.vhd",
"swc_async_multiport_mem.vhd"]
files = ["mpm_async_grow_fifo.vhd",
"mpm_async_fifo_ctrl.vhd",
"mpm_fifo_mem_cell.vhd",
"mpm_async_shrink_fifo.vhd",
"mpm_private_pkg.vhd",
"mpm_pipelined_mux.vhd",
"mpm_top.vhd",
"mpm_write_path.vhd",
"mpm_read_path.vhd",
"mpm_async_fifo.vhd",
"mpm_rpath_io_block.vhd"]
......@@ -4,20 +4,19 @@ use ieee.numeric_std.all;
use work.genram_pkg.all; -- for f_log2_size
entity swc_async_shrink_fifo is
entity mpm_async_fifo is
generic (
g_width : integer; -- narrow port width
g_ratio : integer;
g_size : integer);
g_width : integer := 11 + 1;
g_size : integer := 8);
port (
rst_n_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
we_i : in std_logic;
d_i : in std_logic_vector(g_width*g_ratio-1 downto 0);
d_i : in std_logic_vector(g_width-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width-1 downto 0);
......@@ -25,11 +24,11 @@ entity swc_async_shrink_fifo is
full_o : out std_logic;
empty_o : out std_logic);
end swc_async_shrink_fifo;
end mpm_async_fifo;
architecture rtl of swc_async_shrink_fifo is
architecture rtl of mpm_async_fifo is
component swc_fifo_mem_cell
component mpm_fifo_mem_cell
generic (
g_width : integer;
g_size : integer);
......@@ -42,11 +41,11 @@ architecture rtl of swc_async_shrink_fifo is
rd_o : out std_logic_vector(g_width-1 downto 0));
end component;
component swc_async_fifo_ctrl
component mpm_async_fifo_ctrl
generic (
g_size : integer);
port (
rst_n_i : in std_logic;
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rd_i : in std_logic;
......@@ -57,66 +56,44 @@ architecture rtl of swc_async_shrink_fifo is
empty_o : out std_logic);
end component;
signal rd_count : unsigned(3 downto 0);
signal real_rd : std_logic;
signal q_int : std_logic_vector(g_width*g_ratio-1 downto 0);
signal q_comb : std_logic_vector(g_width-1 downto 0);
signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal empty_int : std_logic;
signal line_flushed : std_logic;
begin -- rtl
gen_mem_cells : for i in 0 to g_ratio-1 generate
U_Mem : swc_fifo_mem_cell
generic map (
g_width => g_width,
g_size => g_size)
port map (
clk_i => clk_wr_i,
wa_i => wr_addr,
wd_i => d_i(g_width*(i+1) -1 downto g_width*i),
we_i => we_i,
ra_i => rd_addr,
rd_o => q_int(g_width*(i+1) -1 downto g_width*i));
end generate gen_mem_cells;
U_CTRL : swc_async_fifo_ctrl
U_Mem_Mem : mpm_fifo_mem_cell
generic map (
g_width => g_width,
g_size => g_size)
port map (
clk_i => clk_wr_i,
wa_i => wr_addr,
wd_i => d_i,
we_i => we_i,
ra_i => rd_addr,
rd_o => q_comb);
U_CTRL : mpm_async_fifo_ctrl
generic map (
g_size => g_size)
port map (
rst_n_i => rst_n_i,
rst_n_a_i => rst_n_a_i,
clk_wr_i => clk_wr_i,
clk_rd_i => clk_rd_i,
rd_i => real_rd,
rd_i => rd_i,
wr_i => we_i,
wr_addr_o => wr_addr,
rd_addr_o => rd_addr,
full_o => full_o,
empty_o => empty_int);
empty_o => empty_o);
p_read_mux : process(clk_rd_i, rst_n_i)
p_output_reg : process(clk_rd_i)
begin
if rst_n_i = '0' then
rd_count <= (others => '0');
q_o <= (others => '0');
elsif rising_edge(clk_rd_i) then
if(rd_i = '1' and empty_int = '0') then
if(rd_count = g_ratio-1) then
rd_count <= (others => '0');
else
rd_count <= rd_count + 1;
end if;
q_o <= q_int(((to_integer(rd_count)+1)*g_width)-1 downto to_integer(rd_count)*g_width);
end if;
if rising_edge(clk_rd_i) then
q_o <= q_comb;
end if;
end process;
line_flushed <= '1' when (rd_count = g_ratio-1) else '0';
real_rd <= line_flushed and rd_i;
empty_o <= empty_int and line_flushed;
end rtl;
......@@ -2,7 +2,7 @@
-- Title : Dual clock (asynchronous) FIFO controller
-- Project : White Rabbit Switch
-------------------------------------------------------------------------------
-- File : swc_async_fifo_ctrl.vhd
-- File : mpm_async_fifo_ctrl.vhd
-- Author : Tomasz Włostowski
-- Company : CERN BE-CO-HT
-- Created : 2012-01-30
......@@ -13,7 +13,7 @@
-------------------------------------------------------------------------------
-- Description: Gray-encoded dual clock FIFO controller and address generator.
-- Based on Xilinx Application Note "Asynchronous FIFO in Virtex-II FPGAs" by
-- P. Alfke & example code from http://www.asic-world.com.
-- P. Alfke & Generic FIFO project by Rudolf Usselmann.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012 CERN
......@@ -46,15 +46,15 @@ use ieee.numeric_std.all;
use work.genram_pkg.all;
entity swc_async_fifo_ctrl is
entity mpm_async_fifo_ctrl is
generic (
g_size : integer);
port(
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rd_i : in std_logic;
wr_i : in std_logic;
......@@ -62,103 +62,135 @@ entity swc_async_fifo_ctrl is
wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
full_o : out std_logic;
empty_o : out std_logic);
end swc_async_fifo_ctrl;
full_o : out std_logic;
going_full_o : out std_logic;
empty_o : out std_logic);
end mpm_async_fifo_ctrl;
architecture rtl of mpm_async_fifo_ctrl is
architecture rtl of swc_async_fifo_ctrl 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;
-- Gray-encoded increase-by-1 function. Takes a gray-encoded integer x and returns
-- gray-encoded value of (x+1).
function f_gray_inc(x : unsigned) return unsigned is
variable bin, tmp : unsigned(x'left downto 0);
function f_gray2bin(gray : unsigned) return unsigned is
variable bin : unsigned(gray'left downto 0);
begin
-- gray to binary
for i in 0 to x'left loop
-- gray to binary
for i in 0 to gray'left loop
bin(i) := '0';
for j in i to x'left loop
bin(i) := bin(i) xor x(j);
for j in i to gray'left loop
bin(i) := bin(i) xor gray(j);
end loop; -- j
end loop; -- i
-- increase
tmp := bin + 1;
-- binary to gray
return tmp(tmp'left) & (tmp(tmp'left-1 downto 0) xor tmp(tmp'left downto 1));
end f_gray_inc;
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 : t_counter;
end record;
signal wr_ptr, rd_ptr : unsigned(f_log2_size(g_size) -1 downto 0);
signal rcb, wcb : t_counter_block;
signal full_int, empty_int : std_logic;
signal same_addr : std_logic;
signal rst_stat, set_stat : std_logic;
signal set_full, set_empty : std_logic;
signal stat : std_logic;
signal going_full : std_logic;
begin -- rtl
wcb.bin_next <= wcb.bin + 1;
wcb.gray_next <= f_bin2gray(wcb.bin_next);
p_write_ptr : process(clk_wr_i, rst_n_a_i)
begin
if rst_n_a_i = '0' then
wr_ptr <= (others => '0');
wcb.bin <= (others => '0');
wcb.gray <= (others => '0');
elsif rising_edge(clk_wr_i) then
if(wr_i = '1' and full_int = '0') then
wr_ptr <= f_gray_inc(wr_ptr);
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_a_i)
begin
if rst_n_a_i = '0' then
rd_ptr <= (others => '0');
rcb.bin <= (others => '0');
rcb.gray <= (others => '0');
elsif rising_edge(clk_rd_i) then
if(rd_i = '1' and empty_int = '0') then
rd_ptr <= f_gray_inc(rd_ptr);
rcb.bin <= rcb.bin_next;
rcb.gray <= rcb.gray_next;
end if;
end if;
end process;
p_quardant_status : process(rd_ptr, wr_ptr)
p_sync_read_ptr : process(clk_wr_i)
begin
set_stat <= (wr_ptr(wr_ptr'left-1) xnor rd_ptr(rd_ptr'left))
and (wr_ptr(wr_ptr'left) xor rd_ptr(rd_ptr'left-1));
rst_stat <= (wr_ptr(wr_ptr'left-1) xor rd_ptr(rd_ptr'left))
and (wr_ptr(wr_ptr'left) xnor rd_ptr(rd_ptr'left-1));
if rising_edge(clk_wr_i) then
rcb.gray_x <= rcb.gray;
end if;
end process;
process(set_stat, rst_stat, rst_n_a_i)
p_sync_write_ptr : process(clk_rd_i)
begin
if(rst_stat = '1' or rst_n_a_i = '0') then
stat <= '0';
elsif(set_stat = '1') then
stat <= '1';
if rising_edge(clk_rd_i) then
wcb.gray_x <= wcb.gray;
end if;
end process;
set_full <= '1' when (stat = '1' and wr_ptr = rd_ptr) else '0';
set_empty <= '1' when (stat = '0' and wr_ptr = rd_ptr) else '0';
wcb.bin_x <= f_gray2bin(wcb.gray_x);
rcb.bin_x <= f_gray2bin(rcb.gray_x);
p_full_flag : process(clk_wr_i, set_full)
p_gen_empty : process(clk_rd_i, rst_n_a_i)
begin
if(set_full = '1') then
full_int <= '1';
elsif rising_edge(clk_wr_i) then
full_int <= set_full;
if rst_n_a_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_empty_flag : process(clk_rd_i, set_empty)
p_gen_going_full : process(wr_i, wcb, rcb)
begin
if(set_empty = '1') then
empty_int <= '1';
elsif rising_edge(clk_rd_i) then
empty_int <= set_empty;
if ((wcb.bin (wcb.bin'left-2 downto 0) = rcb.bin_x(rcb.bin_x'left-2 downto 0))
and (wcb.bin(wcb.bin'left) /= rcb.bin_x(wcb.bin_x'left))) then
going_full <= '1';
elsif (wr_i = '1'
and (wcb.bin_next(wcb.bin'left-2 downto 0) = rcb.bin_x(rcb.bin_x'left-2 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_a_i)
begin
if rst_n_a_i = '0' then
full_int <= '0';
elsif rising_edge (clk_wr_i) then
full_int <= going_full;
end if;
end process;
full_o <= full_int;
empty_o <= empty_int;
full_o <= full_int;
empty_o <= empty_int;
going_full_o <= going_full;
wr_addr_o <= std_logic_vector(wr_ptr);
rd_addr_o <= std_logic_vector(rd_ptr);
wr_addr_o <= std_logic_vector(wcb.bin(wcb.bin'left-1 downto 0));
rd_addr_o <= std_logic_vector(rcb.bin(rcb.bin'left-1 downto 0));
end rtl;
-------------------------------------------------------------------------------
-- Title : Dual clock (asynchronous) asymmetric (1:N) FIFO
-- Project : White Rabbit Switch
-------------------------------------------------------------------------------
-- File : swc_async_grow_fifo.vhd
-- Author : Tomasz Włostowski
-- Company : CERN BE-CO-HT
-- Created : 2012-01-30
-- Last update : 2012-01-30
-- Platform : FPGA-generic
-- Standard : VHDL'93
-- Dependencies : swc_fifo_mem_cell, swc_async_fifo_ctrl, genram_pkg
-------------------------------------------------------------------------------
-- Description: Asynchronous FIFO with asymmetric (deserializing) read/write
-- ports. g_ratio words written to input port d_i are combined into a single
-- (g_ratio * g_width) word on port q_o. An additional symmetric
-- sideband channel (side_i/side_o) is provided for passing auxillary data.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2012 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
-- 2012-01-30 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all; -- for f_log2_size
entity mpm_async_grow_fifo is
generic (
-- base data width (narrow port)
g_width : integer := 16;
-- wide/narrow data width ratio
g_ratio : integer := 6;
-- number of wide words in FIFO
g_size : integer := 8;
-- sideband channel (side_i/side_o) width
g_sideband_width : integer := 16);
port (
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
-- 1: write word available on (d_i) to the FIFO
we_i : in std_logic;
-- 1: perform an aligned write (i.e. at the beginning of the wide word)
align_i : in std_logic;
-- data input
d_i : in std_logic_vector(g_width-1 downto 0);
-- 1: performs a read of a single wide word, outputted on q_o
rd_i : in std_logic;
-- registered data output
q_o : out std_logic_vector(g_width * g_ratio-1 downto 0);
-- "Sideband" channel (for passing auxillary data, such as page indices)
side_i : in std_logic_vector(g_sideband_width-1 downto 0);
side_o : out std_logic_vector(g_sideband_width-1 downto 0);
-- Full flag (clk_wr_i domain)
full_o : out std_logic;
-- Empty flag (clk_rd_i domain)
empty_o : out std_logic);
end mpm_async_grow_fifo;
architecture rtl of mpm_async_grow_fifo is
component mpm_fifo_mem_cell
generic (
g_width : integer;
g_size : integer);
port (
clk_i : in std_logic;
wa_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
wd_i : in std_logic_vector(g_width-1 downto 0);
we_i : in std_logic;
ra_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
rd_o : out std_logic_vector(g_width-1 downto 0));
end component;
component mpm_async_fifo_ctrl
generic (
g_size : integer);
port (
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rd_i : in std_logic;
wr_i : in std_logic;
wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
full_o : out std_logic;
going_full_o : out std_logic;
empty_o : out std_logic);
end component;
signal wr_sreg : std_logic_vector(g_ratio-1 downto 0);
signal wr_cell : std_logic_vector(g_ratio-1 downto 0);
signal real_we : std_logic;
signal q_int : std_logic_vector(g_width*g_ratio-1 downto 0);
signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal full_int : std_logic;
signal side_comb : std_logic_vector(g_sideband_width-1 downto 0);
begin -- rtl
-- Genrate g_ratio memory cells, which are written sequentially (each memory
-- block corresponds to a bit in wr_cell shift register) and read all at
-- once, forming a deserializer.
gen_mem_cells : for i in 0 to g_ratio-1 generate
wr_cell(i) <= wr_sreg(i) and we_i;
U_Mem : mpm_fifo_mem_cell
generic map (
g_width => g_width,
g_size => g_size)
port map (
clk_i => clk_wr_i,
wa_i => wr_addr,
wd_i => d_i,
we_i => wr_cell(i),
ra_i => rd_addr,
rd_o => q_int(g_width*(i+1) -1 downto g_width*i));
end generate gen_mem_cells;
-- Extra memory cell for sideband channel
U_Sideband_Mem : mpm_fifo_mem_cell
generic map (
g_width => g_sideband_width,
g_size => g_size)
port map (
clk_i => clk_wr_i,
wa_i => wr_addr,
wd_i => side_i,
we_i => real_we,
ra_i => rd_addr,
rd_o => side_comb);
U_CTRL : mpm_async_fifo_ctrl
generic map (
g_size => g_size)
port map (
rst_n_a_i => rst_n_a_i,
clk_wr_i => clk_wr_i,
clk_rd_i => clk_rd_i,
rd_i => rd_i,
wr_i => real_we,
wr_addr_o => wr_addr,
rd_addr_o => rd_addr,
going_full_o => full_int,
-- full_o => full_int,
empty_o => empty_o);
-- Per-cell write shift register control
p_write_grow_sreg : process(clk_wr_i, rst_n_a_i)
begin
if rst_n_a_i = '0' then
wr_sreg(0) <= '1';
wr_sreg(wr_sreg'left downto 1) <= (others => '0');
elsif rising_edge(clk_wr_i) then
if(we_i = '1') then
if(align_i = '1') then
wr_sreg(0) <= '1';
wr_sreg(wr_sreg'left downto 1) <= (others => '0');
else
wr_sreg <= wr_sreg(wr_sreg'left-1 downto 0) & wr_sreg(wr_sreg'left);
end if;
end if;
end if;
end process;
real_we <= wr_cell(wr_cell'left) or (we_i and align_i);
-- Output register on q_o. Memory cells are combinatorial, the register is
-- here to improve the timing.
p_output_reg : process(clk_rd_i, rst_n_a_i)
begin
if (rst_n_a_i = '0') then
q_o <= (others => '0');
side_o <= (others => '0');
elsif rising_edge(clk_rd_i) then
if(rd_i = '1') then
q_o <= q_int;
side_o <= side_comb;
end if;
end if;
end process;
-- full flag is only active when there's no space left in the highest memory
-- cell
full_o <= full_int and wr_sreg(wr_sreg'left);
end rtl;
......@@ -4,38 +4,37 @@ use ieee.numeric_std.all;
use work.genram_pkg.all; -- for f_log2_size
entity swc_async_grow_fifo is
entity mpm_async_shrink_fifo is
generic (
g_width : integer := 16;
g_ratio : integer := 6;
g_size : integer := 8;
g_sideband_width : integer := 16);
g_width : integer; -- narrow port width
g_ratio : integer;
g_size : integer;
g_sideband_width : integer);
port (
rst_n_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
we_i : in std_logic;
align_i : in std_logic; -- 1: aligned write
d_i : in std_logic_vector(g_width-1 downto 0);
we_i : in std_logic;
d_i : in std_logic_vector(g_width*g_ratio-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width * g_ratio-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width-1 downto 0);
-- "Sideband" channel (for passing aux data)
side_i : in std_logic_vector(g_sideband_width-1 downto 0);
side_i : in std_logic_vector(g_sideband_width-1 downto 0);
side_o : out std_logic_vector(g_sideband_width-1 downto 0);
flush_i : in std_logic := '0';
full_o : out std_logic;
empty_o : out std_logic);
end swc_async_grow_fifo;
end mpm_async_shrink_fifo;
architecture rtl of swc_async_grow_fifo is
architecture rtl of mpm_async_shrink_fifo is
component swc_fifo_mem_cell
component mpm_fifo_mem_cell
generic (
g_width : integer;
g_size : integer);
......@@ -48,11 +47,11 @@ architecture rtl of swc_async_grow_fifo is
rd_o : out std_logic_vector(g_width-1 downto 0));
end component;
component swc_async_fifo_ctrl
component mpm_async_fifo_ctrl
generic (
g_size : integer);
port (
rst_n_i : in std_logic;
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rd_i : in std_logic;
......@@ -63,76 +62,97 @@ architecture rtl of swc_async_grow_fifo is
empty_o : out std_logic);
end component;
signal wr_sreg : std_logic_vector(g_ratio-1 downto 0);
signal wr_cell : std_logic_vector(g_ratio-1 downto 0);
signal real_we : std_logic;
signal q_int : std_logic_vector(g_width*g_ratio-1 downto 0);
signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal full_int : std_logic;
signal rd_count : unsigned(3 downto 0);
signal real_rd : std_logic;
signal q_muxed : std_logic_vector(g_width-1 downto 0);
signal q_comb, q_reg : std_logic_vector(g_width*g_ratio-1 downto 0);
signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal empty_wide, empty_narrow : std_logic;
signal line_flushed : std_logic;
begin -- rtl
gen_mem_cells : for i in 0 to g_ratio-1 generate
wr_cell(i) <= wr_sreg(i) and we_i;
gen_sb_mem : if(g_sideband_width > 0) generate
U_Sideband_Mem : mpm_fifo_mem_cell
generic map (
g_width => g_sideband_width,
g_size => g_size)
port map (
clk_i => clk_wr_i,
wa_i => wr_addr,
wd_i => side_i,
we_i => we_i,
ra_i => rd_addr,
rd_o => side_o);
end generate gen_sb_mem;
gen_mem_cells : for i in 0 to g_ratio-1 generate
U_Mem : swc_fifo_mem_cell
U_Mem : mpm_fifo_mem_cell
generic map (
g_width => g_width,
g_size => g_size)
port map (
clk_i => clk_wr_i,
wa_i => wr_addr,
wd_i => d_i,
we_i => wr_cell(i),
wd_i => d_i(g_width*(i+1) -1 downto g_width*i),
we_i => we_i,
ra_i => rd_addr,
rd_o => q_int(g_width*(i+1) -1 downto g_width*i));
rd_o => q_comb(g_width*(i+1) -1 downto g_width*i));
end generate gen_mem_cells;
U_CTRL : swc_async_fifo_ctrl
U_CTRL : mpm_async_fifo_ctrl
generic map (
g_size => g_size)
port map (
rst_n_i => rst_n_i,
rst_n_a_i => rst_n_a_i,
clk_wr_i => clk_wr_i,
clk_rd_i => clk_rd_i,
rd_i => rd_i,
wr_i => real_we,
rd_i => real_rd,
wr_i => we_i,
wr_addr_o => wr_addr,
rd_addr_o => rd_addr,
full_o => full_int,
empty_o => empty_o);
full_o => full_o,
empty_o => empty_wide);
p_write_grow_sreg : process(clk_wr_i, rst_n_i)
p_read_mux : process(clk_rd_i, rst_n_a_i)
begin
if rst_n_i = '0' then
wr_sreg(0) <= '1';
wr_sreg(wr_sreg'left downto 1) <= (others => '0');
elsif rising_edge(clk_wr_i) then
if(we_i = '1') then
if(align_i = '1') then
wr_sreg(0) <= '1';
wr_sreg(wr_sreg'left downto 1) <= (others => '0');
else
wr_sreg <= wr_sreg(wr_sreg'left-1 downto 0) & wr_sreg(wr_sreg'left);
end if;
if rst_n_a_i = '0' then
rd_count <= (others => '0');
q_reg <= (others => '0');
line_flushed <= real_rd;
empty_narrow <= '1';
elsif rising_edge(clk_rd_i) then
if(empty_wide = '0') then
empty_narrow <= '0';
elsif(((rd_count = g_ratio-1 and rd_i = '1') or flush_i = '1') and empty_wide = '1') then
empty_narrow <= '1';
end if;
end if;
end process;
real_we <= wr_cell(wr_cell'left);
line_flushed <= real_rd;
p_output_reg : process(clk_rd_i, rst_n_i)
begin
if (rst_n_i = '0') then
q_o <= (others => '0');
elsif rising_edge(clk_rd_i) then
if(rd_i = '1') then
q_o <= q_int;
if(real_rd = '1')then
q_reg <= q_comb;
end if;
if(rd_i = '1' or flush_i = '1') then
if(rd_count = g_ratio-1 or flush_i = '1') then
rd_count <= (others => '0');
else
rd_count <= rd_count + 1;
end if;
q_muxed <= q_reg(((to_integer(rd_count)+1)*g_width)-1 downto to_integer(rd_count)*g_width);
end if;
end if;
end process;
full_o <= full_int and wr_sreg(wr_sreg'left);
real_rd <= '1' when (rd_count = 0) and rd_i = '1' else '0';
q_o <= q_reg(g_width-1 downto 0) when line_flushed = '1' else q_muxed;
empty_o <= empty_narrow;
end rtl;
......@@ -4,7 +4,7 @@ use IEEE.numeric_std.all;
use work.genram_pkg.all;
entity swc_fifo_mem_cell is
entity mpm_fifo_mem_cell is
generic (
g_width : integer;
......@@ -19,9 +19,9 @@ entity swc_fifo_mem_cell is
ra_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
rd_o : out std_logic_vector(g_width-1 downto 0));
end swc_fifo_mem_cell;
end mpm_fifo_mem_cell;
architecture rtl of swc_fifo_mem_cell is
architecture rtl of mpm_fifo_mem_cell is
type t_mem_array is array(0 to g_size-1) of std_logic_vector(g_width-1 downto 0);
signal mem : t_mem_array;
......
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
use work.mpm_private_pkg.all;
entity mpm_pipelined_mux is
generic (
g_width : integer := 16;
g_inputs : integer := 18);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
d_i : in std_logic_vector(g_inputs * g_width-1 downto 0);
q_o : out std_logic_vector(g_width-1 downto 0);
-- select input (one hot encoded)
sel_i : in std_logic_vector(g_inputs-1 downto 0)
);
end mpm_pipelined_mux;
architecture rtl of mpm_pipelined_mux is
type t_generic_slv_array is array (integer range <>, integer range <>) of std_logic;
constant c_first_stage_muxes : integer := (g_inputs+2)/3;
signal first_stage : t_generic_slv_array(0 to c_first_stage_muxes-1, g_width-1 downto 0);
begin -- rtl
-- 1st stage, optimized for 5-input LUTs: mux each 3-input groups or 0
-- if (sel == 11)
gen_1st_stage : for i in 0 to c_first_stage_muxes-1 generate
gen_each_bit : for j in 0 to g_width-1 generate
p_mux_or : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
first_stage(i, j) <= '0';
else
if(sel_i(3*i + 2 downto 3*i) = "001") then
first_stage(i, j) <= d_i(i * 3 * g_width + j);
elsif (sel_i(3*i + 2 downto 3*i) = "010") then
first_stage(i, j) <= d_i(i * 3 * g_width + g_width + j);
elsif (sel_i(3*i + 2 downto 3*i) = "100") then
first_stage(i, j) <= d_i(i * 3 * g_width + 2*g_width + j);
else
first_stage(i, j) <= '0';
end if;
end if;
end if;
end process;
end generate gen_each_bit;
end generate gen_1st_stage;
-- 2nd stage: simply OR together the results of the 1st stage
p_2nd_stage : process(clk_i)
variable row : std_logic_vector(c_first_stage_muxes-1 downto 0);
begin
if rising_edge(clk_i) then
for j in 0 to g_width-1 loop
if rst_n_i = '0' then
q_o(j) <= '0';
else
for i in 0 to c_first_stage_muxes-1 loop
row(i) := first_stage(i, j);
end loop; -- i
if(unsigned(row) = 0) then
q_o(j) <= '0';
else
q_o(j) <= '1';
end if;
end if;
end loop; -- j in 0 to g_width-1 loop
end if;
end process;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
package mpm_private_pkg is
-----------------------------------------------------------------------------
-- Components
-----------------------------------------------------------------------------
component mpm_pipelined_mux
generic (
g_width : integer;
g_inputs : integer);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
d_i : in std_logic_vector(g_inputs * g_width-1 downto 0);
q_o : out std_logic_vector(g_width-1 downto 0);
sel_i : in std_logic_vector(g_inputs-1 downto 0));
end component;
component mpm_async_grow_fifo
generic (
g_width : integer;
g_ratio : integer;
g_size : integer;
g_sideband_width : integer);
port (
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
we_i : in std_logic;
align_i : in std_logic;
d_i : in std_logic_vector(g_width-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width * g_ratio-1 downto 0);
side_i : in std_logic_vector(g_sideband_width-1 downto 0);
side_o : out std_logic_vector(g_sideband_width-1 downto 0);
full_o : out std_logic;
empty_o : out std_logic);
end component;
component mpm_async_shrink_fifo
generic (
g_width : integer;
g_ratio : integer;
g_size : integer;
g_sideband_width : integer);
port (
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
we_i : in std_logic;
d_i : in std_logic_vector(g_width*g_ratio-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width-1 downto 0);
side_i : in std_logic_vector(g_sideband_width-1 downto 0);
side_o : out std_logic_vector(g_sideband_width-1 downto 0);
flush_i : in std_logic := '0';
full_o : out std_logic;
empty_o : out std_logic);
end component;
component mpm_async_fifo
generic (
g_width : integer;
g_size : integer);
port (
rst_n_a_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
we_i : in std_logic;
d_i : in std_logic_vector(g_width-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width-1 downto 0);
full_o : out std_logic;
empty_o : out std_logic);
end component;
function f_slice (
x : std_logic_vector;
index : integer;
len : integer) return std_logic_vector;
end mpm_private_pkg;
package body mpm_private_pkg is
function f_slice (
x : std_logic_vector;
index : integer;
len : integer) return std_logic_vector is
begin
return x((index + 1) * len - 1 downto index * len);
end f_slice;
end mpm_private_pkg;
This diff is collapsed.
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all; -- for f_rr_arbitrate
use work.genram_pkg.all; -- for f_log2_size
use work.mpm_private_pkg.all;
entity mpm_top is
generic (
g_data_width : integer := 18;
g_ratio : integer := 8;
g_page_size : integer := 64;
g_num_pages : integer := 2048;
g_num_ports : integer := 18;
g_fifo_size : integer := 8;
g_page_addr_width : integer := 11;
g_partial_select_width : integer := 1;
g_max_packet_size : integer := 10000
);
port(
-- I/O ports clock (slow)
clk_io_i : in std_logic;
-- Memory/Core clock (fast)
clk_core_i : in std_logic;
rst_n_i : in std_logic;
-- read-write ports I/F (streaming)
wport_d_i : in std_logic_vector (g_num_ports * g_data_width -1 downto 0);
wport_dvalid_i : in std_logic_vector (g_num_ports-1 downto 0);
wport_dlast_i : in std_logic_vector (g_num_ports-1 downto 0);
wport_pg_addr_i : in std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
wport_pg_req_o : out std_logic_vector(g_num_ports -1 downto 0);
wport_dreq_o : out std_logic_vector (g_num_ports-1 downto 0);
rport_d_o : out std_logic_vector (g_num_ports * g_data_width -1 downto 0);
rport_dvalid_o : out std_logic_vector (g_num_ports-1 downto 0);
rport_dlast_o : out std_logic_vector (g_num_ports-1 downto 0);
rport_dsel_o : out std_logic_vector(g_partial_select_width -1 downto 0);
rport_dreq_i : in std_logic_vector (g_num_ports-1 downto 0);
rport_abort_i : in std_logic_vector (g_num_ports-1 downto 0);
rport_pg_addr_i : in std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
rport_pg_valid_i : in std_logic_vector (g_num_ports-1 downto 0);
rport_pg_req_o : out std_logic_vector (g_num_ports-1 downto 0);
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width+1 downto 0)
);
end mpm_top;
architecture rtl of mpm_top is
signal rst_n_core : std_logic;
signal rst_n_io : std_logic;
component mpm_write_path
generic (
g_data_width : integer;
g_ratio : integer;
g_page_size : integer;
g_num_pages : integer;
g_num_ports : integer;
g_fifo_size : integer;
g_page_addr_width : integer;
g_partial_select_width : integer);
port (
clk_io_i : in std_logic;
clk_core_i : in std_logic;
rst_n_io_i : in std_logic;
rst_n_core_i : in std_logic;
wport_d_i : in std_logic_vector (g_num_ports * g_data_width -1 downto 0);
wport_dvalid_i : in std_logic_vector (g_num_ports-1 downto 0);
wport_dlast_i : in std_logic_vector (g_num_ports-1 downto 0);
wport_pg_addr_i : in std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
wport_pg_req_o : out std_logic_vector(g_num_ports -1 downto 0);
wport_dreq_o : out std_logic_vector (g_num_ports-1 downto 0);
fbm_addr_o : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
fbm_data_o : out std_logic_vector(g_ratio * g_data_width -1 downto 0);
fbm_we_o : out std_logic);
end component;
component mpm_read_path
generic (
g_data_width : integer;
g_ratio : integer;
g_page_size : integer;
g_num_pages : integer;
g_num_ports : integer;
g_fifo_size : integer;
g_page_addr_width : integer;
g_partial_select_width : integer;
g_max_packet_size : integer);
port (
clk_io_i : in std_logic;
clk_core_i : in std_logic;
rst_n_i : in std_logic;
rport_d_o : out std_logic_vector (g_num_ports * g_data_width -1 downto 0);
rport_dvalid_o : out std_logic_vector (g_num_ports-1 downto 0);
rport_dlast_o : out std_logic_vector (g_num_ports-1 downto 0);
rport_dsel_o : out std_logic_vector(g_partial_select_width -1 downto 0);
rport_dreq_i : in std_logic_vector (g_num_ports-1 downto 0);
rport_abort_i : in std_logic_vector (g_num_ports-1 downto 0);
rport_pg_addr_i : in std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
rport_pg_req_o : out std_logic_vector(g_num_ports-1 downto 0);
rport_pg_valid_i : in std_logic_vector (g_num_ports-1 downto 0);
ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
ll_data_i : in std_logic_vector(g_page_addr_width+1 downto 0);
fbm_addr_o : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
fbm_data_i : in std_logic_vector(g_ratio * g_data_width -1 downto 0));
end component;
signal fbm_wr_addr, fbm_rd_addr : std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
signal fbm_wr_data, fbm_rd_data : std_logic_vector(g_ratio * g_data_width -1 downto 0);
signal fbm_we : std_logic;
begin -- rtl
-- Reset synchronizer for the core clock domain
U_Sync_Reset_Coreclk : gc_sync_ffs
port map (
clk_i => clk_core_i,
rst_n_i => '1',
data_i => rst_n_i,
synced_o => rst_n_core);
rst_n_io <= rst_n_i;
U_Write_Path : mpm_write_path
generic map (
g_data_width => g_data_width,
g_ratio => g_ratio,
g_page_size => g_page_size,
g_num_pages => g_num_pages,
g_num_ports => g_num_ports,
g_fifo_size => g_fifo_size,
g_page_addr_width => g_page_addr_width,
g_partial_select_width => g_partial_select_width)
port map (
clk_io_i => clk_io_i,
clk_core_i => clk_core_i,
rst_n_io_i => rst_n_io,
rst_n_core_i => rst_n_core,
wport_d_i => wport_d_i,
wport_dvalid_i => wport_dvalid_i,
wport_dlast_i => wport_dlast_i,
wport_pg_addr_i => wport_pg_addr_i,
wport_pg_req_o => wport_pg_req_o,
wport_dreq_o => wport_dreq_o,
fbm_addr_o => fbm_wr_addr,
fbm_data_o => fbm_wr_data,
fbm_we_o => fbm_we);
U_Read_Path : mpm_read_path
generic map (
g_data_width => g_data_width,
g_ratio => g_ratio,
g_page_size => g_page_size,
g_num_pages => g_num_pages,
g_num_ports => g_num_ports,
g_fifo_size => g_fifo_size,
g_page_addr_width => g_page_addr_width,
g_partial_select_width => g_partial_select_width,
g_max_packet_size => g_max_packet_size)
port map (
clk_io_i => clk_io_i,
clk_core_i => clk_core_i,
rst_n_i => rst_n_i,
rport_d_o => rport_d_o,
rport_dvalid_o => rport_dvalid_o,
rport_dlast_o => rport_dlast_o,
rport_dsel_o => rport_dsel_o,
rport_dreq_i => rport_dreq_i,
rport_abort_i => rport_abort_i,
rport_pg_addr_i => rport_pg_addr_i,
rport_pg_req_o => rport_pg_req_o,
rport_pg_valid_i => rport_pg_valid_i,
ll_addr_o => ll_addr_o,
ll_data_i => ll_data_i,
fbm_addr_o => fbm_rd_addr,
fbm_data_i => fbm_rd_data);
-- The memory itself.
U_F_B_Memory : generic_dpram
generic map (
g_data_width => g_data_width * g_ratio,
g_size => g_num_pages * (g_page_size / g_ratio))
port map (
rst_n_i => rst_n_core,
clka_i => clk_core_i,
wea_i => fbm_we,
aa_i => fbm_wr_addr,
da_i => fbm_wr_data,
clkb_i => clk_core_i,
web_i => '0',
ab_i => fbm_rd_addr,
qb_o => fbm_rd_data);
end rtl;
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all; -- for f_log2_size
entity swc_async_grow_fifo is
generic (
g_width : integer;
g_ratio : integer;
g_size : integer);
port (
rst_n_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
we_i : in std_logic;
d_i : in std_logic_vector(g_width-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width * g_ratio-1 downto 0);
wr_full_o : out std_logic;
rd_empty_o : out std_logic);
end swc_async_grow_fifo;
architecture rtl of swc_async_grow_fifo is
component swc_fifo_mem_cell
generic (
g_width : integer;
g_size : integer);
port (
clk_i : in std_logic;
wa_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
wd_i : in std_logic_vector(g_width-1 downto 0);
we_i : in std_logic;
ra_i : in std_logic_vector(f_log2_size(g_size)-1 downto 0);
rd_o : out std_logic_vector(g_width-1 downto 0));
end component;
component swc_async_fifo_ctrl
generic (
g_size : integer);
port (
rst_n_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
rd_i : in std_logic;
wr_i : in std_logic;
wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
full_o : out std_logic;
empty_o : out std_logic);
end component;
signal wr_sreg : std_logic_vector(g_ratio-1 downto 0);
signal wr_cell : std_logic_vector(g_ratio-1 downto 0);
signal real_we : std_logic;
signal q_int : std_logic_vector(g_width*g_ratio-1 downto 0);
signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
begin -- rtl
gen_mem_cells : for i in 0 to g_ratio-1 generate
wr_cell(i) <= we_i and wr_sreg(i);
U_Mem : swc_fifo_mem_cell
generic map (
g_width => g_width * g_ratio,
g_size => g_size)
port map (
clk_i => clk_wr_i,
wa_i => wr_addr,
wd_i => d_i,
we_i => rd_addr,
ra_i => std_logic_vector(rd_ptr),
rd_o => q_int(g_width*(i+1) -1 downto g_width*i));
end generate gen_mem_cells;
p_write_grow_sreg : process(clk_wr_i, rst_n_i)
begin
if rst_n_i = '0' then
wr_sreg(0) <= '1';
wr_sreg(wr_sreg'left downto 1) <= (others => '0');
real_we <= '0';
elsif rising_edge(clk_wr_i) then
if(we_i = '1') then
wr_sreg <= wr_sreg(wr_sreg'left-1 downto 0) & wr_sreg(wr_sreg'left);
if(wr_sreg(wr_sreg'left) = '1' and full_int = '0') then
real_we <= '1';
else
real_we <= '0';
end if;
else
real_we <= '0';
end if;
end if;
end process;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.swc_private_pkg.all;
use work.genram_pkg.all;
entity swc_async_multiport_mem is
generic (
g_ratio : integer;
g_page_size : integer;
g_num_pages : integer;
g_num_ports : integer
);
port(
-- I/O ports clock (slow)
clk_io_i : in std_logic;
-- Memory/Core clock (fast)
clk_core_i : in std_logic;
rst_n_i : in std_logic;
-- read-write ports I/F (streaming)
wport_i : in t_mpm_write_in_array(0 to g_num_ports-1);
wport_o : out t_mpm_write_out_array(0 to g_num_ports-1);
rport_i : in t_mpm_read_in_array(0 to g_num_ports-1);
rport_o : out t_mpm_read_out_array(0 to g_num_ports-1);
-- linked list I/F
ll_addr_o : out std_logic_vector(f_log2_size(g_num_pages)-1 downto 0);
ll_data_o : out std_logic_vector(f_log2_size(g_num_pages)-1 downto 0);
ll_data_i : in std_logic_vector(f_log2_size(g_num_pages)-1 downto 0);
ll_we_o : out std_logic
);
end swc_async_multiport_mem;
architecture rtl of swc_async_multiport_mem is
component swc_async_grow_fifo
generic (
g_width : integer;
g_ratio : integer;
g_size : integer);
port (
rst_n_i : in std_logic;
clk_wr_i : in std_logic;
clk_rd_i : in std_logic;
align_i : in std_logic;
we_i : in std_logic;
d_i : in std_logic_vector(g_width-1 downto 0);
rd_i : in std_logic;
q_o : out std_logic_vector(g_width * g_ratio-1 downto 0);
full_o : out std_logic;
empty_o : out std_logic);
end component;
type t_fifo_slv_array is array(0 to g_num_ports-1) of std_logic_vector(c_data_path_width downto 0);
type t_wport_state is record
cur_page : unsigned(c_page_addr_width-1 downto 0);
cur_offset : unsigned(f_log2_size(g_page_size)-1 downto 0);
cur_valid : std_logic;
next_page : unsigned(c_page_addr_width-1 downto 0);
next_offset : unsigned(f_log2_size(g_page_size)-1 downto 0);
next_valid : std_logic;
fifo_empty : std_logic;
fifo_full : std_logic;
fifo_nempty : std_logic;
fifo_rd : std_logic;
fifo_q : std_logic_vector((c_data_path_width+1) * g_ratio - 1 downto 0);
end record;
type t_wport_state_array is array(0 to g_num_ports-1) of t_wport_state;
signal w_req, w_sel, w_mask : std_logic_vector(f_log2_size(g_num_ports)-1 downto 0);
signal wstate : t_wport_state_array;
procedure f_rr_arbitrate (
signal req : in std_logic_vector;
signal pre_grant : in std_logic_vector;
signal grant : out std_logic_vector)is
variable reqs : std_logic_vector(g_width - 1 downto 0);
variable gnts : std_logic_vector(g_width - 1 downto 0);
variable gnt : std_logic_vector(g_width - 1 downto 0);
variable gntM : std_logic_vector(g_width - 1 downto 0);
variable zeros : std_logic_vector(g_width - 1 downto 0);
begin
zeros := (others => '0');
-- bit twiddling magic :
s_gnt := req and std_logic_vector(unsigned(not req) + 1);
s_reqs := req and not (std_logic_vector(unsigned(pre_grant) - 1) or pre_grant);
s_gnts := reqs and std_logic_vector(unsigned(not reqs)+1);
s_gntM := gnt when reqs = zeros else gnts;
if((req and pre_grant) = s_zeros) then
grant <= gntM;
s_pre_grant <= gntM; -- remember current grant vector, for the next operation
end if;
end f_rr_arbitrate;
begin -- rtl
gen_input_fifos : for i in 0 to g_num_ports-1 generate
U_Input_FIFOx : swc_async_grow_fifo
generic map (
g_width => c_data_path_width + 1,
g_ratio => g_ratio,
g_size => c_mpm_async_fifo_depth)
port map (
rst_n_i => rst_n_i,
clk_wr_i => clk_io_i,
clk_rd_i => clk_core_i,
we_i => wport_i(i).d_valid,
d_i(c_data_path_width-2 downto 0) => wport_i(i).d,
d_i(c_data_path_width-1) => wport_i(i).d_eof,
align_i => wport_i(i).d_eof,
rd_i => wstate(i).fifo_rd,
q_o => wstate(i).fifo_q,
full_o => wstate(i).fifo_full,
empty_o => wstate(i).fifo_empty);
end generate gen_input_fifos;
end rtl;
library ieee;
use ieee.std_logic_1164.all;
package swc_private_pkg is
constant c_data_path_width : integer := 18;
constant c_eof_marker : std_logic_vector(c_data_path_width-1 downto 0) := "11XXXXXXXXXXXXXXXX";
constant c_mpm_async_fifo_depth : integer := 8;
constant c_page_addr_width : integer := 12;
type t_generic_slv_array is array (integer range <>, integer range <>) of std_logic;
type t_mpm_write_in is record
d : std_logic_vector(c_data_path_width-1 downto 0);
d_valid : std_logic;
d_eof : std_logic;
pg_addr : std_logic_vector(c_page_addr_width-1 downto 0);
pg_valid : std_logic;
end record;
type t_mpm_write_out is record
d_req : std_logic;
pg_req : std_logic;
end record;
type t_mpm_write_in_array is array (integer range <>) of t_mpm_write_in;
type t_mpm_write_out_array is array (integer range <>) of t_mpm_write_out;
type t_mpm_read_out is record
d : std_logic_vector(c_data_path_width-1 downto 0);
d_valid : std_logic;
d_eof : std_logic;
pg_req : std_logic;
end record;
type t_mpm_read_in is record
pg_addr : std_logic_vector(c_page_addr_width-1 downto 0);
pg_valid : std_logic;
d_req : std_logic;
end record;
type t_mpm_read_in_array is array (integer range <>) of t_mpm_read_in;
type t_mpm_read_out_array is array (integer range <>) of t_mpm_read_out;
end swc_private_pkg;
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