Skip to content
Snippets Groups Projects
Commit 1a7bb42d authored by Wesley W. Terpstra's avatar Wesley W. Terpstra
Browse files

eb2: first few FIFOs and mux

parent 78281e50
Branches
Tags
No related merge requests found
------------------------------------------------------------------------------
-- Title : Etherbone FIFO
-- Project : Etherbone Core
------------------------------------------------------------------------------
-- File : eb_fifo.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-04-08
-- Last update: 2013-04-08
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: A convenience wrapper for FIFOs used in Etherbone
-------------------------------------------------------------------------------
-- Copyright (c) 2013 GSI
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2013-04-08 1.0 terpstra Created
-------------------------------------------------------------------------------
-- r_dat_o is valid when r_empty_o=0
-- w_dat_i is valid when w_push_i =1
-- r_pop_i affects r_empty_o on the next cycle
-- w_push_i affects w_full_o on the next cycle
entity eb_fifo is
generic(
g_width : natural;
g_size : natural);
port(
clk_i : in std_logic;
rstn_i : in std_logic;
w_full_o : out std_logic;
w_push_i : in std_logic;
w_dat_i : in std_logic_vector(g_width-1 downto 0);
r_empty_o : out std_logic;
r_pop_i : in std_logic;
r_dat_o : out std_logic_vector(g_width-1 downto 0));
end eb_fifo;
architecture rtl of eb_fifo is
constant c_depth : natural := f_ceil_log2(g_size);
signal r_idx : unsigned(c_depth downto 0);
signal w_idx : unsigned(c_depth downto 0);
signal r_idx1 : unsigned(c_depth downto 0);
signal w_idx1 : unsigned(c_depth downto 0);
constant c_high : unsigned(c_depth downto 0) := (c_depth => '1', others => '0');
begin
ram : generic_simple_dpram
generic map(
g_data_width => g_width,
g_size => g_size,
g_dual_clock => false)
port map(
rst_n_i => rstn_i,
clka_i => clk_i,
bwea_i => (others => '1'),
wea_i => w_push_i,
aa_i => w_idx(c_depth-1 downto 0),
da_i => w_dat_i,
clkb_i => clk_i,
ab_i => r_idx(c_depth-1 downto 0),
qb_o => r_dat_o);
r_idx1 <= (r_idx+1) when r_pop_i ='1' else r_idx;
w_idx1 <= (w_idx+1) when r_push_i='1' else w_idx;
main : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_idx <= (others => '0');
w_idx <= (others => '0');
w_full_o <= '0';
r_empty_o <= '1';
elsif rising_edge(clk_i) then
r_idx <= r_idx1;
w_idx <= w_idx1;
-- Compare the newest pointers
if (w_idx1 xor c_high) = r_idx1 then
full_o <= '1';
else
full_o <= '0';
end if;
-- Use the OLD write pointer to prevent read-during-write
if w_idx = r_idx1 then
empty_o <= '1';
else
empty_o <= '0';
end if;
end if;
end process;
end rtl;
......@@ -45,4 +45,45 @@ component eb_rx_fsm is
wb_stall_i : in std_logic );
end component;
component eb_fifo is
generic(
g_width : natural;
g_size : natural);
port(
clk_i : in std_logic;
rstn_i : in std_logic;
w_full_o : out std_logic;
w_push_i : in std_logic;
w_dat_i : in std_logic_vector(g_width-1 downto 0);
r_empty_o : out std_logic;
r_pop_i : in std_logic;
r_dat_o : out std_logic_vector(g_width-1 downto 0));
end component;
component eb_tx_mux is
port(
clk_i : in std_logic;
rstn_i : in std_logic;
tag_pop_o : out std_logic;
tag_dat_i : in t_tag;
tag_ready_i : in std_logic;
pass_pop_o : out std_logic;
pass_dat_o : out std_logic_vector(31 downto 0);
pass_ready_i : in std_logic;
cfg_pop_o : out std_logic;
cfg_dat_i : in std_logic_vector(31 downto 0);
cfg_ready_i : in std_logic;
wb_pop_o : out t_wishbone_master_out;
wb_dat_i : in std_logic_vector(31 downto 0);
wb_ready_i : in std_logic;
tx_stb_o : out std_logic;
tx_dat_o : out std_logic_vector(31 downto 0);
tx_stall_i : in std_logic);
end component;
end package;
------------------------------------------------------------------------------
-- Title : Etherbone Pass FIFO
-- Project : Etherbone Core
------------------------------------------------------------------------------
-- File : eb_pass_fifo.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-04-08
-- Last update: 2013-04-08
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Records protocol data that should be put into response
-------------------------------------------------------------------------------
-- Copyright (c) 2013 GSI
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2013-04-08 1.0 terpstra Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.eb_internals_pkg.all;
-- Updates (registered) outputs based on {stb,pop}_i
entity eb_pass_fifo is
port(
clk_i : in std_logic;
rstn_i : in std_logic;
fsm_stb_i : in std_logic;
fsm_dat_i : in std_logic_vector(31 downto 0);
fsm_full_o : out std_logic;
mux_pop_i : in std_logic;
mux_dat_o : out std_logic_vector(31 downto 0);
mux_empty_o : out std_logic);
end eb_pass_fifo;
architecture rtl of eb_pass_fifo is
begin
fifo : eb_fifo
generic map(
g_data_width => 32,
g_size => 1024) -- 4* the length of the other FIFOs
port map(
clk_i => clk_i,
rs_n_i => rstn_i,
w_full_o => fsm_full_o,
w_push_i => fsm_stb_i,
w_dat_i => fsm_dat_i,
r_empty_o => mux_empty_o,
r_pop_i => mux_pop_i,
r_dat_o => mux_dat_o);
end rtl;
------------------------------------------------------------------------------
-- Title : Etherbone Tag FIFO
-- Project : Etherbone Core
------------------------------------------------------------------------------
-- File : eb_tag_fifo.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-04-08
-- Last update: 2013-04-08
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Tracks which channel the MUX should pop next
-------------------------------------------------------------------------------
-- Copyright (c) 2013 GSI
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2013-04-08 1.0 terpstra Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.eb_internals_pkg.all;
-- Updates (registered) outputs based on {stb,pop}_i
entity eb_tag_fifo is
port(
clk_i : in std_logic;
rstn_i : in std_logic;
fsm_stb_i : in std_logic;
fsm_dat_i : in t_tag;
fsm_full_o : out std_logic;
mux_pop_i : in std_logic;
mux_dat_o : out t_tag;
mux_empty_o : out std_logic);
end eb_tag_fifo;
architecture rtl of eb_tag_fifo is
begin
fifo : eb_fifo
generic map(
g_data_width => 2,
g_size => 1024) -- 4* the length of the other FIFOs
port map(
clk_i => clk_i,
rs_n_i => rstn_i,
w_full_o => fsm_full_o,
w_push_i => fsm_stb_i,
w_dat_i => fsm_dat_i,
r_empty_o => mux_empty_o,
r_pop_i => mux_pop_i,
r_dat_o => mux_dat_o);
end rtl;
------------------------------------------------------------------------------
-- Title : Etherbone TX MUX
-- Project : Etherbone Core
------------------------------------------------------------------------------
-- File : eb_tux_mux.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-04-08
-- Last update: 2013-04-08
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Combines output streams into a packet
-------------------------------------------------------------------------------
-- Copyright (c) 2013 GSI
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2013-04-08 1.0 terpstra Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.eb_internals_pkg.all;
entity eb_tx_mux is
port(
clk_i : in std_logic;
rstn_i : in std_logic;
tag_pop_o : out std_logic;
tag_dat_i : in t_tag;
tag_ready_i : in std_logic;
pass_pop_o : out std_logic;
pass_dat_o : out std_logic_vector(31 downto 0);
pass_ready_i : in std_logic;
cfg_pop_o : out std_logic;
cfg_dat_i : in std_logic_vector(31 downto 0);
cfg_ready_i : in std_logic;
wb_pop_o : out t_wishbone_master_out;
wb_dat_i : in std_logic_vector(31 downto 0);
wb_ready_i : in std_logic;
tx_stb_o : out std_logic;
tx_dat_o : out std_logic_vector(31 downto 0);
tx_stall_i : in std_logic);
end eb_tx_mux;
architecture rtl of eb_tx_mux is
signal r_tx_stb : std_logic;
signal s_can_tx : std_logic;
signal s_dat_ready : std_logic;
signal s_dat_value : std_logic_vector(31 downto 0);
signal s_tag_pop : std_logic;
signal r_tag_valid : std_logic;
signal r_tag_value : t_tag;
begin
-- We can write whenever TX is unstalled and/or not full
s_can_tx <= not r_tx_stb or not tx_stall_i;
tx_stb_o <= r_tx_stb;
tx_out : process(clk_i) is
begin
if rstn_i = '0' then
r_tx_stb <= '0';
tx_dat_o <= '0';
elsif rising_edge(clk_i) then
-- Can we push the data?
if s_can_tx then
r_tx_stb <= s_dat_ready and r_tag_valid;
tx_dat_o <= s_dat_value;
end if;
end if;
end process;
-- Pop the queue we fed into TX
pass_pop_o <= s_can_tx and r_tag_valid and pass_ready_i and (r_tag_value = c_tag_pass_on);
cfg_pop_o <= s_can_tx and r_tag_valid and cfg_ready_i and (r_tag_value = c_tag_cfg_req);
wb_pop_o <= s_can_tx and r_tag_valid and wb_ready_i and (r_tag_value = c_tag_wb_drop or r_tag_value = c_tag_wb_copy);
s_tag_pop <= s_can_tx and r_tag_valid and s_dat_ready;
with r_tag_value select
s_dat_ready <=
cfg_ready_i when c_tag_cfg_req,
pass_ready_i when c_tag_pass_on,
wb_ready_i when others;
with r_tag_value select
s_dat_value <=
cfg_dat_i when c_tag_cfg_req,
pass_dat_i when c_tag_pass_on,
wb_dat_i when others;
-- Pop the tag FIFO if the register is empty/emptied
tag_pop_o <= tag_ready_i and (s_tag_pop or not r_tag_valid);
tag_in : process(clk_i) is
begin
if rstn_i = '0' then
r_tag_valid <= '0';
r_tag_value <= c_tag_wb_drop;
elsif rising_edge(clk_i) then
if s_tag_pop = '1' then
r_tag_valid <= tag_ready_i;
r_tag_value <= tag_dat_i;
end if;
end if;
end process;
end rtl;
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