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

eb2: all the TX path is there

parent 1a7bb42d
Branches
Tags
No related merge requests found
------------------------------------------------------------------------------
-- Title : Etherbone Config Master FIFO
-- Project : Etherbone Core
------------------------------------------------------------------------------
-- File : eb_cfg_fifo.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-04-08
-- Last update: 2013-04-08
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Buffers Config space requests
-------------------------------------------------------------------------------
-- 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_cfg_fifo is
generic(
g_sdb_address : t_wishbone_address);
port(
clk_i : in std_logic;
rstn_i : in std_logic;
errreg_i : in std_logic_vector(63 downto 0);
cfg_i : in t_wishbone_slave_in;
cfg_o : out t_wishbone_slave_out;
fsm_wb_i : in t_wishbone_master_out;
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_cfg_fifo;
architecture rtl of eb_cfg_fifo is
constant c_size : natural := 256;
constant c_depth : natural := f_ceil_log2(c_size);
constant c_pad : std_logic_vector(31 downto 16) := (others => '0');
signal r_mac : std_logic_vector(6*8-1 downto 0);
signal r_ip : std_logic_vector(4*8-1 downto 0);
signal r_port : std_logic_vector(2*8-1 downto 0);
signal s_fsm_adr : std_logic_vector(2 downto 0);
signal s_fifo_adr : std_logic_vector(2 downto 0);
signal s_fifo_empty : std_logic;
signal s_fifo_pop : std_logic;
signal r_cache_empty : std_logic;
signal r_cache_adr : std_logic_vector(2 downto 0);
impure function update(x : std_logic_vector) return std_logic_vector is
alias y : std_logic_vector(x'length-1 downto 0) is x;
variable o : std_logic_vector(x'length-1 downto 0);
begin
for i in (y'length/8)-1 downto 0 loop
if cfg_i.sel(i) = '1' then
o(i*8+7 downto i*8) := cfg_i.dat(i*8+7 downto i*8);
else
o(i*8+7 downto i*8) := y(i*8+7 downto i*8);
end if;
end loop;
return o;
end update;
begin
cfg_o.int <= '0';
cfg_o.err <= '0';
cfg_o.rty <= '0';
cfg_wbs : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_mac <= x"D15EA5EDBEEF";
r_ip <= x"C0A80064";
r_port <= x"EBD0";
cfg_o.ack <= '0';
cfg_o.dat <= (others => '0');
elsif rising_edge(clk_i) then
if cfg_i.cyc = '1' and cfg_i.stb = '1' and cfg_i.we = '1' then
case to_integer(unsigned(cfg_i.adr(4 downto 2))) is
when 0 => null;
when 1 => null;
when 2 => null;
when 3 => null;
when 4 => r_mac(47 downto 32) <= update(r_mac(47 downto 32));
when 5 => r_mac(31 downto 0) <= update(r_mac(31 downto 0));
when 6 => r_ip <= update(r_ip);
when others => r_port <= update(r_port);
end case;
end if;
cfg_o.ack <= cfg_i.cyc and cfg_i.stb;
case to_integer(unsigned(cfg_i.adr(4 downto 2))) is
when 0 => cfg_o.dat <= errreg_i(63 downto 32);
when 1 => cfg_o.dat <= errreg_i(31 downto 0);
when 2 => cfg_o.dat <= (others => '0');
when 3 => cfg_o.dat <= g_sdb_address;
when 4 => cfg_o.dat <= c_pad & r_mac(47 downto 32);
when 5 => cfg_o.dat <= r_mac(31 downto 0);
when 6 => cfg_o.dat <= r_ip;
when others => cfg_o.dat <= c_pad & r_port;
end case;
end if;
end process;
-- Turn writes into address "010" so they result in zeros
s_fsm_adr <= '010' when fsm_wb_i.we='1' else fsm_wb_i.adr(4 downto 2);
fifo : eb_fifo
generic map(
g_data_width => 3,
g_size => c_size)
port map(
clk_i => clk_i,
rs_n_i => rstn_i,
w_full_o => fsm_full_o,
w_push_i => fsm_wb_i.stb,
w_dat_i => s_fsm_adr,
r_empty_o => s_fifo_empty,
r_pop_i => s_fifo_pop,
r_dat_o => s_fifo_adr);
s_fifo_pop <= not s_fifo_empty and (r_cache_empty or mux_pop_i);
cache : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_cache_empty <= '1';
r_cache_adr <= (others => '0');
elsif rising_edge(clk_i) then
if r_cache_empty = '1' or mux_pop_i = '1' then
r_cache_empty <= s_fifo_empty;
r_cache_adr <= s_fifo_adr;
end if;
end if;
end process;
mux_empty_o <= r_cache_empty;
with r_cache_adr select
mux_dat_o <=
errreg_i(63 downto 32) when '000',
errreg_i(31 downto 0) when '001',
x"00000000" when '010',
g_sdb_address when '011',
c_pad & r_mac(47 downto 32) when '100',
r_mac(31 downto 0) when '101',
r_ip when '110',
c_pad & r_port when others;
end rtl;
......@@ -19,6 +19,14 @@
-- 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;
-- 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
......
......@@ -10,80 +10,150 @@ use work.wishbone_pkg.all;
package eb_internals_pkg is
subtype t_tag is std_logic_vector(1 downto 0);
constant c_tag_wb_drop : t_tag := "00";
constant c_tag_wb_copy : t_tag := "01";
constant c_tag_cfg_req : t_tag := "10";
constant c_tag_pass_on : t_tag := "11";
component eb_rx_fsm is
port (
clk_i : in std_logic;
rstn_i : in std_logic;
rx_cyc_i : in std_logic;
rx_stb_i : in std_logic;
rx_dat_i : in std_logic_vector(31 downto 0);
rx_stall_o : out std_logic;
mux_empty_i : in std_logic;
tag_stb_o : out std_logic;
tag_dat_o : out t_tag;
tag_stall_i : in std_logic;
pass_stb_o : out std_logic;
pass_dat_o : out std_logic_vector(31 downto 0);
pass_stall_i : in std_logic;
cfg_o : out t_wishbone_master_out; -- cyc always hi
cfg_stall_i : in std_logic;
wb_o : out t_wishbone_master_out;
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;
subtype t_tag is std_logic_vector(1 downto 0);
constant c_tag_wbm_req : t_tag := "00";
constant c_tag_cfg_req : t_tag := "01";
constant c_tag_pass_on : t_tag := "10";
component eb_rx_fsm is
port (
clk_i : in std_logic;
rstn_i : in std_logic;
rx_cyc_i : in std_logic;
rx_stb_i : in std_logic;
rx_dat_i : in std_logic_vector(31 downto 0);
rx_stall_o : out std_logic;
tx_cyc_o : out std_logic;
mux_empty_i : in std_logic;
tag_stb_o : out std_logic;
tag_dat_o : out t_tag;
tag_stall_i : in std_logic;
pass_stb_o : out std_logic;
pass_dat_o : out std_logic_vector(31 downto 0);
pass_stall_i : in std_logic;
cfg_o : out t_wishbone_master_out; -- cyc always hi
cfg_stall_i : in std_logic;
wbm_o : out t_wishbone_master_out;
wbm_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_i : in 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;
wbm_pop_o : out t_wishbone_master_out;
wbm_dat_i : in std_logic_vector(31 downto 0);
wbm_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;
component 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 component;
component 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 component;
entity eb_cfg_fifo is
generic(
g_sdb_address : t_wishbone_address);
port(
clk_i : in std_logic;
rstn_i : in std_logic;
errreg_i : in std_logic_vector(63 downto 0);
cfg_i : in t_wishbone_slave_in;
cfg_o : out t_wishbone_slave_out;
fsm_wb_i : in t_wishbone_master_out;
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_cfg_fifo;
component eb_wbm_fifo is
port(
clk_i : in std_logic;
rstn_i : in std_logic;
errreg_o : out std_logic_vector(63 downto 0);
busy_o : out std_logic;
wb_stb_o : out std_logic;
wb_adr_o : out t_wishbone_address;
wb_sel_o : out t_wishbone_byte_select;
wb_we_o : out std_logic;
wb_dat_o : out t_wishbone_data;
wb_i : in t_wishbone_master_in;
fsm_wb_i : in t_wishbone_master_out;
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 component;
end package;
......@@ -27,7 +27,6 @@ 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;
......
------------------------------------------------------------------------------
-- Title : Etherbone Slave
-- Project : Etherbone Core
------------------------------------------------------------------------------
-- File : eb_slave.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-04-08
-- Last update: 2013-04-08
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Connect all the components of an Etherbone slave
-------------------------------------------------------------------------------
-- 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_slave
generic(
g_sdb_address : t_wishbone_address);
port(
clk_i : in std_logic; --! System Clk
nRst_i : in std_logic; --! active low sync reset
EB_RX_i : in t_wishbone_slave_in; --! Streaming wishbone(record) sink from RX transport protocol block
EB_RX_o : out t_wishbone_slave_out; --! Streaming WB sink flow control to RX transport protocol block
EB_TX_i : in t_wishbone_master_in; --! Streaming WB src flow control from TX transport protocol block
EB_TX_o : out t_wishbone_master_out; --! Streaming WB src to TX transport protocol block
config_master_i : in t_wishbone_master_in; --! WB V4 interface to WB interconnect/device(s)
config_master_o : out t_wishbone_master_out; --! WB V4 interface to WB interconnect/device(s)
WB_master_i : in t_wishbone_master_in; --! WB V4 interface to WB interconnect/device(s)
WB_master_o : out t_wishbone_master_out); --! WB V4 interface to WB interconnect/device(s)
end eb_slave;
architecture rtl of eb_slave is
signal rstn_i : std_logic;
signal mux_empty : std_logic;
signal errreg : std_logic_vector(63 downto 0);
signal wbm_busy : std_logic;
signal fsm_tag_stb : std_logic;
signal fsm_tag_dat : std_logic_vector(31 downto 0);
signal tag_fsm_stall : std_logic;
signal fsm_pass_stb : std_logic;
signal fsm_pass_dat : std_logic_vector(31 downto 0);
signal pass_fsm_stall : std_logic;
signal fsm_cfg_wb : t_wishbone_master_o;
signal cfg_fsm_stall : std_logic;
signal fsm_wbm_wb : t_wishbone_master_o;
signal wb_fsm_stall : std_logic;
signal mux_tag_pop : std_logic;
signal tag_mux_dat : std_logic_vector(31 downto 0);
signal tag_mux_empty : std_logic;
signal mux_pass_pop : std_logic;
signal pass_mux_dat : std_logic_vector(31 downto 0);
signal pass_mux_empty : std_logic;
signal mux_cfg_pop : std_logic;
signal cfg_mux_dat : std_logic_vector(31 downto 0);
signal cfg_mux_empty : std_logic;
signal mux_wbm_pop : std_logic;
signal wbm_mux_dat : std_logic_vector(31 downto 0);
signal wbm_mux_empty : std_logic;
begin
rstn_i <= nRst_i;
EB_RX_o.ack <= EB_RX_i.cyc and EB_RX_i.stb and not EB_RX_o.stall;
EB_RX_o.err <= '0';
EB_RX_o.rty <= '0';
EB_RX_o.int <= '0';
fsm : eb_rx_fsm
port map(
clk_i => clk_i,
rstn_i => rstn_i,
rx_cyc_i => EB_RX_i.cyc,
rx_stb_i => EB_RX_i.stb,
rx_dat_i => EB_RX_i.dat,
rx_stall_o => EB_RX_o.stall,
tx_cyc_o => tx_cyc,
mux_empty_i => mux_empty,
tag_stb_o => fsm_tag_stb,
tag_dat_o => fsm_tag_dat,
tag_stall_i => tag_fsm_stall,
pass_stb_o => fsm_pass_stb,
pass_dat_o => fsm_pass_dat,
pass_stall_i => pass_fsm_stall,
cfg_wb_o => fsm_cfg_wb,
cfg_stall_i => cfg_fsm_stall,
wbm_wb_o => fsm_wbm_wb,
wbm_stall_i => wbm_fsm_stall);
EB_TX_o.cyc <= tx_cyc;
EB_TX_o.we <= '1';
EB_TX_o.sel <= (others => '1');
EB_TX_o.adr <= (others => '0');
mux : eb_tx_mux
port map (
clk_i => clk_i,
rstn_i => rstn_i,
tag_pop_o => mux_tag_pop,
tag_dat_i => tag_mux_dat,
tag_empty_i => tag_mux_empty,
pass_pop_o => mux_pass_pop,
pass_dat_i => pass_mux_dat,
pass_empty_i => pass_mux_empty,
cfg_pop_o => mux_cfg_pop,
cfg_dat_i => cfg_mux_dat,
cfg_empty_i => cfg_mux_empty,
wbm_pop_o => mux_wb_pop,
wbm_dat_i => wb_mux_dat,
wbm_empty_i => wb_mux_empty,
tx_stb_o => EB_TX_o.stb,
tx_dat_o => EB_TX_o.dat,
tx_stall_i => EB_TX_i.stall);
tag : eb_tag_fifo
port map(
clk_i => clk_i,
rstn_i => rstn_i,
fsm_stb_i => fsm_tag_stb,
fsm_dat_i => fsm_tag_dat,
fsm_full_o => tag_fsm_full,
mux_pop_i => mux_tag_pop,
mux_dat_o => tag_mux_dat,
mux_empty_o => tag_mux_empty);
pass : eb_pass_fifo
port map(
clk_i => clk_i,
rstn_i => rstn_i,
fsm_stb_i => fsm_pass_stb,
fsm_dat_i => fsm_pass_dat,
fsm_full_o => pass_fsm_full,
mux_pop_i => mux_pass_pop,
mux_dat_o => pass_mux_dat,
mux_empty_o => pass_mux_empty);
cfg : eb_cfg_fifo
generic map(
g_sdb_address => g_sdb_address)
port map(
clk_i => clk_i,
rstn_i => rstn_i,
errreg_i => errreg,
cfg_i => config_master_i,
cfg_o => config_master_o,
fsm_wb_i => fsm_cfg_wb,
fsm_full_o => cfg_fsm_full,
mux_pop_i => mux_cfg_pop,
mux_dat_o => cfg_mux_dat,
mux_empty_o => cfg_mux_empty);
WB_master_o.cyc <= fsm_wb.cyc;
wbm : eb_wbm_fifo
port map(
clk_i => clk_i,
rstn_i => rstn_i,
errreg_o => errreg,
busy_o => wbm_busy,
wb_stb_o => WB_master_o.stb,
wb_adr_o => WB_master_o.adr,
wb_sel_o => WB_master_o.sel,
wb_we_o => WB_master_o.we,
wb_dat_o => WB_master_o.dat,
wb_i => WB_master_i,
fsm_wb_i => fsm_wbm_wb,
fsm_full_o => wbm_fsm_wb,
mux_pop_i => mux_wbm_pop,
mux_dat_o => wbm_mux_dat,
mux_empty_o => wbm_mux_empty);
mux_empty <=
not wbm_busy and
wbm_mux_empty and
cfg_mux_empty and
pass_mux_empty and
tag_mux_empty;
end rtl;
......@@ -27,7 +27,6 @@ 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;
......
......@@ -34,19 +34,19 @@ entity eb_tx_mux is
tag_pop_o : out std_logic;
tag_dat_i : in t_tag;
tag_ready_i : in std_logic;
tag_empty_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;
pass_dat_i : in std_logic_vector(31 downto 0);
pass_empty_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;
cfg_empty_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;
wbm_pop_o : out t_wishbone_master_out;
wbm_dat_i : in std_logic_vector(31 downto 0);
wbm_empty_i : in std_logic;
tx_stb_o : out std_logic;
tx_dat_o : out std_logic_vector(31 downto 0);
......@@ -57,7 +57,7 @@ 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_empty : std_logic;
signal s_dat_value : std_logic_vector(31 downto 0);
signal s_tag_pop : std_logic;
signal r_tag_valid : std_logic;
......@@ -69,7 +69,7 @@ begin
s_can_tx <= not r_tx_stb or not tx_stall_i;
tx_stb_o <= r_tx_stb;
tx_out : process(clk_i) is
tx_out : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_tx_stb <= '0';
......@@ -77,40 +77,40 @@ begin
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;
r_tx_stb <= not s_dat_empty 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;
pass_pop_o <= s_can_tx and r_tag_valid and not pass_empty_i and (r_tag_value = c_tag_pass_on);
cfg_pop_o <= s_can_tx and r_tag_valid and not cfg_empty_i and (r_tag_value = c_tag_cfg_req);
wbm_pop_o <= s_can_tx and r_tag_valid and not wbm_empty_i and (r_tag_value = c_tag_wbm_req);
s_tag_pop <= s_can_tx and r_tag_valid and not s_dat_empty;
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;
s_dat_empty <=
cfg_empty_i when c_tag_cfg_req,
pass_empty_i when c_tag_pass_on,
wbm_empty_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;
wbm_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
tag_pop_o <= not tag_empty_i and (s_tag_pop or not r_tag_valid);
tag_in : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_tag_valid <= '0';
r_tag_value <= c_tag_wb_drop;
r_tag_value <= c_tag_pass_on;
elsif rising_edge(clk_i) then
if s_tag_pop = '1' then
r_tag_valid <= tag_ready_i;
r_tag_valid <= not tag_empty_i;
r_tag_value <= tag_dat_i;
end if;
end if;
......
------------------------------------------------------------------------------
-- Title : Etherbone Wishbone Master FIFO
-- Project : Etherbone Core
------------------------------------------------------------------------------
-- File : eb_wbm_fifo.vhd
-- Author : Wesley W. Terpstra
-- Company : GSI
-- Created : 2013-04-08
-- Last update: 2013-04-08
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Buffers Wishbone requests to resulting data
-------------------------------------------------------------------------------
-- 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_wbm_fifo is
port(
clk_i : in std_logic;
rstn_i : in std_logic;
errreg_o : out std_logic_vector(63 downto 0);
busy_o : out std_logic;
wb_stb_o : out std_logic;
wb_adr_o : out t_wishbone_address;
wb_sel_o : out t_wishbone_byte_select;
wb_we_o : out std_logic;
wb_dat_o : out t_wishbone_data;
wb_i : in t_wishbone_master_in;
fsm_wb_i : in t_wishbone_master_out;
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_wbm_fifo;
architecture rtl of eb_pass_fifo is
constant c_size : natural := 256;
constant c_depth : natural := f_ceil_log2(c_size);
signal r_timeout : unsigned(20 downto 0);
signal r_inflight : unsigned(c_depth-1 downto 0);
signal r_full : std_logic;
signal r_errreg : std_logic_vector(63 downto 0);
signal s_wb_i_rdy : std_logic;
signal s_mux_dat : std_logic_vector(31 downto 0);
signal s_mux_we : std_logic;
begin
wb_stb_o <= fsm_wb_i.stb;
wb_adr_o <= fsm_wb_i.adr;
wb_sel_o <= fsm_wb_i.sel;
wb_we_o <= fsm_wb_i.we;
wb_dat_o <= fsm_wb_i.dat;
fsm_full_o <= r_full;
s_wb_i_rdy <= wb_i.ack or wb_i.err or wb_i.rty;
full : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_full <= '0';
elsif rising_edge(clk_i) then
if r_inflight < size-2 then
r_full <= '0';
else
r_full <= '1';
end if;
end if;
end process;
inflight : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_inflight <= (others => '0');
busy_o <= '0';
elsif rising_edge(clk_i) then
if fsm_wb_i.stb = '1' then
busy_o <= '1';
if mux_pop_i = '1' then
r_inflight <= r_inflight;
else
r_inflight <= r_inflight + 1;
end if;
else
if r_inflight = 0 then
busy_o <= '0';
end if;
if mux_pop_i = '1' then
r_inflight <= r_inflight - 1;
else
r_inflight <= r_inflight;
end if;
end if;
end if;
end process;
errreg : process(rstn_i, clk_i) is
begin
if rstn_i = '0' then
r_errreg <= (others => '0');
elsif rising_edge(clk_i) then
if s_wb_i_rdy = '1' then
r_errreg <= r_errreg(r_errreg'left-1 downto 0) & (not wb_i.ack);
end if;
end if;
end process;
datfifo : eb_fifo
generic map(
g_data_width => 32,
g_size => c_size)
port map(
clk_i => clk_i,
rs_n_i => rstn_i,
w_full_o => open,
w_push_i => s_wb_i_rdy,
w_dat_i => wb_i.dat,
r_empty_o => mux_empty_o,
r_pop_i => mux_pop_i,
r_dat_o => s_mux_dat);
reqfifo : eb_fifo
generic map(
g_data_width => 1,
g_size => c_size)
port map(
clk_i => clk_i,
rs_n_i => rstn_i,
w_full_o => open,
w_push_i => fsm_wb_i.stb,
w_dat_i => fsm_wb_i.we,
r_empty_o => open,
r_pop_i => mux_pop_i,
r_dat_o => s_mux_we);
mux_dat_o <= s_mux_dat when s_mux_we='0' else (others => '0');
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