Commit f29715e1 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

Merge branch 'proposed_master'

parents 598a2f6c 3cd0b5c9
general-cores @ 25a24733
Subproject commit 45cf97977fdb5e451491a5a24af408ea6df4858a
Subproject commit 25a2473348137142cf885a5c8d44e0629cb16936
files = ["wr_fabric_pkg.vhd", "xwb_fabric_sink.vhd", "xwb_fabric_source.vhd", "xwrf_mux.vhd" ]
files = ["wr_fabric_pkg.vhd", "xwb_fabric_sink.vhd", "xwb_fabric_source.vhd", "xwrf_mux.vhd", "xwrf_reg.vhd" ]
......@@ -91,6 +91,19 @@ package wr_fabric_pkg is
);
end component;
component xwrf_reg is
generic(
g_adr_width : integer := 2;
g_dat_width : integer :=16);
port(
rst_n_i : in std_logic;
clk_i : in std_logic;
snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out;
src_i : in t_wrf_source_in;
src_o : out t_wrf_source_out);
end component;
end wr_fabric_pkg;
package body wr_fabric_pkg is
......
library ieee;
use ieee.std_logic_1164.all;
use work.wr_fabric_pkg.all;
entity xwrf_reg is
generic(
g_adr_width : integer := 2;
g_dat_width : integer :=16);
port(
rst_n_i : in std_logic;
clk_i : in std_logic;
snk_i : in t_wrf_sink_in;
snk_o : out t_wrf_sink_out;
src_i : in t_wrf_source_in;
src_o : out t_wrf_source_out);
end xwrf_reg;
architecture behav of xwrf_reg is
type t_reg_fsm is (PASS, STALL, FLUSH);
signal state : t_reg_fsm;
signal temp : t_wrf_sink_in;
begin
process(clk_i)
begin
if rising_edge(clk_i) then
snk_o <= src_i;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
state <= PASS;
src_o <= c_dummy_snk_in;
else
case state is
when PASS =>
if (src_i.stall = '0') then
src_o <= snk_i;
else
temp <= snk_i;
state <= STALL;
end if;
when STALL =>
if (src_i.stall = '0') then
src_o <= temp;
state <= FLUSH;
end if;
when FLUSH =>
if (src_i.stall = '0') then
src_o <= snk_i;
state <= PASS;
else
temp <= snk_i;
state <= STALL;
end if;
end case;
end if;
end if;
end process;
end behav;
......@@ -6,7 +6,7 @@
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-02-25
-- Last update: 2013-07-29
-- Last update: 2014-07-15
-- Platform : FPGA-generic
-- Standard : VHDL '93
-------------------------------------------------------------------------------
......@@ -118,7 +118,8 @@ entity dmtd_with_deglitcher is
tag_o : out std_logic_vector(g_counter_bits-1 downto 0);
-- [clk_sys_i] pulse indicates new phase tag on tag_o
tag_stb_p1_o : out std_logic
tag_stb_p1_o : out std_logic;
dbg_clk_d3_o : out std_logic
);
end dmtd_with_deglitcher;
......@@ -132,7 +133,6 @@ architecture rtl of dmtd_with_deglitcher is
signal stab_cntr : unsigned(15 downto 0);
signal free_cntr : unsigned(g_counter_bits-1 downto 0);
signal in_d0, in_d1 : std_logic;
signal s_one : std_logic;
signal clk_in : std_logic;
......@@ -348,6 +348,6 @@ begin -- rtl
pulse_i => new_edge_p,
extended_o => dbg_dmtdout_o);
dbg_clk_d3_o <= clk_i_d3;
end rtl;
......@@ -3,6 +3,7 @@ files = [
"eca_adder.vhd",
"eca_channel.vhd",
"eca_gpio_channel.vhd",
"eca_scubus_channel.vhd",
"eca_offset.vhd",
"eca_pkg.vhd",
"eca_sdp.vhd",
......@@ -13,4 +14,7 @@ files = [
"eca_wb_channel.vhd",
"eca_wb_event.vhd",
"eca_wr_time.vhd",
"wr_eca.vhd"]
"wr_eca.vhd",
"eca_ac_wbm_auto_pkg.vhd",
"eca_ac_wbm_auto.vhd",
"eca_ac_wbm.vhd"]
#ifndef _ECA_AC_WBM_H_
#define _ECA_AC_WBM_H_
//| Address Map ------------------------ slave ----------------------------------------------|
#define SLAVE_STATUS_GET 0x00 // r _0x000000ff , Shows if the device is rdy/busy
#define SLAVE_MAX_MACROS_GET 0x04 // r _0xffffffff , Shows maximum number of macros
#define SLAVE_MAX_SPACE_GET 0x08 // r _0xffffffff , Shows maximum memory space
#define SLAVE_ENABLE_GET 0x0c // rw _0x00000001 , Turns device on/off
#define SLAVE_ENABLE_SET 0x10 // rw _0x00000001 , ""
#define SLAVE_ENABLE_CLR 0x14 // rw _0x00000001 , ""
#define SLAVE_EXEC_OWR 0x18 // wfs _0x000000ff , Executes macro at idx
#define SLAVE_LAST_EXEC_GET 0x1c // r _0x000000ff , Shows idx of last executed macro
#define SLAVE_REC_OWR 0x20 // wfs _0x000000ff , Records macro at idx
#define SLAVE_LAST_REC_GET 0x24 // r _0x000000ff , Shows idx of last recorded macro
#define SLAVE_MACRO_QTY_GET 0x28 // r _0x000000ff , Shows the number of macros in the ram
#define SLAVE_SPACE_LEFT_GET 0x2c // r _0x0000ffff , Shows number of free spaces in the RAM
#define SLAVE_CLEAR_ALL_OWR 0x30 // wsp _0x00000001 , Clears all macros
#define SLAVE_CLEAR_IDX_OWR 0x34 // wfs _0x000000ff , Clears macro at idx
#define SLAVE_REC_FIFO_OWR 0x38 // wf _0xffffffff , Recording fifo. 3 word sequences: #ADR# #VAL# #META#
#endif
This diff is collapsed.
<wbdevice unitname="eca_ac_wbm" author="M. Kreider" version="0.0.1">
<codegen>
<generate language="vhdl" documentation="yes" test="yes"></generate>
<generate language="c" documentation="yes" test="yes"></generate>
<generate language="c++" documentation="yes" test="yes"></generate>
</codegen>
<generics>
</generics>
<slaveinterface name="slave" data="32" type="pipelined" pages="0">
<sdb vendorID="GSI" productID="0x18415778" version="1" date="auto" name="ECA ActChn WBM"></sdb>
<registers>
<reg name="STATUS" read="yes" mask="0xff" comment="Shows if the device is rdy/busy"></reg>
<reg name="MAX_MACROS" read="yes" mask="0xffffffff" comment="Shows maximum number of macros"></reg>
<reg name="MAX_SPACE" read="yes" mask="0xffffffff" comment="Shows maximum memory space"></reg>
<reg name="ENABLE" read="yes" write="yes" access="atomic" mask="0x1" comment="Turns device on/off"></reg>
<reg name="EXEC" write="yes" mask="0xff" weflag="yes" autostall='yes' comment="Executes macro at idx"></reg>
<reg name="LAST_EXEC" read="yes" mask="0xff" comment="Shows idx of last executed macro"></reg>
<reg name="REC" write="yes" mask="0xff" weflag="yes" autostall='yes' comment="Records macro at idx"></reg>
<reg name="LAST_REC" read="yes" mask="0xff" comment="Shows idx of last recorded macro"></reg>
<reg name="MACRO_QTY" read="yes" mask="0xff" comment="Shows the number of macros in the ram"></reg>
<reg name="SPACE_LEFT" read="yes" mask="0xffff" comment="Shows number of free spaces in the RAM"></reg>
<reg name="CLEAR_ALL" write="yes" mask="0x1" autostall='yes' pulse='yes' comment="Clears all macros"></reg>
<reg name="CLEAR_IDX" write="yes" mask="0xff" weflag="yes" autostall='yes' comment="Clears macro at idx"></reg>
<reg name="REC_FIFO" write="yes" mask="0xffffffff" weflag="yes" comment="Recording fifo. 3 word sequences: #ADR# #VAL# #META#"></reg>
</registers>
</slaveinterface>
</wbdevice>
-- File Name : /home/mkreider/hdlprojects/bel_projects/ip_cores/wr-cores/modules/wr_eca/eca_ac_wbm_auto.vhd
-- Design Unit Name : eca_ac_wbm_auto
-- Revision : 0.0.1
-- Author : M. Kreider
-- Created : 08/01/2015
-- ***********************************************************
-- ** WARNING - THIS IS AUTO-GENERATED CODE! DO NOT MODIFY! **
-- ***********************************************************
--
-- If you want to change the interface,
-- modify eca_ac_wbm.xml and re-run 'python wbgenplus.py eca_ac_wbm.xml' !
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
use work.eca_ac_wbm_auto_pkg.all;
entity eca_ac_wbm_auto is
Port(
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
slave_regs_i : in t_slave_regs_i;
slave_regs_o : out t_slave_regs_o;
slave_i : in t_wishbone_slave_in := ('0', '0', x"00000000", x"F", '0', x"00000000");
slave_o : out t_wishbone_slave_out
);
end eca_ac_wbm_auto;
architecture rtl of eca_ac_wbm_auto is
--+******************************************************************************************+
--| ------------------------------------- WB Registers -------------------------------------|
--+******************************************************************************************+
--| WBS Regs ---------------------------- slave ---------------------------------------------|
signal r_slave : t_slave_regs_o;
signal s_slave : t_slave_regs_i;
signal r_slave_out_stall : std_logic;
signal r_slave_out_ack0,
r_slave_out_ack1,
r_slave_out_err0,
r_slave_out_err1 : std_logic;
signal r_slave_out_dat0,
r_slave_out_dat1 : std_logic_vector(31 downto 0);
begin
--+******************************************************************************************+
--| WBS FSM ------------------------------ slave --------------------------------------------|
--+******************************************************************************************+
slave : process(clk_sys_i)
variable v_dat_i : t_wishbone_data;
variable v_dat_o : t_wishbone_data;
variable v_adr : natural;
variable v_page : natural;
variable v_sel : t_wishbone_byte_select;
variable v_we : std_logic;
variable v_en : std_logic;
begin
if rising_edge(clk_sys_i) then
if(rst_n_i = '0') then
r_slave.ENABLE <= (others => '0');
r_slave.EXEC <= (others => '0');
r_slave.EXEC_WE <= '0'; -- pulse
r_slave.REC <= (others => '0');
r_slave.REC_WE <= '0'; -- pulse
r_slave.CLEAR_ALL <= (others => '0');
r_slave.CLEAR_IDX <= (others => '0');
r_slave.CLEAR_IDX_WE <= '0'; -- pulse
r_slave.REC_FIFO <= (others => '0');
r_slave.REC_FIFO_WE <= '0'; -- pulse
r_slave_out_stall <= '0';
r_slave_out_ack0 <= '0';
r_slave_out_err0 <= '0';
r_slave_out_dat0 <= (others => '0');
r_slave_out_ack1 <= '0';
r_slave_out_err1 <= '0';
r_slave_out_dat1 <= (others => '0');
else
-- short names
v_dat_i := slave_i.dat;
v_adr := to_integer(unsigned(slave_i.adr(5 downto 2)) & "00");
v_sel := slave_i.sel;
v_en := slave_i.cyc and slave_i.stb and not (r_slave_out_stall or slave_regs_i.STALL);
v_we := slave_i.we;
--interface outputs
r_slave_out_stall <= '0';
r_slave_out_ack0 <= '0';
r_slave_out_err0 <= '0';
r_slave_out_dat0 <= (others => '0');
r_slave_out_ack1 <= r_slave_out_ack0;
r_slave_out_err1 <= r_slave_out_err0;
r_slave_out_dat1 <= r_slave_out_dat0;
r_slave.EXEC_WE <= '0'; -- EXEC pulse
r_slave.REC_WE <= '0'; -- REC pulse
r_slave.CLEAR_ALL <= (others => '0'); -- CLEAR_ALL pulse
r_slave.CLEAR_IDX_WE <= '0'; -- CLEAR_IDX pulse
r_slave.REC_FIFO_WE <= '0'; -- REC_FIFO pulse
if(v_en = '1') then
r_slave_out_ack0 <= '1';
if(v_we = '1') then
-- WISHBONE WRITE ACTIONS
case v_adr is
when c_slave_ENABLE_SET => r_slave.ENABLE <= f_wb_wr(r_slave.ENABLE, v_dat_i, v_sel, "set"); -- Turns device on/off
when c_slave_ENABLE_CLR => r_slave.ENABLE <= f_wb_wr(r_slave.ENABLE, v_dat_i, v_sel, "clr"); -- ""
when c_slave_EXEC_OWR => r_slave.EXEC <= f_wb_wr(r_slave.EXEC, v_dat_i, v_sel, "owr"); -- Executes macro at idx
r_slave.EXEC_WE <= '1'; -- EXEC write enable
r_slave_out_stall <= '1'; -- EXEC auto stall
when c_slave_REC_OWR => r_slave.REC <= f_wb_wr(r_slave.REC, v_dat_i, v_sel, "owr"); -- Records macro at idx
r_slave.REC_WE <= '1'; -- REC write enable
r_slave_out_stall <= '1'; -- REC auto stall
when c_slave_CLEAR_ALL_OWR => r_slave.CLEAR_ALL <= f_wb_wr(r_slave.CLEAR_ALL, v_dat_i, v_sel, "owr"); -- Clears all macros
r_slave_out_stall <= '1'; -- CLEAR_ALL auto stall
when c_slave_CLEAR_IDX_OWR => r_slave.CLEAR_IDX <= f_wb_wr(r_slave.CLEAR_IDX, v_dat_i, v_sel, "owr"); -- Clears macro at idx
r_slave.CLEAR_IDX_WE <= '1'; -- CLEAR_IDX write enable
r_slave_out_stall <= '1'; -- CLEAR_IDX auto stall
when c_slave_REC_FIFO_OWR => r_slave.REC_FIFO <= f_wb_wr(r_slave.REC_FIFO, v_dat_i, v_sel, "owr"); -- Recording fifo. 3 word sequences: #ADR# #VAL# #META#
r_slave.REC_FIFO_WE <= '1'; -- REC_FIFO write enable
when others => r_slave_out_ack0 <= '0'; r_slave_out_err0 <= '1';
end case;
else
-- WISHBONE READ ACTIONS
case v_adr is
when c_slave_STATUS_GET => r_slave_out_dat0(7 downto 0) <= s_slave.STATUS; -- Shows if the device is rdy/busy
when c_slave_MAX_MACROS_GET => r_slave_out_dat0(31 downto 0) <= s_slave.MAX_MACROS; -- Shows maximum number of macros
when c_slave_MAX_SPACE_GET => r_slave_out_dat0(31 downto 0) <= s_slave.MAX_SPACE; -- Shows maximum memory space
when c_slave_ENABLE_GET => r_slave_out_dat0(0 downto 0) <= r_slave.ENABLE; -- Turns device on/off
when c_slave_LAST_EXEC_GET => r_slave_out_dat0(7 downto 0) <= s_slave.LAST_EXEC; -- Shows idx of last executed macro
when c_slave_LAST_REC_GET => r_slave_out_dat0(7 downto 0) <= s_slave.LAST_REC; -- Shows idx of last recorded macro
when c_slave_MACRO_QTY_GET => r_slave_out_dat0(7 downto 0) <= s_slave.MACRO_QTY; -- Shows the number of macros in the ram
when c_slave_SPACE_LEFT_GET => r_slave_out_dat0(15 downto 0) <= s_slave.SPACE_LEFT; -- Shows number of free spaces in the RAM
when others => r_slave_out_ack0 <= '0'; r_slave_out_err0 <= '1';
end case;
end if; -- v_we
end if; -- v_en
end if; -- rst
end if; -- clk edge
end process;
slave_regs_o <= r_slave;
s_slave <= slave_regs_i;
slave_o.stall <= r_slave_out_stall or slave_regs_i.STALL;
slave_o.dat <= r_slave_out_dat1;
slave_o.ack <= r_slave_out_ack1 and not slave_regs_i.ERR;
slave_o.err <= r_slave_out_err1 or slave_regs_i.ERR;
end rtl;
-- File Name : /home/mkreider/hdlprojects/bel_projects/ip_cores/wr-cores/modules/wr_eca/eca_ac_wbm_auto_pkg.vhd
-- Design Unit Name : eca_ac_wbm_auto
-- Revision : 0.0.1
-- Author : M. Kreider
-- Created : 08/01/2015
-- ***********************************************************
-- ** WARNING - THIS IS AUTO-GENERATED CODE! DO NOT MODIFY! **
-- ***********************************************************
--
-- If you want to change the interface,
-- modify eca_ac_wbm.xml and re-run 'python wbgenplus.py eca_ac_wbm.xml' !
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package eca_ac_wbm_auto_pkg is
--+******************************************************************************************+
--| ------------------------------- WB Slaves - Adress Maps --------------------------------|
--+******************************************************************************************+
--| WBS Adr ------------------------------ slave --------------------------------------------|
constant c_slave_STATUS_GET : natural := 16#00#; -- r 0x000000ff, Shows if the device is rdy/busy
constant c_slave_MAX_MACROS_GET : natural := 16#04#; -- r 0xffffffff, Shows maximum number of macros
constant c_slave_MAX_SPACE_GET : natural := 16#08#; -- r 0xffffffff, Shows maximum memory space
constant c_slave_ENABLE_GET : natural := 16#0c#; -- rw 0x00000001, Turns device on/off
constant c_slave_ENABLE_SET : natural := 16#10#; -- rw 0x00000001, ""
constant c_slave_ENABLE_CLR : natural := 16#14#; -- rw 0x00000001, ""
constant c_slave_EXEC_OWR : natural := 16#18#; -- wfs 0x000000ff, Executes macro at idx
constant c_slave_LAST_EXEC_GET : natural := 16#1c#; -- r 0x000000ff, Shows idx of last executed macro
constant c_slave_REC_OWR : natural := 16#20#; -- wfs 0x000000ff, Records macro at idx
constant c_slave_LAST_REC_GET : natural := 16#24#; -- r 0x000000ff, Shows idx of last recorded macro
constant c_slave_MACRO_QTY_GET : natural := 16#28#; -- r 0x000000ff, Shows the number of macros in the ram
constant c_slave_SPACE_LEFT_GET : natural := 16#2c#; -- r 0x0000ffff, Shows number of free spaces in the RAM
constant c_slave_CLEAR_ALL_OWR : natural := 16#30#; -- wsp 0x00000001, Clears all macros
constant c_slave_CLEAR_IDX_OWR : natural := 16#34#; -- wfs 0x000000ff, Clears macro at idx
constant c_slave_REC_FIFO_OWR : natural := 16#38#; -- wf 0xffffffff, Recording fifo. 3 word sequences: #ADR# #VAL# #META#
--+******************************************************************************************+
--| ------------------------- WB Slaves - Control Register Records -------------------------|
--+******************************************************************************************+
--| WBS Register Record ------------ slave --------------------------------------------------|
type t_slave_regs_o is record
ENABLE : std_logic_vector(0 downto 0); -- Turns device on/off
EXEC : std_logic_vector(7 downto 0); -- Executes macro at idx
EXEC_WE : std_logic; -- WE flag
REC : std_logic_vector(7 downto 0); -- Records macro at idx
REC_WE : std_logic; -- WE flag
CLEAR_ALL : std_logic_vector(0 downto 0); -- Clears all macros
CLEAR_IDX : std_logic_vector(7 downto 0); -- Clears macro at idx
CLEAR_IDX_WE : std_logic; -- WE flag
REC_FIFO : std_logic_vector(31 downto 0); -- Recording fifo. 3 word sequences: #ADR# #VAL# #META#
REC_FIFO_WE : std_logic; -- WE flag
end record t_slave_regs_o;
type t_slave_regs_i is record
STALL : std_logic; -- Stall control for outside entity
ERR : std_logic; -- Error control for outside entity
STATUS : std_logic_vector(7 downto 0); -- Shows if the device is rdy/busy
MAX_MACROS : std_logic_vector(31 downto 0); -- Shows maximum number of macros
MAX_SPACE : std_logic_vector(31 downto 0); -- Shows maximum memory space
LAST_EXEC : std_logic_vector(7 downto 0); -- Shows idx of last executed macro
LAST_REC : std_logic_vector(7 downto 0); -- Shows idx of last recorded macro
MACRO_QTY : std_logic_vector(7 downto 0); -- Shows the number of macros in the ram
SPACE_LEFT : std_logic_vector(15 downto 0); -- Shows number of free spaces in the RAM
end record t_slave_regs_i;
--| Component ---------------------- eca_ac_wbm_auto ----------------------------------------|
component eca_ac_wbm_auto is
Port(
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
slave_regs_i : in t_slave_regs_i;
slave_regs_o : out t_slave_regs_o;
slave_i : in t_wishbone_slave_in := ('0', '0', x"00000000", x"F", '0', x"00000000");
slave_o : out t_wishbone_slave_out
);
end component;
constant c_eca_ac_wbm_slave_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"00",
wbd_endian => c_sdb_endian_big,
wbd_width => x"7", -- 8/16/32-bit port granularity
sdb_component => (
addr_first => x"0000000000000000",
addr_last => x"000000000000003f",
product => (
vendor_id => x"0000000000000651",
device_id => x"18415778",
version => x"00000001",
date => x"20150108",
name => "ECA ACTCHN WBM ")));
end eca_ac_wbm_auto_pkg;
package body eca_ac_wbm_auto_pkg is
end eca_ac_wbm_auto_pkg;
......@@ -27,9 +27,16 @@ use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.eca_ac_wbm_auto_pkg.c_eca_ac_wbm_slave_sdb;
package eca_pkg is
constant c_eca_ac_wbm_slave_sdb : t_sdb_device := work.eca_ac_wbm_auto_pkg.c_eca_ac_wbm_slave_sdb;
constant c_eca_sdb : t_sdb_device := (
abi_class => x"0000", -- undocumented device
abi_ver_major => x"02",
......@@ -235,6 +242,36 @@ package eca_pkg is
gpio_o : out std_logic_vector(15 downto 0));
end component;
-- sends channel_i.tag to the scu bus
component eca_scubus_channel is
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
channel_i : in t_channel;
tag_valid : out std_logic;
tag : out std_logic_vector(31 downto 0));
end component eca_scubus_channel;
-- uses channel tag to replay specified bus ops macro on wishbone master
component eca_ac_wbm
generic(
g_entries : natural := 32;
g_ram_size : natural := 256
);
Port(
clk_ref_i : in std_logic;
rst_ref_n_i : in std_logic;
channel_i : in t_channel;
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
slave_i : in t_wishbone_slave_in := ('0', '0', x"00000000", x"F", '0', x"00000000");
slave_o : out t_wishbone_slave_out;
master_o : out t_wishbone_master_out;
master_i : in t_wishbone_master_in
);
end component;
---------------------- Internals ------------------------
function f_eca_active_high(x : boolean) return std_logic;
......
--! @file eca_gpio_channel.vhd
--! @brief ECA-GPIO Adapter
--! @author Wesley W. Terpstra <w.terpstra@gsi.de>
--! @author Stefan Rauch <s.rauch@gsi.de>
--!
--! Copyright (C) 2013 GSI Helmholtz Centre for Heavy Ion Research GmbH
--!
--! This component takes an action channel and sends the tag to the SCU bus
--!
--------------------------------------------------------------------------------
--! This library 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 3 of the License, or (at your option) any later version.
--!
--! This library 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 library. If not, see <http://www.gnu.org/licenses/>.
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
use work.eca_pkg.all;
entity eca_scubus_channel is
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
channel_i : in t_channel;
tag_valid : out std_logic;
tag : out std_logic_vector(31 downto 0));
end eca_scubus_channel;
architecture rtl of eca_scubus_channel is
-- Out of principle, tell quartus to leave my design alone.
attribute altera_attribute : string;
attribute altera_attribute of rtl : architecture is "-name AUTO_SHIFT_REGISTER_RECOGNITION OFF";
signal s_tag : std_logic_vector(31 downto 0);
signal s_valid : std_logic;
type state_type is (idle, cnt);
signal sm_state : state_type;
begin
tag_valid <= s_valid;
tag <= s_tag;
main : process(clk_i) is
variable v_cnt : unsigned(1 downto 0);
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
s_tag <= (others => '0');
s_valid <= '0';
v_cnt := (others => '0');
else
case sm_state is
when idle =>
s_valid <= '0';
v_cnt := (others => '0');
if channel_i.valid = '1' then
s_tag <= channel_i.tag;
sm_state <= cnt;
end if;
when cnt =>
s_valid <= '1';
if v_cnt = 3 then
sm_state <= idle;
else
v_cnt := v_cnt + 1;
end if;
end case;
end if;
end if;
end process;
end rtl;
......@@ -13,7 +13,11 @@ files = [ "endpoint_private_pkg.vhd",
"ep_rx_oob_insert.vhd",
"ep_rx_early_address_match.vhd",
"ep_clock_alignment_fifo.vhd",
"ep_tx_framer.vhd",
"ep_tx_path.vhd",
"ep_tx_crc_inserter.vhd",
"ep_tx_header_processor.vhd",
"ep_tx_vlan_unit.vhd",
"ep_tx_packet_injection.vhd",
"ep_packet_filter.vhd",
"ep_rx_vlan_unit.vhd",
"ep_ts_counter.vhd",
......@@ -30,6 +34,7 @@ files = [ "endpoint_private_pkg.vhd",
"ep_wishbone_controller.vhd",
"ep_registers_pkg.vhd",
"ep_crc32_pkg.vhd",
"ep_tx_inject_ctrl.vhd",
"endpoint_pkg.vhd",
"wr_endpoint.vhd",
"xwr_endpoint.vhd"
......
......@@ -2,4 +2,4 @@
mkdir -p doc
wbgen2 -D ./doc/wrsw_endpoint.html -C endpoint_regs.h -p ep_registers_pkg.vhd -H record -V ep_wishbone_controller.vhd --cstyle struct --lang vhdl -K ../../sim/endpoint_regs.v ep_wishbone_controller.wb
wbgen2 -D ./doc/wrsw_endpoint_mdio.html -V ep_pcs_tbi_mdio_wb.vhd --cstyle defines --lang vhdl -K ../../sim/endpoint_mdio.v pcs_regs.wb
\ No newline at end of file
wbgen2 -D ./doc/wrsw_endpoint_mdio.html -V ep_pcs_tbi_mdio_wb.vhd --cstyle defines --lang vhdl -K ../../sim/endpoint_mdio.v pcs_regs.wb
This diff is collapsed.
This diff is collapsed.
......@@ -9,7 +9,7 @@ package ep_crc32_pkg is
constant c_CRC32_INIT_VALUE : std_logic_vector(31 downto 0) := x"00000000";
function f_update_crc32_d16(d : std_logic_vector; data_in : std_logic_vector) return std_logic_vector;
function f_update_crc32_d8(d : std_logic_vector; data_in : std_logic_vector) return std_logic_vector;
function f_update_crc32_d8(d : std_logic_vector(31 downto 0); data_in : std_logic_vector(7 downto 0)) return std_logic_vector;
end ep_crc32_pkg;
......@@ -56,8 +56,8 @@ package body ep_crc32_pkg is
end f_update_crc32_d16;
function f_update_crc32_d8(d : std_logic_vector; data_in : std_logic_vector) return std_logic_vector is
variable q : std_logic_vector(d'length-1 downto 0);
function f_update_crc32_d8(d : std_logic_vector(31 downto 0); data_in : std_logic_vector(7 downto 0)) return std_logic_vector is
variable q : std_logic_vector(31 downto 0);
begin
q(7) := not ((not d(31)) xor (not d(25)) xor data_in(7) xor data_in(1));
q(6) := not ((not d(31)) xor (not d(30)) xor (not d(25)) xor (not d(24)) xor data_in(7) xor data_in(6) xor data_in(1) xor data_in(0));
......
......@@ -331,7 +331,8 @@ begin -- behavioral
done_int <= '0';
drop_o <= '0';
pclass_o <= (others => '0');
elsif((stage2 = '1' and insn.fin = '1') or snk_fab_i.error = '1' or snk_fab_i.eof = '1') then
elsif( (stage2 = '1' and insn.fin = '1') or
((snk_fab_i.error = '1' or snk_fab_i.eof = '1') and done_int = '0') ) then
done_int <= '1';
pclass_o <= regs(31 downto 24);
drop_o <= regs(23);
......
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : ep_pcs_tbi_mdio_wb.vhd
-- Author : auto-generated by wbgen2 from pcs_regs.wb
-- Created : Thu Feb 14 10:46:19 2013
-- Created : Thu Aug 1 10:24:16 2013
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE pcs_regs.wb
......
This diff is collapsed.
......@@ -16,8 +16,18 @@ entity ep_rtu_header_extract is
src_fab_o : out t_ep_internal_fabric;
src_dreq_i : in std_logic;
mbuf_is_pause_i : in std_logic;
vlan_class_i : in std_logic_vector(2 downto 0);
vlan_vid_i : in std_logic_vector(11 downto 0);
vlan_tag_done_i : in std_logic;
vlan_is_tagged_i: in std_logic;
rmon_drp_at_rtu_full_o: out std_logic;
rtu_rq_o : out t_ep_internal_rtu_request;
rtu_full_i : in std_logic;
rtu_rq_abort_o : out std_logic;
rtu_rq_valid_o : out std_logic
);
......@@ -27,7 +37,13 @@ architecture rtl of ep_rtu_header_extract is
signal hdr_offset : std_logic_vector(11 downto 0);
signal in_packet : std_logic;
signal in_header : std_logic;
signal rtu_rq_valid_basic : std_logic;
signal rtu_rq_valid_tagged : std_logic;
signal rtu_rq_valid_out : std_logic;
signal rtu_rq_abort : std_logic;
procedure f_extract_rtu(signal q : out std_logic_vector;
signal fab : t_ep_internal_fabric;
signal at_offset : std_logic) is
......@@ -40,7 +56,7 @@ architecture rtl of ep_rtu_header_extract is
begin -- rtl
gen_with_rtu : if(g_with_rtu) generate
p_hdr_offset_sreg : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
......@@ -59,43 +75,76 @@ begin -- rtl
if rst_n_i = '0' then
rtu_rq_o.smac <= (others => '0');
rtu_rq_o.dmac <= (others => '0');
rtu_rq_o.vid <= (others => '0');
rtu_rq_o.has_vid <= '0';
rtu_rq_o.prio <= (others => '0');
rtu_rq_o.has_prio <= '0';
in_packet <= '0';
rtu_rq_valid_basic<= '0';
rmon_drp_at_rtu_full_o <='0';
rtu_rq_abort <= '0';
in_header <= '0';
else
rmon_drp_at_rtu_full_o <='0';
if(snk_fab_i.sof = '1' and rtu_full_i = '0') then
in_packet <= '1';
in_header <= '1';
elsif(snk_fab_i.sof = '1' and rtu_full_i = '1') then
rmon_drp_at_rtu_full_o <='1';
end if;
if(snk_fab_i.eof = '1' or snk_fab_i.error = '1') then
if((snk_fab_i.eof = '1' and snk_fab_i.sof = '0') or -- in case both (sof & eof) are HIGH
snk_fab_i.error = '1') then
in_packet <= '0';
end if;
if(snk_fab_i.error = '1' or rtu_rq_valid_out = '1') then
in_header <= '0';
end if;
f_extract_rtu(rtu_rq_o.dmac(47 downto 32), snk_fab_i, hdr_offset(0));
f_extract_rtu(rtu_rq_o.dmac(31 downto 16), snk_fab_i, hdr_offset(1));
f_extract_rtu(rtu_rq_o.dmac(15 downto 0), snk_fab_i, hdr_offset(2));
f_extract_rtu(rtu_rq_o.smac(47 downto 32), snk_fab_i, hdr_offset(3));
f_extract_rtu(rtu_rq_o.smac(31 downto 16), snk_fab_i, hdr_offset(4));
f_extract_rtu(rtu_rq_o.smac(15 downto 0), snk_fab_i, hdr_offset(5));
if(hdr_offset(5) = '1' and in_packet = '1') then
rtu_rq_valid_o <= '1';
if(snk_fab_i.dvalid = '1' and hdr_offset(6) = '1' and in_packet = '1') then
rtu_rq_valid_basic <='1';
elsif(rtu_rq_valid_out = '1' or -- reset after making request or
snk_fab_i.error = '1') then -- when there is error in the header, so we don't
-- make request for invalid frame which will be dumped
-- in the SWcore (which reads error status).
-- the special case when error occurs when the request
-- is made, we do end with the output of error (below, end of file)
rtu_rq_valid_basic <= '0';
end if;
if(in_packet = '1' and in_header = '0' and -- if we have packet and the header is already processed
snk_fab_i.error = '1' and rtu_rq_abort = '0') then
rtu_rq_abort <= '1';
else
rtu_rq_valid_o <= '0';
rtu_rq_abort <= '0';
end if;
end if;
end if;
end process;
src_fab_o.sof <= snk_fab_i.sof and not rtu_full_i;
rtu_rq_abort_o <= rtu_rq_abort;
src_fab_o.sof <= snk_fab_i.sof and not rtu_full_i; -- null dev
rtu_rq_valid_tagged <= rtu_rq_valid_basic and vlan_tag_done_i;
-- the request is not done for PAUSE frames as they never go outside of Endpoint
-- (they are dropped inside Endpoint)
rtu_rq_valid_out <= (rtu_rq_valid_tagged and (not mbuf_is_pause_i))when (vlan_is_tagged_i = '1') else
(rtu_rq_valid_basic and (not mbuf_is_pause_i));
end generate gen_with_rtu;
gen_without_rtu : if (not g_with_rtu) generate
src_fab_o.sof <= snk_fab_i.sof;
rtu_rq_valid_out <='0';
end generate gen_without_rtu;
snk_dreq_o <= src_dreq_i;
......@@ -107,5 +156,11 @@ begin -- rtl
src_fab_o.data <= snk_fab_i.data;
src_fab_o.addr <= snk_fab_i.addr;
src_fab_o.has_rx_timestamp <= snk_fab_i.has_rx_timestamp;
rtu_rq_o.vid <= vlan_vid_i;
rtu_rq_o.has_vid <= vlan_is_tagged_i;
rtu_rq_o.prio <= vlan_class_i;
rtu_rq_o.has_prio <= vlan_is_tagged_i;
rtu_rq_valid_o <= rtu_rq_valid_out and not snk_fab_i.error;
end rtl;
......@@ -47,7 +47,8 @@ use work.ep_wbgen2_pkg.all;
entity ep_rx_buffer is
generic (
g_size : integer := 1024
g_size : integer := 1024;
g_with_fc : boolean := false
);
port(
clk_sys_i : in std_logic;
......@@ -67,7 +68,7 @@ end ep_rx_buffer;
architecture behavioral of ep_rx_buffer is
constant c_drop_threshold : integer := g_size - 2;
constant c_drop_threshold : integer := g_size - 3;
constant c_release_threshold : integer := g_size * 7 / 8;
type t_write_state is(WAIT_FRAME, DATA);
......@@ -130,14 +131,14 @@ architecture behavioral of ep_rx_buffer is
if(din(17 downto 16) = "10") then -- some fancy encoding is necessary here
case cur_addr(1 downto 0) is
when c_WRF_DATA =>
fab.addr <= c_WRF_OOB after 1ns;
fab.addr <= c_WRF_OOB after 1 ns;
when c_WRF_STATUS =>
fab.addr <= c_WRF_DATA after 1ns;
when others => fab.addr <= c_WRF_DATA after 1ns;
fab.addr <= c_WRF_DATA after 1 ns;
when others => fab.addr <= c_WRF_DATA after 1 ns;
end case;
else
fab.addr <= cur_addr after 1ns;
fab.addr <= cur_addr after 1 ns;
end if;
fab.dvalid <= not din(17) or (din(17) and not din(16));
......@@ -148,7 +149,7 @@ architecture behavioral of ep_rx_buffer is
else
fab.bytesel <= '0';
fab.addr <= cur_addr after 1ns;
fab.addr <= cur_addr after 1 ns;
fab.dvalid <= '0';
fab.sof <= '0';
fab.eof <= '0';
......@@ -162,9 +163,10 @@ architecture behavioral of ep_rx_buffer is
signal q_usedw : std_logic_vector(f_log2_size(g_size)-1 downto 0);
signal q_empty : std_logic;
signal q_reset : std_logic;
signal q_wr, q_rd : std_logic;
signal q_rd : std_logic;
signal q_drop : std_logic;
signal q_in_valid, q_out_valid : std_logic;
signal q_aempty, q_afull : std_logic;
signal state : t_write_state;
......@@ -180,7 +182,6 @@ begin
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
q_wr <= '0';
q_drop <= '0';
state <= WAIT_FRAME;
in_prev_addr <= (others => '0');
......@@ -190,11 +191,9 @@ begin
in_prev_addr <= snk_fab_i.addr;
end if;
if(unsigned(q_usedw) = c_drop_threshold) then
if(q_afull = '1') then
q_drop <= '1';
end if;
if(unsigned(q_usedw) = c_release_threshold) then
elsif(q_aempty = '1') then
q_drop <= '0';
end if;
......@@ -217,7 +216,7 @@ begin
end if;
end process;
p_pack_rbuf : process(state, fab_to_encode, in_prev_addr)
p_pack_rbuf : process(state, fab_to_encode, in_prev_addr, q_in, q_in_valid)
begin
f_pack_rbuf_contents(state, fab_to_encode, in_prev_addr, q_in, q_in_valid);
end process;
......@@ -247,7 +246,11 @@ begin
generic map (
g_data_width => 18,
g_size => g_size,
g_with_count => true)
g_with_almost_empty => true,
g_with_almost_full => true,
g_almost_empty_threshold => c_release_threshold,
g_almost_full_threshold => c_drop_threshold,
g_with_count => g_with_fc)
port map (
rst_n_i => q_reset,
clk_i => clk_sys_i,
......@@ -257,8 +260,8 @@ begin
rd_i => q_rd,
empty_o => q_empty,
full_o => open,
almost_empty_o => open,
almost_full_o => open,
almost_empty_o => q_aempty,
almost_full_o => q_afull,
count_o => q_usedw);
......@@ -283,7 +286,7 @@ begin
end if;
end process;
p_unpack : process(q_out, out_cur_addr, q_out_valid)
p_unpack : process(q_out, out_cur_addr, q_out_valid,src_fab_int)
begin
f_unpack_rbuf_contents(q_out, out_cur_addr, q_out_valid, src_fab_int);
end process;
......@@ -291,6 +294,17 @@ begin
src_fab_o <= src_fab_int;
snk_dreq_o <= '1';
level_o <= q_usedw(q_usedw'left downto q_usedw'left - 7);
GEN_FC: if g_with_fc = true generate
GEN_LEV_BIG : if f_log2_size(g_size)-1 > level_o'left generate
level_o <= q_usedw(q_usedw'left downto q_usedw'left - 7);
end generate;
GEN_LEV_SML : if f_log2_size(g_size)-1 < level_o'left+1 generate
level_o(q_usedw'left downto 0) <= q_usedw;
end generate;
end generate;
GEN_NOFC: if g_with_fc = false generate
level_o <= (others=>'X');
end generate;
end behavioral;
......@@ -36,6 +36,7 @@
library ieee;
use ieee.std_logic_1164.all;
use work.wr_fabric_pkg.all;
entity ep_rx_bypass_queue is
generic(
......@@ -84,7 +85,7 @@ architecture behavioral of ep_rx_bypass_queue is
return '1';
end function;
type t_queue_array is array(0 to g_width-1) of std_logic_vector(g_size-1 downto 0);
type t_queue_array is array(0 to g_size-1) of std_logic_vector(g_width-1 downto 0);
signal q_data : t_queue_array;
signal q_valid : std_logic_vector(g_size-1 downto 0);
......@@ -97,6 +98,8 @@ architecture behavioral of ep_rx_bypass_queue is
signal sreg_enable : std_logic;
signal first_word : std_logic_vector(g_width-1 downto 0);
signal oob_in : std_logic;
begin -- behavioral
qempty <= f_queue_occupation(q_valid, '1');
......@@ -104,21 +107,23 @@ begin -- behavioral
empty_o <= qempty;
gen_sreg : for i in 0 to g_width-1 generate
U_sreg : ep_shift_reg
generic map (
g_size => g_size)
port map (
clk_i => clk_i,
ce_i => sreg_enable,
d_i => d_i(i),
q_o => q_o(i));
end generate gen_sreg;
first_word <= q_data(g_size-1) ;
process(clk_i)
begin
if rising_edge(clk_i) then
if(sreg_enable = '1') then
q_data(g_size-1) <= d_i;
L0: for i in 0 to g_size-2 loop
q_data(i) <= q_data(i+1);
end loop L0;
end if;
end if;
end process;
sreg_enable <= '1' when ((valid_i = '1') or (qempty = '0' and (flushing = '1') and valid_int = '1')) else '0';
q_o <= q_data(g_size-1) when (first_word(17 downto 16) = c_WRF_OOB) else q_data(0);
oob_in <= '1' when (first_word(17 downto 16) = c_WRF_OOB and q_valid(0) = '1') else '0';
sreg_enable <= '1' when ((valid_i = '1') or (qempty = '0' and valid_int = '1')) else '0';
p_queue : process(clk_i)
begin
......@@ -137,15 +142,19 @@ begin -- behavioral
valid_mask <= dreq_i;
if sreg_enable = '1' then
q_valid(0) <= valid_i;
q_valid(q_valid'length-1 downto 1) <= q_valid(q_valid'length-2 downto 0);
q_valid(0) <= valid_i;
if(oob_in = '1' ) then -- flashing CRC
q_valid(q_valid'length-1 downto 1) <=(others => '0');
else
q_valid(q_valid'length-1 downto 1) <= q_valid(q_valid'length-2 downto 0);
end if;
end if;
end if;
end if;
end process;
dreq_o <= dreq_i and not (flush_i or flushing);
valid_int <= (qfull and valid_i) or (not qempty and flushing and valid_mask);
dreq_o <= (dreq_i or not qfull ) and not ((flush_i or flushing) and not qempty);
valid_int <= (qfull and valid_i) or (not qempty and (oob_in or flushing) and valid_mask);
valid_o <= valid_int;
end behavioral;
......@@ -180,6 +189,4 @@ begin -- rtl
end if;
end process;
q_o <= sreg(g_size-1);
end rtl;
......@@ -11,6 +11,9 @@ use work.ep_wbgen2_pkg.all;
-- to filter out pause and HP frames in advance.
entity ep_rx_early_address_match is
generic
(
g_early_hp_detection : boolean := false);
port(
clk_sys_i : in std_logic;
clk_rx_i : in std_logic;
......@@ -23,9 +26,19 @@ entity ep_rx_early_address_match is
match_done_o : out std_logic;
match_is_hp_o : out std_logic;
-- indicate that pause was detected
match_is_pause_o : out std_logic;
-- tell quanta (for prio-based pause it is the greatest of all prios)
match_pause_quanta_o : out std_logic_vector(15 downto 0);
-- mask with priorities which shall be PAUSEd
match_pause_prio_mask_o : out std_logic_vector(7 downto 0);
-- once the PAUSE frame is decoded, it requests pausing from SWcore
match_pause_p_o : out std_logic;
regs_i : in t_ep_out_registers
);
......@@ -33,7 +46,7 @@ end ep_rx_early_address_match;
architecture behavioral of ep_rx_early_address_match is
signal hdr_offset : std_logic_vector(11 downto 0);
signal hdr_offset : std_logic_vector(16 downto 0);
signal at_ethertype : std_logic;
signal at_vid : std_logic;
......@@ -43,6 +56,12 @@ architecture behavioral of ep_rx_early_address_match is
signal comb_pcp_matches_hp : std_logic;
signal done_int : std_logic;
signal pause_prio_mask : std_logic_vector(7 downto 0);
signal match_pause_req : std_logic;
signal match_is_pause : std_logic;
signal is_perprio_pause : std_logic;
signal match_pause_quanta : std_logic_vector(15 downto 0);
function f_compare_slv (a : std_logic_vector; b : std_logic_vector) return std_logic is
begin
if(a = b) then
......@@ -78,8 +97,11 @@ begin -- behavioral
if rising_edge(clk_rx_i) then
if rst_n_rx_i = '0' or snk_fab_i.sof = '1' then
pause_match_int <= (others => '0');
match_pause_quanta_o <= (others => '0');
match_is_pause_o <= '0';
match_pause_quanta <= (others => '0');
match_is_pause <= '0';
pause_prio_mask <= (others => '0');
match_pause_req <= '0';
is_perprio_pause <= '0';
else
if(snk_fab_i.dvalid = '1') then
if(hdr_offset(0) = '1') then
......@@ -91,33 +113,63 @@ begin -- behavioral
if(hdr_offset(2) = '1') then
pause_match_int (2) <= f_compare_slv(snk_fab_i.data, x"0001");
end if;
if(hdr_offset(3) = '1') then
pause_match_int (3) <= f_compare_slv(snk_fab_i.data, regs_i.mach_o);
end if;
if(hdr_offset(4) = '1') then
pause_match_int (4) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(31 downto 16));
end if;
if(hdr_offset(5) = '1') then
pause_match_int (5) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(15 downto 0));
end if;
-- if(hdr_offset(3) = '1') then
-- pause_match_int (3) <= f_compare_slv(snk_fab_i.data, regs_i.mach_o);
-- end if;
-- if(hdr_offset(4) = '1') then
-- pause_match_int (4) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(31 downto 16));
-- end if;
-- if(hdr_offset(5) = '1') then
-- pause_match_int (5) <= f_compare_slv(snk_fab_i.data, regs_i.macl_o(15 downto 0));
-- end if;
if(hdr_offset(6) = '1') then
pause_match_int (6) <= f_compare_slv(snk_fab_i.data, x"8808");
pause_match_int (3) <= f_compare_slv(snk_fab_i.data, x"8808");
end if;
if(hdr_offset(7) = '1') then
pause_match_int (7) <= f_compare_slv(snk_fab_i.data, x"0001");
pause_match_int (4) <= f_compare_slv(snk_fab_i.data, x"0001"); -- 802.3 PAUSE
pause_match_int (5) <= f_compare_slv(snk_fab_i.data, x"0101"); -- 802.1Q PAUSE (per-prio)
end if;
if(hdr_offset(8) = '1') then
match_is_pause_o <= f_compare_slv(pause_match_int, x"ff");
match_pause_quanta_o <= snk_fab_i.data;
if(f_compare_slv(pause_match_int, b"0001_1111") = '1') then -- 802.3 PAUSE
match_is_pause <= '1'; -- to indicate that frame shall be dropped
if(regs_i.fcr_rxpause_o = '1') then
match_pause_req <= '1';
match_pause_quanta <= snk_fab_i.data;
pause_prio_mask <= (others => '1');
end if;
elsif(f_compare_slv(pause_match_int, b"0010_1111") = '1') then -- 802.1Q PAUSE (per-prio)
match_is_pause <= '1'; -- to indicate that frame shall be dropped
if(regs_i.fcr_rxpause_802_1q_o = '1') then
pause_prio_mask <= snk_fab_i.data(7 downto 0);
is_perprio_pause <= '1';
end if;
end if;
end if;
if (is_perprio_pause ='1' and ((hdr_offset(16 downto 9) and pause_prio_mask) /= b"0000_0000")) then
if(snk_fab_i.data > match_pause_quanta) then
match_pause_quanta <= snk_fab_i.data;
end if;
end if;
if(hdr_offset(16) = '1' and is_perprio_pause = '1') then
match_pause_req <= '1';
end if;
end if;
end if;
end if;
end process;
match_is_pause_o <= match_is_pause;
match_pause_prio_mask_o <= pause_prio_mask;
match_pause_quanta_o <= match_pause_quanta;
gen_with_early_hp_det: if(g_early_hp_detection) generate
-- ML: the p_match_hp is not used, instead identification of HP is done in RTU
p_match_hp : process(clk_rx_i)
variable index : integer;
begin
......@@ -143,6 +195,11 @@ begin -- behavioral
end if;
end if;
end process;
end generate gen_with_early_hp_det;
gen_without_early_hp_det: if(not g_early_hp_detection) generate
match_is_hp_o <='0';
end generate gen_without_early_hp_det;
p_gen_done : process(clk_rx_i)
begin
......@@ -166,6 +223,14 @@ begin -- behavioral
data_i => done_int,
ppulse_o => match_done_o);
U_sync_pause : gc_sync_ffs
generic map (
g_sync_edge => "positive")
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_sys_i,
data_i => match_pause_req,
ppulse_o => match_pause_p_o);
end behavioral;
......
This diff is collapsed.
......@@ -99,8 +99,10 @@ entity ep_rx_pcs_16bit is
an_rx_valid_o : out std_logic;
an_idle_match_o : out std_logic;
-- RMON statistic counters
rmon_o : inout t_rmon_triggers
-- RMON events
rmon_rx_overrun : out std_logic;
rmon_rx_inv_code : out std_logic;
rmon_rx_sync_lost : out std_logic
);
end ep_rx_pcs_16bit;
......@@ -440,7 +442,7 @@ begin
rmon_rx_overrun_p_int <= '0';
rmon_invalid_code_p_int <= '0';
timestamp_trigger_p_a_o <= '0';
timestamp_trigger_p_a_o <= '0';
timestamp_pending <= "000";
else -- normal PCS operation
......@@ -725,7 +727,7 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_invalid_code_p_int,
extended_o => rmon_o.rx_invalid_code);
extended_o => rmon_rx_inv_code);
U_ext_rmon_2 : gc_extend_pulse
generic map (
......@@ -734,10 +736,10 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_rx_overrun_p_int,
extended_o => rmon_o.rx_overrun);
extended_o => rmon_rx_overrun);
-- drive the "RX PCS Sync Lost" event counter
rmon_o.rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
rmon_rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
pcs_fab_o.rx_timestamp_valid <= timestamp_valid_i;
......
......@@ -105,8 +105,10 @@ entity ep_rx_pcs_8bit is
an_rx_valid_o : out std_logic;
an_idle_match_o : out std_logic;
-- RMON statistic counters
rmon_o : inout t_rmon_triggers
-- RMON events
rmon_rx_overrun : out std_logic;
rmon_rx_inv_code : out std_logic;
rmon_rx_sync_lost : out std_logic
);
end ep_rx_pcs_8bit;
......@@ -196,7 +198,6 @@ architecture behavioral of ep_rx_pcs_8bit is
-- RMON counter pulses
signal rmon_rx_overrun_p_int : std_logic;
signal rmon_syncloss_p_int : std_logic;
signal rmon_invalid_code_p_int : std_logic;
-- Misc. signals
......@@ -829,7 +830,7 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_invalid_code_p_int,
extended_o => rmon_o.rx_invalid_code);
extended_o => rmon_rx_inv_code);
U_ext_rmon_2 : gc_extend_pulse
generic map (
......@@ -838,10 +839,10 @@ begin
clk_i => phy_rx_clk_i,
rst_n_i => reset_synced_rxclk,
pulse_i => rmon_rx_overrun_p_int,
extended_o => rmon_o.rx_overrun);
extended_o => rmon_rx_overrun);
-- drive the "RX PCS Sync Lost" event counter
rmon_o.rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
rmon_rx_sync_lost <= rx_sync_lost_p and (not mdio_mcr_pdown_i);
end behavioral;
......
......@@ -24,7 +24,7 @@ entity ep_rx_status_reg_insert is
mbuf_is_hp_i : in std_logic;
mbuf_is_pause_i : in std_logic;
rmon_o : out t_rmon_triggers
rmon_pfilter_drop_o : out std_logic
);
end ep_rx_status_reg_insert;
......@@ -58,16 +58,24 @@ begin -- rtl
mbuf_ack_o <= '1' when (mbuf_valid_i = '1' and state = WAIT_MBUF) else '0';
snk_dreq_o <= src_dreq_i and dreq_mask and not snk_fab_i.sof;
-- snk_dreq_o <= src_dreq_i and not snk_fab_i.sof;
p_gen_status : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
rmon_pfilter_drop_o <= '0';
state <= WAIT_FRAME;
dreq_mask <= '1';
sreg.match_class <= (others =>'0');
sreg.is_hp <= '0';
sreg.has_crc <= '0';
sreg.has_smac <= '0';
sreg.error <= '0';
else
case state is
when WAIT_FRAME =>
rmon_pfilter_drop_o <= '0';
if(snk_fab_i.sof = '1') then
state <= WAIT_MBUF;
dreq_mask <= '0';
......@@ -75,11 +83,11 @@ begin -- rtl
when WAIT_MBUF =>
if(mbuf_valid_i = '1') then
rmon_o.rx_pause <= mbuf_is_pause_i;
rmon_o.rx_pfilter_drop <= mbuf_drop_i;
rmon_pfilter_drop_o <= mbuf_drop_i;
if(mbuf_drop_i = '0' and mbuf_is_pause_i = '0') then
state <= GEN_STATUS;
dreq_mask <= '1';
else
state <= WAIT_FRAME;
dreq_mask <= '1';
......@@ -91,12 +99,12 @@ begin -- rtl
sreg.has_smac <= '1';
sreg.error <= '0';
else
rmon_o.rx_pfilter_drop <= '0';
rmon_o.rx_pause <= '0';
rmon_o.rx_path_timing_failure <= '0';
rmon_pfilter_drop_o <= '0';
--rmon_o.rx_path_timing_failure <= '0';
end if;
when GEN_STATUS =>
rmon_pfilter_drop_o <= '0';
if(src_dreq_i = '1') then
state <= WAIT_FRAME;
dreq_mask <= '1';
......
......@@ -23,8 +23,8 @@ entity ep_rx_vlan_unit is
tclass_o : out std_logic_vector(2 downto 0);
vid_o : out std_logic_vector(11 downto 0);
tag_done_o : out std_logic;
is_tagged_o: out std_logic;
rmon_o : inout t_rmon_triggers;
regs_i : in t_ep_out_registers;
regs_o : out t_ep_in_registers
);
......@@ -56,6 +56,7 @@ architecture behavioral of ep_rx_vlan_unit is
signal force_dvalid : std_logic;
signal r_tcar_pcp_map : std_logic_vector(23 downto 0);
signal is_tag_inserted: std_logic;
procedure f_vlan_decision
(tag_type : t_tag_type;
......@@ -137,15 +138,13 @@ architecture behavioral of ep_rx_vlan_unit is
end procedure;
begin -- behavioral
at_ethertype <= hdr_offset(6) and snk_fab_i.dvalid;
at_tpid <= hdr_offset(7) and snk_fab_i.dvalid and is_tagged;
at_vid <= hdr_offset(8) and snk_fab_i.dvalid and is_tagged;
at_tpid <= hdr_offset(6) and snk_fab_i.dvalid and is_tagged;--unused
at_vid <= hdr_offset(7) and snk_fab_i.dvalid and is_tagged;
snk_dreq_o <= src_dreq_i and dreq_mask and not at_ethertype;
snk_dreq_o <= src_dreq_i and dreq_mask;-- and not at_ethertype;
p_decode_tag_type : process(snk_fab_i, is_tagged)
begin
......@@ -170,16 +169,17 @@ begin -- behavioral
if rising_edge(clk_sys_i) then
if rst_n_i = '0' or regs_i.ecr_rx_en_o = '0' then
hdr_offset(hdr_offset'left downto 1) <= (others => '0');
hdr_offset(0) <= '1';
state <= WAIT_FRAME;
dreq_mask <= '0';
hdr_offset(0) <= '1';
state <= WAIT_FRAME;
dreq_mask <= '0';
vid_o <= (others =>'0');
is_tag_inserted <= '0';
is_tagged <= '0';
src_fab_o.eof <= '0';
src_fab_o.error <= '0';
src_fab_o.dvalid <= '0';
else
if(snk_fab_i.error = '1') then
state <= DISCARD_FRAME;
else
......@@ -190,7 +190,9 @@ begin -- behavioral
src_fab_o.eof <= '0';
src_fab_o.error <= '0';
is_tagged <= '0';
is_tag_inserted <= '0';
prio_int <= regs_i.vcr0_prio_val_o;
vid_o <= (others =>'0');
if(snk_fab_i.sof = '1') then
hdr_offset(hdr_offset'left downto 1) <= (others => '0');
......@@ -224,9 +226,9 @@ begin -- behavioral
if(snk_fab_i.data = x"8100") then -- got a 802.1q tagged frame
is_tagged <= '1';
else
if (regs_i.vcr0_qmode_o = c_QMODE_PORT_ACCESS or regs_i.vcr0_qmode_o = c_QMODE_PORT_UNQUALIFIED) then
if (regs_i.vcr0_qmode_o = c_QMODE_PORT_ACCESS) then
prio_int <= regs_i.vcr0_prio_val_o;
is_tag_inserted <= '1';
v_src_fab.dvalid := '0';
v_next_state := INSERT_TAG;
v_dreq_mask := '0';
......@@ -254,7 +256,6 @@ begin -- behavioral
-- or not.
f_vlan_decision(comb_tag_type, regs_i.vcr0_qmode_o, admit, use_pvid, use_fixed_prio);
-- assign the VID
if(admit = '0') then -- oops...
v_next_state := DISCARD_FRAME;
......@@ -264,7 +265,7 @@ begin -- behavioral
v_stored_fab.data(11 downto 0) := regs_i.vcr0_pvid_o;
v_src_fab.data(11 downto 0) := regs_i.vcr0_pvid_o;
end if;
vid_o <= v_src_fab.data(11 downto 0);
-- assign the priority
if(regs_i.vcr0_fix_prio_o = '1' or use_fixed_prio = '1') then
-- Forced priority (or a non-priority tagged frame)? Take the priority
......@@ -280,12 +281,30 @@ begin -- behavioral
hdr_offset <= hdr_offset(hdr_offset'left-1 downto 0) & '0';
end if;
src_fab_o.eof <= v_src_fab.eof;
src_fab_o.dvalid <= v_src_fab.dvalid;
src_fab_o.error <= v_src_fab.error;
src_fab_o.addr <= v_src_fab.addr;
src_fab_o.data <= v_src_fab.data;
src_fab_o.bytesel <= v_src_fab.bytesel;
-- new stuff
if(v_next_state = INSERT_TAG) then
src_fab_o.eof <= '0';
src_fab_o.dvalid <= '1';
src_fab_o.error <= '0';
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= x"8100";
src_fab_o.bytesel <= '0';
else
src_fab_o.eof <= v_src_fab.eof;
src_fab_o.dvalid <= v_src_fab.dvalid;
src_fab_o.error <= v_src_fab.error;
src_fab_o.addr <= v_src_fab.addr;
src_fab_o.data <= v_src_fab.data;
src_fab_o.bytesel <= v_src_fab.bytesel;
end if;
-- old stuff
-- src_fab_o.eof <= v_src_fab.eof;
-- src_fab_o.dvalid <= v_src_fab.dvalid;
-- src_fab_o.error <= v_src_fab.error;
-- src_fab_o.addr <= v_src_fab.addr;
-- src_fab_o.data <= v_src_fab.data;
-- src_fab_o.bytesel <= v_src_fab.bytesel;
dreq_mask <= v_dreq_mask;
stored_fab <= v_stored_fab;
......@@ -323,25 +342,60 @@ begin -- behavioral
if(src_dreq_i = '1') then
-- we are at 7th word from the beginning of the frame, but the sink reception
-- is disabled, so we can insert the original ethertype as the TPID
-- new stuff
if(hdr_offset(7) = '1') then
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= x"8100";
src_fab_o.data <= regs_i.vcr0_prio_val_o & '0' & regs_i.vcr0_pvid_o;
src_fab_o.dvalid <= '1';
vid_o <= regs_i.vcr0_pvid_o; -- use the inserted PVID
dreq_mask <= '0';
stored_fab.bytesel <= snk_fab_i.bytesel;
stored_fab.data <= snk_fab_i.data;
stored_fab.addr <= snk_fab_i.addr;
stored_fab.dvalid <= '1';
end if;
if(hdr_offset(8) = '1') then
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= stored_ethertype;
src_fab_o.dvalid <= '1';
dreq_mask <= '1';
end if;
if(hdr_offset(9) = '1') then
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.data <= regs_i.vcr0_prio_val_o & '0' & regs_i.vcr0_pvid_o;
state <= DATA;
src_fab_o.dvalid <= '1';
src_fab_o.addr <= stored_fab.addr;
src_fab_o.data <= stored_fab.data;
src_fab_o.dvalid <= stored_fab.dvalid;
src_fab_o.bytesel <= stored_fab.bytesel;
dreq_mask <= '1';
state <= DATA;
end if;
-- old stuff
-- if(hdr_offset(7) = '1') then
-- src_fab_o.addr <= c_WRF_DATA;
-- src_fab_o.data <= x"8100";
-- src_fab_o.dvalid <= '1';
-- end if;
--
-- if(hdr_offset(8) = '1') then
-- src_fab_o.addr <= c_WRF_DATA;
-- src_fab_o.data <= regs_i.vcr0_prio_val_o & '0' & regs_i.vcr0_pvid_o;
-- src_fab_o.dvalid <= '1';
-- vid_o <= regs_i.vcr0_pvid_o; -- use the inserted PVID
-- dreq_mask <= '1';
-- end if;
--
-- if(hdr_offset(9) = '1') then
-- src_fab_o.addr <= c_WRF_DATA;
-- src_fab_o.data <= stored_ethertype;
-- src_fab_o.dvalid <= '1';
-- dreq_mask <= '1';
-- state <= DATA;
-- end if;
hdr_offset <= hdr_offset(hdr_offset'left-1 downto 0) & '0';
else
src_fab_o.dvalid <= '0';
......@@ -369,6 +423,7 @@ begin -- behavioral
if(rst_n_i = '0' or regs_i.ecr_rx_en_o = '0' or snk_fab_i.sof = '1')then
tag_done_o <= '0';
tclass_o <= "000";
elsif(hdr_offset(9) = '1') then
-- we're already after the headers, so prio_int is
-- certainly valid
......@@ -382,14 +437,15 @@ begin -- behavioral
when "101" => tclass_o <= r_tcar_pcp_map(17 downto 15);
when "110" => tclass_o <= r_tcar_pcp_map(20 downto 18);
when "111" => tclass_o <= r_tcar_pcp_map(23 downto 21);
when others => tclass_o <= "XXX"; -- packet probably contains porn
when others => tclass_o <= "000";--"XXX"; -- packet probably contains porn
end case;
end if;
end if;
end process;
src_fab_o.sof <= regs_i.ecr_rx_en_o and snk_fab_i.sof;
is_tagged_o <= is_tagged or is_tag_inserted;
end behavioral;
......
......@@ -59,16 +59,21 @@ architecture behavioral of ep_rx_wb_master is
signal tmp_sel : std_logic;
signal tmp_dat : std_logic_vector(15 downto 0);
signal tmp_adr : std_logic_vector(1 downto 0);
signal enter_idle: std_logic;
signal enter_idle: std_logic;
signal sof_reg : std_logic;
begin -- behavioral
gen_cyc_on_stall: if g_cyc_on_stall = true generate
snk_dreq_o <= '1' when ((src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and snk_fab_i.sof = '0' and enter_idle = '0') or state = IDLE) else '0';
snk_dreq_o <= '1' when ((src_wb_i.stall = '0' and state /= FINISH_CYCLE and
state /= THROW_ERROR and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and snk_fab_i.sof = '0' and enter_idle = '0') or state = IDLE) else '0';
end generate;
gen_nocyc_on_stall: if g_cyc_on_stall = false generate
snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and snk_fab_i.sof = '0' and enter_idle = '0') else '0';
-- snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and snk_fab_i.sof = '0' and enter_idle = '0') else '0';
-- snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and snk_fab_i.eof = '0' and snk_fab_i.error = '0' and enter_idle = '0') else '0';
snk_dreq_o <= '1' when (src_wb_i.stall = '0' and state /= FINISH_CYCLE and
state /= THROW_ERROR and snk_fab_i.eof = '0' and snk_fab_i.error = '0') else '0';
end generate;
p_count_acks : process(clk_sys_i)
......@@ -98,6 +103,7 @@ begin -- behavioral
src_out_int.adr <= c_WRF_DATA;
src_out_int.cyc <= '0';
enter_idle <= '1';
sof_reg <= '0';
else
case state is
when IDLE =>
......@@ -105,12 +111,13 @@ begin -- behavioral
src_out_int.adr <= snk_fab_i.addr;
src_out_int.dat <= snk_fab_i.data;
if(snk_fab_i.sof = '1' and src_wb_i.err = '0') then
if((snk_fab_i.sof='1' or sof_reg='1') and src_wb_i.err = '0') then
src_out_int.cyc <= '1';
state <= DATA;
end if;
when DATA =>
sof_reg <= '0';
if(src_wb_i.stall = '0') then
src_out_int.adr <= snk_fab_i.addr;
src_out_int.dat <= snk_fab_i.data;
......@@ -157,9 +164,12 @@ enter_idle <= '1';
end if;
when THROW_ERROR =>
if(snk_fab_i.sof='1') then
sof_reg <= '1';
end if;
if(src_wb_i.err = '1') then
enter_idle <= '1';
state <= IDLE;
enter_idle <= '1';
state <= IDLE;
src_out_int.cyc <= '0';
src_out_int.stb <= '0';
elsif(src_wb_i.stall = '0') then
......@@ -172,6 +182,9 @@ enter_idle <= '1';
when FINISH_CYCLE =>
if(snk_fab_i.sof='1') then
sof_reg <= '1';
end if;
if(src_wb_i.stall = '0') then
src_out_int.stb <= '0';
end if;
......
-------------------------------------------------------------------------------
-- Title : 1000base-X MAC/Endpoint
-- Project : White Rabbit
-------------------------------------------------------------------------------
-- File : ep_tx_crc_inserter.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-CO-HT
-- Created : 2009-06-22
-- Last update: 2012-11-15
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Calculates and embeds the CRC into the transmitted frame.
-------------------------------------------------------------------------------
--
-- Copyright (c) 2009-2012 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.gencores_pkg.all;
use work.wr_fabric_pkg.all;
use work.endpoint_private_pkg.all;
use work.ep_wbgen2_pkg.all;
use work.ep_crc32_pkg.all;
entity ep_tx_crc_inserter is
generic(
g_use_new_crc : boolean := false);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
snk_fab_i : in t_ep_internal_fabric;
snk_dreq_o : out std_logic;
src_fab_o : out t_ep_internal_fabric;
src_dreq_i : in std_logic;
dbg_o : out std_logic_vector(2 downto 0)
);
end ep_tx_crc_inserter;
architecture behavioral of ep_tx_crc_inserter is
type t_state is (IDLE, WAIT_CRC, EMBED_1, EMBED_2, EMBED_3);
-- general signals
signal state : t_state;
-- CRC generator signals
signal crc_gen_reset : std_logic;
signal crc_gen_enable : std_logic;
signal crc_value : std_logic_vector(31 downto 0);
signal odd_length : std_logic;
signal embed_valid, embed_eof : std_logic;
signal stored_msb : std_logic_vector(7 downto 0);
signal in_payload : std_logic;
signal src_dreq_d0 : std_logic;
signal crc_p_value, crc_n_value : std_logic_vector(31 downto 0);
--signal crc_next, crc_new : std_logic_vector(31 downto 0);
begin -- behavioral
dbg_o <= "111" when (state = IDLE) else
"110" when (state = WAIT_CRC) else
"101" when (state = EMBED_1) else
"100" when (state = EMBED_2) else
"011" when (state = EMBED_3) else
"000";
in_payload <= '1' when (state = IDLE or state = WAIT_CRC) else '0';
-- ML: potential optimization (if desperate)
-- in_payload <= '1' when (state = IDLE or state = WAIT_CRC) or (src_dreq_d0 = '1' and odd_length = '0' and state = EMBED_2)) else '0';
crc_gen_reset <= '1' when rst_n_i = '0' or snk_fab_i.sof = '1' else '0';
crc_gen_enable <= '1' when (snk_fab_i.dvalid = '1' and in_payload = '1') else '0';
gen_old_crc: if(g_use_new_crc = false) generate
U_tx_crc_generator : gc_crc_gen
generic map (
g_polynomial => x"04C11DB7",
g_init_value => x"ffffffff",
g_residue => x"38fb2284",
g_data_width => 16,
g_half_width => 8,
g_sync_reset => 1,
g_dual_width => 1,
g_registered_match_output => false,
g_registered_crc_output => true)
port map (
clk_i => clk_sys_i,
rst_i => crc_gen_reset,
en_i => crc_gen_enable,
half_i => snk_fab_i.bytesel,
data_i => snk_fab_i.data,
match_o => open,
crc_o => crc_value);
end generate;
gen_new_crc: if(g_use_new_crc = true) generate
p_check_crc_p: process(clk_sys_i)
begin
if falling_edge(clk_sys_i) then
if(crc_gen_reset = '1')then
crc_n_value <= c_CRC32_INIT_VALUE;
elsif(crc_gen_enable = '1') then
crc_n_value <= f_update_crc32_d8(crc_p_value, snk_fab_i.data(15 downto 8));
end if;
end if;
end process;
p_check_crc_n: process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(crc_gen_reset = '1') then
crc_p_value <= c_CRC32_INIT_VALUE;
elsif(crc_gen_enable = '1' and snk_fab_i.bytesel = '0') then
crc_p_value <= f_update_crc32_d8(crc_n_value, snk_fab_i.data(7 downto 0));
end if;
end if;
end process;
crc_value <= crc_p_value when odd_length = '0' else
crc_n_value;
end generate;
p_delay_dreq: process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
src_dreq_d0 <= src_dreq_i;
end if;
end process;
p_crc_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if(rst_n_i = '0' or snk_fab_i.error = '1') then
state <= IDLE;
embed_eof <= '0';
else
case state is
when IDLE =>
embed_eof <= '0';
odd_length <= '0';
if(snk_fab_i.sof = '1') then
state <= WAIT_CRC;
end if;
when WAIT_CRC =>
if(snk_fab_i.bytesel = '1') then
odd_length <= '1';
stored_msb <= snk_fab_i.data(15 downto 8);
end if;
if(snk_fab_i.eof = '1' or snk_fab_i.addr = c_WRF_OOB) then
state <= EMBED_1;
end if;
when EMBED_1 =>
if(src_dreq_d0 = '1') then
state <= EMBED_2;
end if;
when EMBED_2 =>
if(src_dreq_d0 = '1') then
if(odd_length = '1') then
state <= EMBED_3;
else
state <= IDLE;
embed_eof <= '1';
end if;
end if;
when EMBED_3 =>
if(src_dreq_d0 = '1') then
state <= IDLE;
embed_eof <= '1';
end if;
end case;
end if;
end if;
end process;
p_drive_data_addr : process(state, crc_value, odd_length, stored_msb, snk_fab_i, src_dreq_d0)
begin
case state is
when EMBED_1 =>
if(odd_length = '1') then
src_fab_o.data <= stored_msb & crc_value(31 downto 24);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '0';
else
src_fab_o.data <= crc_value(31 downto 16);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '0';
end if;
when EMBED_2 =>
if(odd_length = '1') then
src_fab_o.data <= crc_value(23 downto 8);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '0';
else
src_fab_o.data <= crc_value(15 downto 0);
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '1';
end if;
when EMBED_3 =>
src_fab_o.data <= crc_value(7 downto 0) & "XXXXXXXX";
src_fab_o.addr <= c_WRF_DATA;
src_fab_o.bytesel <= '1';
src_fab_o.dvalid <= src_dreq_d0;
src_fab_o.eof <= '1';
when others =>
src_fab_o.data <= snk_fab_i.data;
src_fab_o.addr <= snk_fab_i.addr;
src_fab_o.bytesel <= '0';
src_fab_o.dvalid <= snk_fab_i.dvalid and not snk_fab_i.bytesel;
src_fab_o.eof <= '0';
end case;
src_fab_o.addr <= c_WRF_DATA;
end process;
snk_dreq_o <= src_dreq_i and in_payload;
src_fab_o.sof <= snk_fab_i.sof;
src_fab_o.error <= snk_fab_i.error;
end behavioral;
......@@ -113,6 +113,7 @@ entity ep_tx_framer is
-- Control registers
-------------------------------------------------------------------------------
ep_ctrl_i : in std_logic;
regs_i : in t_ep_out_registers
);
......@@ -172,8 +173,8 @@ architecture behavioral of ep_tx_framer is
signal stall_int : std_logic;
signal stall_int_d0 : std_logic;
signal untagging : std_logic;
signal got_error : std_logic;
signal got_error : std_logic;
signal tx_en : std_logic;
function b2s (x : boolean)
return std_logic is
......@@ -299,8 +300,7 @@ begin -- behavioral
error_p1 <= snk_valid and b2s(snk_i.adr = c_WRF_STATUS) and decoded_status.error;
abort_now <= '1' when (state /= TXF_IDLE and state /= TXF_GAP) and (regs_i.ecr_tx_en_o = '0' or error_p1 = '1') else '0';
abort_now <= '1' when (state /= TXF_IDLE and state /= TXF_GAP) and (tx_en = '0' or error_p1 = '1') else '0';
p_store_status : process(clk_sys_i)
begin
......@@ -419,7 +419,7 @@ begin -- behavioral
-- Check start-of-frame and send-pause signals and eventually
-- commence frame transmission
if(pcs_dreq_i = '1' and (sof_p1 = '1' or fc_pause_p_i = '1') and regs_i.ecr_tx_en_o = '1') then
if(pcs_dreq_i = '1' and (sof_p1 = '1' or fc_pause_p_i = '1') and tx_en = '1') then
-- enable writing to PCS FIFO
q_sof <= '1';
write_mask <= '1';
......@@ -741,8 +741,9 @@ begin -- behavioral
end if;
end process;
stall_int <= (not (pcs_dreq_i and tx_ready) and regs_i.ecr_tx_en_o) or (snk_i.cyc xor snk_cyc_d0); -- /dev/null if disabled
tx_en <= regs_i.ecr_tx_en_o and ep_ctrl_i;
stall_int <= (not (pcs_dreq_i and tx_ready) and tx_en) or (snk_i.cyc xor snk_cyc_d0); -- /dev/null if disabled
snk_out.stall <= stall_int;
......
-------------------------------------------------------------------------------
-- Title : Controller of
-- Project : White Rabbit MAC/Endpoint
-------------------------------------------------------------------------------
-- File : ep_tx_inject_ctrl.vhd
-- Author : Maciej Lipinski
-- Company : CERN BE-CO-HT
-- Created : 2014-01-16
-- Last update: 2014-01-16
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: this module enables to control HW packet injection in order
-- to turn the Endpoint into simple traffic generator for testing purposes
-------------------------------------------------------------------------------
--
-- Copyright (c) 2014 CERN / BE-CO-HT
--
-- This source file is free software; you can redistribute it
-- and/or modify it under the terms of the GNU Lesser General
-- Public License as published by the Free Software Foundation;
-- either version 2.1 of the License, or (at your option) any
-- later version.
--
-- This source is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-- PURPOSE. See the GNU Lesser General Public License for more
-- details.
--
-- You should have received a copy of the GNU Lesser General
-- Public License along with this source; if not, download it
-- from http://www.gnu.org/licenses/lgpl-2.1.html
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wr_fabric_pkg.all;
use work.endpoint_private_pkg.all;
use work.ep_wbgen2_pkg.all;
entity ep_tx_inject_ctrl is
generic(
g_min_if_gap_length : integer
);
port (
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
snk_fab_i : in t_ep_internal_fabric;
snk_dreq_o : out std_logic;
src_fab_o : out t_ep_internal_fabric;
src_dreq_i : in std_logic;
inject_req_o : out std_logic;
inject_ready_i : in std_logic;
inject_packet_sel_o : out std_logic_vector(2 downto 0);
inject_user_value_o : out std_logic_vector(15 downto 0);
inject_ctr_ena_o : out std_logic;
inject_ctr_mode_o : out std_logic_vector(1 downto 0);
regs_i : in t_ep_out_registers;
regs_o : out t_ep_in_registers
);
end ep_tx_inject_ctrl;
architecture rtl of ep_tx_inject_ctrl is
-- there a lag between setting inject_req and SOF, this nees to be included
constant if_gap_offset : unsigned(15 downto 0) := x"0000"; -- unused
constant src_fab_null : t_ep_internal_fabric := (
sof => '0',
eof => '0',
error => '0',
dvalid => '0',
bytesel => '0',
has_rx_timestamp => '0',
rx_timestamp_valid => '0',
data => (others => '0'),
addr => (others => '0'));
type t_state is (IDLE, INJECT_REQ, INJECT, IFG, END_GEN);
-- Wishbone settings
signal if_gap_value : unsigned(15 downto 0);
signal pck_sel : std_logic_vector(2 downto 0);
signal gen_ena : std_logic;
signal inj_mode : std_logic_vector(1 downto 0);
signal if_gap_cnt : unsigned(15 downto 0);
signal frame_id_cnt : unsigned(15 downto 0);
signal within_packet : std_logic;
signal state : t_state;
-- translation betwen if_gap_value and real IFG:
-- | ----------------------------------------- |
-- | if_gap_value | gap in words | gap in time |
-- | 0 | 7 | 112 ns | disallowed
-- | ......................................... |
-- | 5 | 12 | 192 ns | minimal leagal
-- | 6 | 13 | 208 ns |
-- | ......................................... |
-- | 65536 | 65546 | 1.048ms | maximum allowed due to register size (16 bits)
-- | ----------------------------------------- |
begin -- rtl
p_detect_within : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
within_packet <= '0';
else
if(snk_fab_i.sof = '1')then
within_packet <= '1';
elsif(snk_fab_i.eof = '1' or snk_fab_i.error = '1') then
within_packet <= '0';
end if;
end if;
end if;
end process;
p_config_reg: process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
if_gap_value <= (others=>'0');
pck_sel <= (others=>'0');
gen_ena <= '0';
inj_mode <= (others=>'0');
else
if(regs_i.inj_ctrl_pic_ena_load_o = '1') then -- writing the register
if (regs_i.inj_ctrl_pic_conf_valid_o = '1') then
if_gap_value <= unsigned(regs_i.inj_ctrl_pic_conf_ifg_o);
pck_sel <= regs_i.inj_ctrl_pic_conf_sel_o;
end if;
if(regs_i.inj_ctrl_pic_mode_valid_o = '1') then
inj_mode <= regs_i.inj_ctrl_pic_mode_id_o(1 downto 0);
end if;
gen_ena <= regs_i.inj_ctrl_pic_ena_o;
end if;
end if;
end if;
end process;
p_ctrl_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
state <= IDLE;
inject_req_o <= '0';
if_gap_cnt <= (others => '0');
frame_id_cnt <= (others => '0');
else
case state is
when IDLE =>
-- start when
-- 1) inject enabled, and
-- 2) no packet being received from SWcore and
-- 3) no packet being just started (otherwise, we could have two SOFs
if(gen_ena = '1' and within_packet = '0' and snk_fab_i.sof = '0') then
inject_req_o <= '1';
if_gap_cnt <= if_gap_offset;
frame_id_cnt <= (others => '0');
state <= INJECT_REQ;
end if;
when INJECT_REQ =>
inject_req_o <= '0';
state <= INJECT;
when INJECT =>
if(inject_ready_i = '1') then
frame_id_cnt <= frame_id_cnt + 1;
state <= IFG;
end if;
when IFG =>
if(gen_ena = '0' ) then --gen disabled
if_gap_cnt <= (others => '0');
frame_id_cnt <= (others => '0');
if(within_packet = '0') then -- if there is no frame being currently dumped
state <= IDLE; -- go to idle state
else -- if there is a frame being dumped,
state <= END_GEN; -- wait until it finishes
end if;
elsif(if_gap_cnt < if_gap_value) then
if_gap_cnt <= if_gap_cnt + 1;
else
inject_req_o <= '1';
if_gap_cnt <= if_gap_offset;
state <= INJECT_REQ;
end if;
when END_GEN =>
if(within_packet = '0') then -- now we can gracefully come back to normal functing
state <= IDLE;
end if;
when others =>
state <= IDLE;
if_gap_cnt <= (others => '0');
frame_id_cnt <= (others => '0');
end case;
end if;
end if;
end process;
inject_user_value_o <= std_logic_vector(frame_id_cnt);
inject_packet_sel_o <= pck_sel;
inject_ctr_ena_o <= gen_ena;
inject_ctr_mode_o <= inj_mode;
snk_dreq_o <= src_dreq_i when (state = IDLE) else '1'; -- dev/null if gen
src_fab_o <= snk_fab_i when (state = IDLE) else src_fab_null;-- dev/null if gen
regs_o.inj_ctrl_pic_conf_ifg_i <= std_logic_vector(if_gap_value);
regs_o.inj_ctrl_pic_conf_sel_i <= pck_sel;
regs_o.inj_ctrl_pic_conf_valid_i <= '0';
regs_o.inj_ctrl_pic_ena_i <= gen_ena;
regs_o.inj_ctrl_pic_mode_id_i <= '0' & inj_mode;
end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -103,8 +103,8 @@ entity ep_tx_pcs_8bit is
-- Timestamp strobe
timestamp_trigger_p_a_o : out std_logic;
-- RMON counters
rmon_o : inout t_rmon_triggers;
-- RMON events
rmon_tx_underrun : out std_logic;
-------------------------------------------------------------------------------
-- PHY Interface
......@@ -260,18 +260,18 @@ begin
-- The PCS is reset or disabled
if(reset_synced_txclk = '0' or mdio_mcr_pdown_synced = '1') then
tx_state <= TX_COMMA;
timestamp_trigger_p_a_o <= '0';
fifo_rd <= '0';
tx_error <= '0';
tx_odata_reg <= (others => '0');
tx_is_k <= '0';
tx_cr_alternate <= '0';
tx_catch_disparity <= '0';
tx_cntr <= (others => '0');
tx_odd_length <= '0';
tx_rdreq_toggle <= '0';
rmon_o.tx_underrun <= '0';
tx_state <= TX_COMMA;
timestamp_trigger_p_a_o <= '0';
fifo_rd <= '0';
tx_error <= '0';
tx_odata_reg <= (others => '0');
tx_is_k <= '0';
tx_cr_alternate <= '0';
tx_catch_disparity <= '0';
tx_cntr <= (others => '0');
tx_odd_length <= '0';
tx_rdreq_toggle <= '0';
rmon_tx_underrun <= '0';
else
......@@ -294,8 +294,8 @@ begin
-- clear the RMON/error pulse after 2 cycles (DATA->COMMA->IDLE) to
-- make sure is't long enough to trigger the event counter
rmon_o.tx_underrun <= '0';
tx_error <= '0';
rmon_tx_underrun <= '0';
tx_error <= '0';
-- endpoint wants to send Config_Reg
if(an_tx_en_synced = '1') then
......@@ -403,8 +403,8 @@ begin
tx_odata_reg <= c_preamble_char;
if (tx_cntr = "0000") then
tx_state <= TX_SFD;
tx_rdreq_toggle <= '1';
tx_state <= TX_SFD;
tx_rdreq_toggle <= '1';
end if;
tx_cntr <= tx_cntr - 1;
......@@ -415,9 +415,9 @@ begin
-------------------------------------------------------------------------------
when TX_SFD =>
tx_odata_reg <= c_preamble_sfd;
tx_rdreq_toggle <= '1';
tx_state <= TX_DATA;
tx_odata_reg <= c_preamble_sfd;
tx_rdreq_toggle <= '1';
tx_state <= TX_DATA;
timestamp_trigger_p_a_o <= '1';
when TX_DATA =>
......@@ -430,11 +430,11 @@ begin
if((fifo_empty = '1' or fifo_fab.error = '1') and fifo_fab.eof = '0') then --
-- FIFO underrun?
tx_odata_reg <= c_k30_7; -- emit error propagation code
tx_is_k <= '1';
tx_state <= TX_GEN_ERROR;
tx_error <= not fifo_fab.error;
rmon_o.tx_underrun <= '1';
tx_odata_reg <= c_k30_7; -- emit error propagation code
tx_is_k <= '1';
tx_state <= TX_GEN_ERROR;
tx_error <= not fifo_fab.error;
rmon_tx_underrun <= '1';
else
if tx_rdreq_toggle = '1' then -- send 16-bit word MSB or LSB
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
files = ["spll_period_detect.vhd",
"spll_bangbang_pd.vhd",
# "spll_bangbang_pd.vhd",
"spll_wbgen2_pkg.vhd",
"spll_aligner.vhd",
"wr_softpll_ng.vhd",
"xwr_softpll_ng.vhd",
"softpll_pkg.vhd",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#define GSI_VENDOR_ID 0x651
#define TLU_DEVICE_ID 0x10051981U
//1 pop => (3rd+rec+adr + 1wr+rec+adr))* 4bytes = 32bytes
#define POP_TS_OPSIZE 32
#define UDP_MAX_POPS 46 // 1500 / 32
#define TLU_READY 0x00 //
#define TLU_CLEAR 0x04
#define TLU_TEST 0x08
......
This diff is collapsed.
......@@ -70,7 +70,7 @@ struct TLU {
/* Access/modify the underlying hardware */
/* ------------------------------------------------------------------- */
Device device; /* Device which hosts this ECA */
Device device; /* Device which hosts this TLU */
eb_address_t address; /* Wishbone base address */
/* Reload mutable registers from hardware */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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