Commit 446f7203 authored by pabloalvarez's avatar pabloalvarez

Very preliminar design. Whisbone and status block to be added. CRC does not work yet.

git-svn-id: http://svn.ohwr.org/cern-fip/trunk/hdl/design@10 7f0067c9-7624-46c7-bd39-3fb5400c0213
parent 3c5a585d
--===========================================================================
--! @file deglitcher.vhd
--! @brief Deserialises the WorldFIP data
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
-------------------------------------------------------------------------------
-- --
-- deglitcher --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: deglitcher
--
--! @brief 1 microsecond pulse adapted filter
--!
--! Used in the NanoFIP design. \n
--! This unit serializes the data.
--!
--!
--! @author Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
--!
--! @date 10/08/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_engine \n
--! tx_engine \n
--! clk_gen \n
--! reset_logic \n
--! consumed_ram \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Erik van der Bij
--! Pablo Alvarez Sanchez
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 07/08/2009 v0.02 PAAS Entity Ports added, start of architecture content
--!
-------------------------------------------------------------------------------
--! @todo Define I/O signals \n
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for deglitcher
--============================================================================
entity deglitcher is
Generic (C_ACULENGTH : integer := 10);
Port ( uclk_i : in STD_LOGIC;
d_i : in STD_LOGIC;
d_o : out STD_LOGIC;
carrier_p_i : in STD_LOGIC;
d_ready_p_o : out STD_LOGIC);
end deglitcher;
architecture Behavioral of deglitcher is
signal s_onesc : signed(C_ACULENGTH - 1 downto 0);
begin
process(uclk_i)
begin
if rising_edge(uclk_i) then
if carrier_p_i = '1' then
s_onesc <= to_signed(0,s_onesc'length);
elsif d_i = '1' then
s_onesc <= s_onesc - 1;
else
s_onesc <= s_onesc + 1;
end if;
end if;
end process;
process(uclk_i)
begin if rising_edge(uclk_i) then
if carrier_p_i = '1' then
d_o <= s_onesc(s_onesc'left);
end if;
d_ready_p_o <= carrier_p_i;
end if;
end process;
end Behavioral;
-------------------------------------------------------------------------------
--! @file dpblockram.vhd
-------------------------------------------------------------------------------
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- --
-- CERN, BE --
-- --
-------------------------------------------------------------------------------
--
-- unit name: dpblockram.vhd
--
--! @brief The dpblockram implements a template for a true dual port ram clocked on both ports by the same clock.
--!
--! @author <Pablo Alvarez(pablo.alvarez.sanchez@cern.ch)>
--
--! @date 24\01\2009
--
--! @version 1
--
--! @details
--!
--! <b>Dependencies:</b>\n
--!
--!
--! <b>References:</b>\n
--! <reference one> \n
--! <reference two>
--!
--! <b>Modified by:</b>\n
--! Author: <name>
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 24\01\2009 paas header included\n
--! <extended description>
-------------------------------------------------------------------------------
--! @todo Adapt vhdl sintax to ohr standard\n
--! <another thing to do> \n
--
-------------------------------------------------------------------------------
entity dpblockram is
generic (dl : integer := 42; -- Length of the data word
al : integer := 10; -- Size of the addr map (10 = 1024 words)
nw : integer := 1024); -- Number of words
-- 'nw' has to be coherent with 'al'
port (clk : in std_logic; -- Global Clock
we : in std_logic; -- Write Enable
aw : in std_logic_vector(al - 1 downto 0); -- Write Address
ar : in std_logic_vector(al - 1 downto 0); -- Read Address
di : in std_logic_vector(dl - 1 downto 0); -- Data input
dw : out std_logic_vector(dl - 1 downto 0); -- Data write, normaly open
do : out std_logic_vector(dl - 1 downto 0)); -- Data output
end dpblockram;
--library synplify;
--use synplify.attributes.all;
architecture syn of dpblockram is
type ram_type is array (nw - 1 downto 0) of std_logic_vector (dl - 1 downto 0);
signal RAM : ram_type;
signal read_a : std_logic_vector(al - 1 downto 0);
signal read_ar : std_logic_vector(al - 1 downto 0);
--attribute syn_ramstyle of RAM : signal is "select_ram";
--attribute syn_ramstyle of RAM : signal is "area ";
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (we = '1') then
RAM(conv_integer(aw)) <= di;
end if;
read_a <=aw ;
read_ar <=ar ;
end if;
end process;
dw <= RAM(conv_integer(read_a));
do <= RAM(conv_integer(read_ar)); -- Notice that the Data Output is not registered
end syn;
--===========================================================================
--! @file nanofip.vhd
--! @brief Top level design file of nanofip
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
-------------------------------------------------------------------------------
-- --
-- nanofip --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: nanofip (nanofip / nanofip)
--
--! @mainpage NanoFIP
--! <HR>
--! @section intro_sec Introduction
--! The NanoFIP is an FPGA component implementing the WorldFIP protocol that
--! can be used in field devices able to communicate at the three standard
--! speeds. The NanoFIP, that is developed as part of the WorldFIP insourcing
--! project, is designed to be radiation tolerant by using different single
--! event upset mitigation techniques such as triple module redundancy. \n\n
--! The NanoFIP design is to be implemented in an Actel ProASIC3 Flash family
--! FPGA that is supposedly to not loose its configuration or have serious
--! total dose effects or latchup problems. SEE still exists but should not
--! give any problems because of SEE mitigation techniques used in the NanoFIP
--! design. \n
--! \n
--! The device is used in conjunction with a FielDrive driver chip and FieldTR
--! insulating transformer, both available from the company ALSTOM.
--!
--! <HR>
--! @section more_sec More information
--! This design is based on the <em>NanoFIP functional specification v1.2</em>
--! http://www.ohwr.org/twiki/pub/OHR/CernFIP/WP3/cernfip_fspec1_2.pdf
--!
--! Complete information about this project at
--! http://www.ohwr.org/twiki/bin/view/OHR/CernFIP/ \n\n
--!
--! <HR>
--! @image html nanofip_image_1s.gif "Block diagram of the NanoFIP design"
--!
--! @author Erik van der Bij (Erik.van.der.Bij@cern.ch)
--
--! @date 07/07/2009
--
--! @version v0.1
--
--! @details
--!
--! <b>Dependencies:</b>\n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Erik van der Bij
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 30/06/2009 v0.010 EB First version \n
--! 06/07/2009 v0.011 EB Dummy blocks \n
--! 07/07/2009 v0.011 EB Comments \n
--!
-------------------------------------------------------------------------------
--! @todo Create entity \n
--
-------------------------------------------------------------------------------
--! @brief Top level design file of nanofip
--============================================================================
--============================================================================
--! Entity declaration for nanofip
--============================================================================
--============================================================================
entity nanofip is
port (
-------------------------------------------------------------------------------
-- WorldFIP settings
-------------------------------------------------------------------------------
--! Bit rate \n
--! 00: 31.25 kbit/s \n
--! 01: 1 Mbit/s \n
--! 10: 2.5 Mbit/s \n
--! 11: reserved, do not use
rate_i : in std_logic_vector (1 downto 0); --! Bit rate
--! Subscriber number coding. Station address.
subs_i : in std_logic_vector (7 downto 0); --! Subscriber number coding.
--! Identification selection (see M_ID, C_ID)
s_id_o : out std_logic_vector (1 downto 0); --! Identification selection
--! Identification variable settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! M_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Model [2*i] 0 1 0 1 \n
--! Model [2*i+1] 0 0 1 1
m_id_i : in std_logic_vector (3 downto 0); --! Model identification settings
--! Constructor identification settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! C_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Constructor[2*i] 0 1 0 1 \n
--! Constructor[2*i+1] 0 0 1 1
c_id_i : in std_logic_vector (3 downto 0); --! Constructor identification settings
--! Produced variable data length \n
--! 000: 2 Bytes \n
--! 001: 8 Bytes \n
--! 010: 16 Bytes \n
--! 011: 32 Bytes \n
--! 100: 64 Bytes \n
--! 101: 124 Bytes \n
--! 110: reserved, do not use \n
--! 111: reserved, do not use \n
--! Actual size: +1 NanoFIP Status byte +1 MPS Status byte (last transmitted)
--! Note: when SLONE=Vcc, p3_lgth_i should be set to 000.
p3_lgth_i : in std_logic_vector (2 downto 0); --! Produced variable data length
-------------------------------------------------------------------------------
-- FIELDRIVE connections
-------------------------------------------------------------------------------
fd_rstn_o : out std_logic; --! Initialisation control, active low
fd_wdgn_i : in std_logic; --! Watchdog on transmitter
fd_txer_i : in std_logic; --! Transmitter error
fd_txena_o: out std_logic; --! Transmitter enable
fd_txck_o : out std_logic; --! Line driver half bit clock
fx_txd_o : out std_logic; --! Transmitter data
fx_rxa_i : in std_logic; --! Reception activity detection
fx_rxd_i : in std_logic; --! Receiver data
-------------------------------------------------------------------------------
-- USER INTERFACE, General signals
-------------------------------------------------------------------------------
uclk_i : in std_logic; --! 40 MHz clock
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
--! No NanoFIP status transmission
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
nostat_i : in std_logic; --! No NanoFIP status transmission
rstin_i : in std_logic; --! Initialisation control, active low
--! Reset output, active low. Active when the reset variable is received
--! and the second byte contains the station address.
rston_o : out std_logic; --! Reset output, active low
-------------------------------------------------------------------------------
-- USER INTERFACE, non WISHBONE
-------------------------------------------------------------------------------
--! Signals new data is received and can safely be read (Consumed
--! variable 05xyh). In stand-alone mode one may sample the data on the
--! first clock edge VAR1_RDY is high.
var1_rdy_o: out std_logic; --! Variable 1 ready
--! Signals that the user logic is accessing variable 1. Only used to
--! generate a status that verifies that VAR1_RDY was high when
--! accessing. May be grounded.
var1_acc_i: in std_logic; --! Variable 1 access
--! Signals new data is received and can safely be read (Consumed
--! broadcast variable 04xyh). In stand-alone mode one may sample the
--! data on the first clock edge VAR1_RDY is high.
var2_rdy_o: out std_logic; --! Variable 2 ready
--! Signals that the user logic is accessing variable 2. Only used to
--! generate a status that verifies that VAR2_RDY was high when
--! accessing. May be grounded.
var2_acc_i: in std_logic; --! Variable 2 access
--! Signals that the variable can safely be written (Produced variable
--! 06xyh). In stand-alone mode, data is sampled on the first clock after
--! VAR_RDY is deasserted.
var3_rdy_o: out std_logic; --! Variable 3 ready
--! Signals that the user logic is accessing variable 3. Only used to
--! generate a status that verifies that VAR3_RDY was high when
--! accessing. May be grounded.
var3_acc_i: in std_logic; --! Variable 3 access
-------------------------------------------------------------------------------
-- USER INTERFACE, WISHBONE SLAVE
-------------------------------------------------------------------------------
wclk_i : in std_logic; --! Wishbone clock. May be independent of UCLK.
--! Data in. Wishbone access only on bits 7-0. Bits 15-8 only used
--! in stand-alone mode.
dat_i : in std_logic_vector (15 downto 0); --! Data in
--! Data out. Wishbone access only on bits 7-0. Bits 15-8 only used
--! in stand-alone mode.
dat_o : out std_logic_vector (15 downto 0); --! Data out
adr_i : in std_logic_vector ( 9 downto 0); --! Address
rst_i : in std_logic; --! Wishbone reset. Does not reset other internal logic.
stb_i : in std_logic; --! Strobe
ack_o : out std_logic; --! Acknowledge
we_i : in std_logic --! Write enable
);
end entity nanofip;
--============================================================================
-- end of entity declaration
--============================================================================
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- COMPONENT DECLARATIONS
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! Placeholder for Consumed RAM
component consumed_ram
port (); --! place holder for ports
end component;
--! Placeholder for Produced RAM
component produced_ram
port (); --! place holder for ports
end component;
--! Placeholder for Produced ROM
component produced_rom
port (); --! place holder for ports
end component;
--! Placeholder for WorldFIP engine
component wf_engine
port (); --! place holder for ports
end component;
--! Placeholder for Transmitter engine
component tx_engine
port (); --! place holder for ports
end component;
--! Placeholder for WorldFIP transmitter/receiver
component wf_tx_rx
port (); --! place holder for ports
end component;
--! Placeholder for User Data interface
component data_if
port (); --! place holder for ports
end component;
--! Placeholder for Reset logic
component reset_logic
port (); --! place holder for ports
end component;
--! Placeholder for Clock generator
component clock_gen
port (); --! place holder for ports
end component;
--! Placeholder for Settings generator
component settings
port (); --! place holder for ports
end component;
--============================================================================
--============================================================================
--! architecture declaration for nanofip
--============================================================================
--============================================================================
--! Architecture contains only connectivity
architecture struc of nanofip is
begin
--! Placeholder for Consumed RAM
cmp_consumed_ram: consumed_ram
port map (); --! place holder for ports
--! Placeholder for Produced RAM
cmp_produced_ram: produced_ram
port map (); --! place holder for ports
--! Placeholder for Produced ROM
cmp_produced_rom: produced_rom
port map (); --! place holder for ports
--! Placeholder for WorldFIP engine
cmp_wf_engine: wf_engine
port map (); --! place holder for ports
--! Placeholder for Transmitter engine
cmp_tx_engine: tx_engine
port map (); --! place holder for ports
--! Placeholder for WorldFIP transmitter/receiver
cmp_wf_tx_rx: wf_tx_rx
port map (); --! place holder for ports
--! Placeholder for User Data interface
cmp_data_if: data_if
port map (); --! place holder for ports
--! Placeholder for Reset logic
cmp_reset_logic: reset_logic
port map (); --! place holder for ports
--! Placeholder for Clock generator
cmp_clock_gen: clock_gen
port map (); --! place holder for ports
--! Placeholder for Settings generator
cmp_settings: settings
port map (); --! place holder for ports
end architecture struc;
--============================================================================
--============================================================================
-- architecture end
--============================================================================
--============================================================================
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file nanofip.vhd
--! @brief Top level design file of nanofip
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
use work.wf_package.all;
-------------------------------------------------------------------------------
-- --
-- nanofip --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: nanofip (nanofip / nanofip)
--
--! @mainpage NanoFIP
--! <HR>
--! @section intro_sec Introduction
--! The NanoFIP is an FPGA component implementing the WorldFIP protocol that
--! can be used in field devices able to communicate at the three standard
--! speeds. The NanoFIP, that is developed as part of the WorldFIP insourcing
--! project, is designed to be radiation tolerant by using different single
--! event upset mitigation techniques such as triple module redundancy. \n\n
--! The NanoFIP design is to be implemented in an Actel ProASIC3 Flash family
--! FPGA that is supposedly to not loose its configuration or have serious
--! total dose effects or latchup problems. SEE still exists but should not
--! give any problems because of SEE mitigation techniques used in the NanoFIP
--! design. \n
--! \n
--! The device is used in conjunction with a FielDrive driver chip and FieldTR
--! insulating transformer, both available from the company ALSTOM.
--!
--! <HR>
--! @section more_sec More information
--! This design is based on the <em>NanoFIP functional specification v1.2</em>
--! http://www.ohwr.org/twiki/pub/OHR/CernFIP/WP3/cernfip_fspec1_2.pdf
--!
--! Complete information about this project at
--! http://www.ohwr.org/twiki/bin/view/OHR/CernFIP/ \n\n
--!
--! <HR>
--! @image html nanofip_image_1s.gif "Block diagram of the NanoFIP design"
--!
--! @author Erik van der Bij (Erik.van.der.Bij@cern.ch)
--
--! @date 07/07/2009
--
--! @version v0.1
--
--! @details
--!
--! <b>Dependencies:</b>\n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Erik van der Bij
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 30/06/2009 v0.010 EB First version \n
--! 06/07/2009 v0.011 EB Dummy blocks \n
--! 07/07/2009 v0.011 EB Comments \n
--!
-------------------------------------------------------------------------------
--! @todo Create entity \n
--
-------------------------------------------------------------------------------
--! @brief Top level design file of nanofip
--============================================================================
--============================================================================
--! Entity declaration for nanofip
--============================================================================
--============================================================================
entity nanofip is
port (
-------------------------------------------------------------------------------
-- WorldFIP settings
-------------------------------------------------------------------------------
--! Bit rate \n
--! 00: 31.25 kbit/s \n
--! 01: 1 Mbit/s \n
--! 10: 2.5 Mbit/s \n
--! 11: reserved, do not use
rate_i : in std_logic_vector (1 downto 0); --! Bit rate
--! Subscriber number coding. Station address.
subs_i : in std_logic_vector (7 downto 0); --! Subscriber number coding.
--! Identification selection (see M_ID, C_ID)
s_id_o : out std_logic_vector (1 downto 0); --! Identification selection
--! Identification variable settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! M_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Model [2*i] 0 1 0 1 \n
--! Model [2*i+1] 0 0 1 1
m_id_i : in std_logic_vector (3 downto 0); --! Model identification settings
--! Constructor identification settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! C_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Constructor[2*i] 0 1 0 1 \n
--! Constructor[2*i+1] 0 0 1 1
c_id_i : in std_logic_vector (3 downto 0); --! Constructor identification settings
--! Produced variable data length \n
--! 000: 2 Bytes \n
--! 001: 8 Bytes \n
--! 010: 16 Bytes \n
--! 011: 32 Bytes \n
--! 100: 64 Bytes \n
--! 101: 124 Bytes \n
--! 110: reserved, do not use \n
--! 111: reserved, do not use \n
--! Actual size: +1 NanoFIP Status byte +1 MPS Status byte (last transmitted)
--! Note: when SLONE=Vcc, p3_lgth_i should be set to 000.
p3_lgth_i : in std_logic_vector (2 downto 0); --! Produced variable data length
-------------------------------------------------------------------------------
-- FIELDRIVE connections
-------------------------------------------------------------------------------
fd_rstn_o : out std_logic; --! Initialisation control, active low
fd_wdgn_i : in std_logic; --! Watchdog on transmitter
fd_txer_i : in std_logic; --! Transmitter error
fd_txena_o: out std_logic; --! Transmitter enable
fd_txck_o : out std_logic; --! Line driver half bit clock
fx_txd_o : out std_logic; --! Transmitter data
fx_rxa_i : in std_logic; --! Reception activity detection
fx_rxd_i : in std_logic; --! Receiver data
-------------------------------------------------------------------------------
-- USER INTERFACE, General signals
-------------------------------------------------------------------------------
uclk_i : in std_logic; --! 40 MHz clock
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
--! No NanoFIP status transmission
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
nostat_i : in std_logic; --! No NanoFIP status transmission
rstin_i : in std_logic; --! Initialisation control, active low
--! Reset output, active low. Active when the reset variable is received
--! and the second byte contains the station address.
rston_o : out std_logic; --! Reset output, active low
-------------------------------------------------------------------------------
-- USER INTERFACE, non WISHBONE
-------------------------------------------------------------------------------
--! Signals new data is received and can safely be read (Consumed
--! variable 05xyh). In stand-alone mode one may sample the data on the
--! first clock edge VAR1_RDY is high.
var1_rdy_o: out std_logic; --! Variable 1 ready
--! Signals that the user logic is accessing variable 1. Only used to
--! generate a status that verifies that VAR1_RDY was high when
--! accessing. May be grounded.
var1_acc_i: in std_logic; --! Variable 1 access
--! Signals new data is received and can safely be read (Consumed
--! broadcast variable 04xyh). In stand-alone mode one may sample the
--! data on the first clock edge VAR1_RDY is high.
var2_rdy_o: out std_logic; --! Variable 2 ready
--! Signals that the user logic is accessing variable 2. Only used to
--! generate a status that verifies that VAR2_RDY was high when
--! accessing. May be grounded.
var2_acc_i: in std_logic; --! Variable 2 access
--! Signals that the variable can safely be written (Produced variable
--! 06xyh). In stand-alone mode, data is sampled on the first clock after
--! VAR_RDY is deasserted.
var3_rdy_o: out std_logic; --! Variable 3 ready
--! Signals that the user logic is accessing variable 3. Only used to
--! generate a status that verifies that VAR3_RDY was high when
--! accessing. May be grounded.
var3_acc_i: in std_logic; --! Variable 3 access
-------------------------------------------------------------------------------
-- USER INTERFACE, WISHBONE SLAVE
-------------------------------------------------------------------------------
wclk_i : in std_logic; --! Wishbone clock. May be independent of UCLK.
--! Data in. Wishbone access only on bits 7-0. Bits 15-8 only used
--! in stand-alone mode.
dat_i : in std_logic_vector (15 downto 0); --! Data in
--! Data out. Wishbone access only on bits 7-0. Bits 15-8 only used
--! in stand-alone mode.
dat_o : out std_logic_vector (15 downto 0); --! Data out
-- dat_i : in std_logic_vector(15 downto 0);
adr_i : in std_logic_vector ( 9 downto 0); --! Address
rst_i : in std_logic; --! Wishbone reset. Does not reset other internal logic.
stb_i : in std_logic; --! Strobe
ack_o : out std_logic; --! Acknowledge
we_i : in std_logic --! Write enable
);
end entity nanofip;
--============================================================================
-- end of entity declaration
--============================================================================
--============================================================================
--============================================================================
--! architecture declaration for nanofip
--============================================================================
--============================================================================
--! Architecture contains only connectivity
architecture struc of nanofip is
signal s_append_status_from_control : std_logic;
signal s_data_length_from_control : std_logic_vector(6 downto 0);
signal s_byte_to_tx : std_logic_vector(7 downto 0);
signal s_rst : std_logic;
signal s_start_send_p : std_logic;
signal s_request_byte_from_tx_p : std_logic;
signal s_byte_to_tx_ready_p : std_logic;
signal s_last_byte_to_tx_p, s_last_byte_from_rx_p : std_logic;
signal s_byte_from_rx_ready_p : std_logic;
signal s_byte_from_rx : std_logic_vector(7 downto 0);
signal s_cons_byte_we_from_control : std_logic;
signal s_var_from_control : t_var;
signal s_add_offset_from_control : std_logic_vector(6 downto 0);
signal addr_from_wb : std_logic_vector(9 downto 0);
signal s_crc_ok_from_rx : std_logic;
signal fss_decoded_p_from_rx : std_logic;
signal frame_ok_from_rx : std_logic;
signal s_stat : std_logic_vector(7 downto 0);
--signal
begin
s_rst <= rst_i;
----! Placeholder for WorldFIP transmitter/receiver
uwf_tx_rx : wf_tx_rx
port map(
uclk_i => uclk_i,
rst_i => s_rst,
start_send_p_i => s_start_send_p,
request_byte_p_o => s_request_byte_from_tx_p,
byte_ready_p_i => s_byte_to_tx_ready_p,
byte_i => s_byte_to_tx,
last_byte_p_i => s_last_byte_to_tx_p,
-- clk_fixed_carrier_p_o : out std_logic;
d_o => fx_txd_o,
d_e_o => fd_txena_o,
d_clk_o => fd_txck_o,
d_a_i => fx_rxd_i,
rate_i => rate_i,
byte_ready_p_o => s_byte_from_rx_ready_p,
byte_o => s_byte_from_rx,
fss_decoded_p_o => fss_decoded_p_from_rx, -- The frame decoder has detected the start of a frame
last_byte_p_o => s_last_byte_from_rx_p,
crc_ok_p_o => s_crc_ok_from_rx
);
uwf_engine_control : wf_engine_control
generic map( C_QUARTZ_PERIOD => 25.0)
port map(
uclk_i => uclk_i, --! User Clock
rst_i => rst_i,
-- Transmiter interface
start_send_p_o => s_start_send_p ,
request_byte_p_i => s_request_byte_from_tx_p,
byte_ready_p_o => s_byte_to_tx_ready_p,
-- byte_o : out std_logic_vector(7 downto 0);
last_byte_p_o => s_last_byte_to_tx_p,
-- Receiver interface
fss_decoded_p_i => fss_decoded_p_from_rx, -- The frame decoder has detected the start of a frame
byte_ready_p_i => s_byte_from_rx_ready_p, -- The frame docoder ouputs a new byte on byte_i
byte_i => s_byte_from_rx, -- Decoded byte
frame_ok_p_i => frame_ok_from_rx,
-- Worldfip bit rate
rate_i => rate_i,
subs_i => subs_i, --! Subscriber number coding.
p3_lgth_i => p3_lgth_i, --! Produced variable data length
slone_i => slone_i, --! Stand-alone mode
nostat_i => nostat_i, --! No NanoFIP status transmission
-------------------------------------------------------------------------------
-- USER INTERFACE, non WISHBONE
-------------------------------------------------------------------------------
var1_rdy_o => var1_rdy_o, --! Variable 1 ready
var2_rdy_o => var2_rdy_o, --! Variable 2 ready
--! Signals that the variable can safely be written (Produced variable
--! 06xyh). In stand-alone mode, data is sampled on the first clock after
--! VAR_RDY is deasserted.
var3_rdy_o => var3_rdy_o, --! Variable 3 ready
-- prod_byte_i : in std_logic_vector(7 downto 0);
var_o => s_var_from_control,
append_status_o => s_append_status_from_control,
add_offset_o => s_add_offset_from_control,
data_length_o => s_data_length_from_control,
cons_byte_we_p_o => s_cons_byte_we_from_control
);
uwf_consumed_vars : wf_consumed_vars
port map(
uclk_i => uclk_i, --! User Clock
rst_i => rst_i,
slone_i => slone_i, --! Stand-alone mode
byte_ready_p_i => s_cons_byte_we_from_control,
var_i => s_var_from_control,
add_offset_i => s_add_offset_from_control,
byte_i => s_byte_from_rx,
dat_o => open, --!
adr_i => addr_from_wb --!
);
addr_from_wb <= (others => '0');
uwf_produced_vars : wf_produced_vars
port map(
uclk_i => uclk_i, --! User Clock
rst_i => rst_i,
m_id_i => m_id_i, --! Model identification settings
c_id_i => c_id_i, --! Constructor identification settings
slone_i => slone_i, --! Stand-alone mode
nostat_i => nostat_i, --! No NanoFIP status transmission
stat_i => s_stat, -- NanoFIP status
var_i => s_var_from_control,
append_status_i => s_append_status_from_control,
add_offset_i => s_add_offset_from_control,
data_length_i => s_data_length_from_control,
byte_o => s_byte_to_tx,
dat_i => dat_i, --!
adr_i => adr_i, --!
we_p_i => we_i --! Write enable
);
s_stat <= (others => '0');
end architecture struc;
--============================================================================
--============================================================================
-- architecture end
--============================================================================
--============================================================================
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file wf_consumed_vars.vhd
--! @brief Nanofip control unit
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
use work.wf_package.all;
-------------------------------------------------------------------------------
-- --
-- wf_consumed_vars --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_consumed_vars
--
--! @brief Nanofip control unit. It accepts variable data and store them into block ram or in stand alone mode directly to the wf_wishbone. \n
--!
--!
--!
--!
--!
--!
--!
--! @author Pablo Alvarez Sanchez (pablo.alvarez.sanchez@cern.ch)
--
--! @date 11/09/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_package \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 11/09/2009 v0.01 EB First version \n
--!
-------------------------------------------------------------------------------
--! @todo
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_consumed_vars
--============================================================================
entity wf_consumed_vars is
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
byte_ready_p_i : in std_logic;
var_i : in t_var;
-- append_status_i : in std_logic;
add_offset_i : in std_logic_vector(6 downto 0);
-- data_length_i : in std_logic_vector(6 downto 0);
byte_i : in std_logic_vector(7 downto 0);
-------------------------------------------------------------------------------
--! USER INTERFACE. Data and address lines synchronized with uclk_i
-------------------------------------------------------------------------------
-- dat_i : in std_logic_vector (15 downto 0); --!
dat_o : out std_logic_vector (15 downto 0); --!
adr_i : in std_logic_vector ( 9 downto 0) --!
-- stb_p_i : in std_logic; --! Strobe
-- ack_p_o : out std_logic; --! Acknowledge
-- we_p_i : in std_logic --! Write enable
);
end entity wf_consumed_vars;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_control
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_consumed_vars is
constant c_presence_pos : natural := 0;
constant c_identification_pos : natural := 1;
constant c_mem_pos : natural := 2;
constant c_last_pos : natural := 2;
signal base_add, add: std_logic_vector(9 downto 0);
signal s_dat_ram : std_logic_vector(7 downto 0);
signal we_ram_p : std_logic;
signal we_byte_p : std_logic_vector(1 downto 0);
signal s_dat : std_logic_vector(15 downto 0);
begin
production_dpram : dpblockram
generic map(dl => 8, -- Length of the data word
al => 7, -- Size of the addr map (10 = 1024 words)
nw => 2**7) -- Number of words
-- 'nw' has to be coherent with 'al'
port map(clk => uclk_i, -- Global Clock
we => we_ram_p, -- Write Enable
aw => add(6 downto 0), -- Write Address
ar => adr_i(6 downto 0), -- Read Address
di => byte_i, -- Data input
dw => open, -- Data write, normaly open
do => s_dat_ram); -- Data output
add <= std_logic_vector(unsigned(add_offset_i) + unsigned(base_add));
process(var_i, add_offset_i, slone_i, byte_ready_p_i)
begin
we_ram_p <= '0';
we_byte_p <= (others => '0');
base_add <= (others => '0');
for I in c_var_array'range loop
if (c_var_array(I).response = consume) then
if c_var_array(I).var = var_i then
base_add <= c_var_array(I).base_add;
if slone_i = '0' then
we_ram_p <= byte_ready_p_i;
elsif slone_i = '1' and I = c_var_var1_pos then
if unsigned(add_offset_i) = c_byte_0_add then
we_byte_p(0) <= byte_ready_p_i ;
end if;
if unsigned(add_offset_i) = c_byte_1_add then
we_byte_p(1) <= byte_ready_p_i ;
end if;
end if;
exit;
end if;
end if;
end loop;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
s_dat <= (others => '0');
else
if we_byte_p(1) = '1' then
s_dat(15 downto 8) <= byte_i;
end if;
if we_byte_p(0) = '1' then
s_dat(7 downto 0) <= byte_i;
end if;
end if;
end if;
end process;
process(s_dat, s_dat_ram, slone_i)
begin
dat_o <= (others => '0');
if slone_i = '1' then
dat_o <= s_dat;
else
dat_o(7 downto 0) <= s_dat_ram;
end if;
end process;
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file wf_crc.vhd
--! @brief Calculates the crc of serialized data.
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
-------------------------------------------------------------------------------
-- --
-- wf_crc --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_crc
--
--! @brief Calculates the crc of serialized data.
--!
--! Used in the NanoFIP design. \n
--! Calculates the crc of serialized data.
--!
--!
--! @author Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
--!
--! @date 10/08/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Pablo Alvarez Sanchez
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 07/08/2009 v0.02 PAAS Entity Ports added, start of architecture content
--!
-------------------------------------------------------------------------------
--! @todo Define I/O signals \n
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_crc
--============================================================================
entity wf_crc is
generic(
c_poly_length : natural := 16);
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
start_p_i : in std_logic;
d_i : in std_logic;
d_rdy_p_i : in std_logic;
data_fcs_sel_n : in std_logic;
crc_o : out std_logic_vector(c_poly_length - 1 downto 0);
crc_rdy_p_o : out std_logic;
crc_ok_p : out std_logic
);
end entity wf_crc;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_crc
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_crc is
--! shift register xor mask
constant c_poly : std_logic_vector(c_poly_length - 1 downto 0) := "0001110111001111";
--! crc check mask
constant c_check_mask : std_logic_vector(c_poly_length - 1 downto 0) := "0001110001101011";
signal s_q, s_q_nx : std_logic_vector(c_poly_length - 1 downto 0);
signal s_crc_rdy_p : std_logic;
begin
G: for I in 0 to c_poly'left generate
G0: if I = 0 generate
s_q_nx(I) <= data_fcs_sel_n and (d_i xor s_q(s_q'left));
end generate;
G1: if I > 0 generate
s_q_nx(I) <= s_q(I-1) xor (c_poly(I) and data_fcs_sel_n and (d_i xor s_q(s_q'left)));
end generate;
end generate;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
s_q <= (others => '1');
else
if start_p_i = '1' then
s_q <= (others => '1');
elsif d_rdy_p_i = '1' then
s_q <= s_q_nx;
end if;
s_crc_rdy_p <= d_rdy_p_i;
end if;
end if;
end process;
crc_o <= s_q;
crc_rdy_p_o <= s_crc_rdy_p;
process(s_q, s_crc_rdy_p)
variable v_q_check_mask : std_logic_vector(c_poly_length - 1 downto 0);
begin
v_q_check_mask := s_q xor c_check_mask;
crc_ok_p <= '0';
if (unsigned(not v_q_check_mask)) = 0 then
crc_ok_p <= s_crc_rdy_p;
end if;
end process;
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file wf_engine_control.vhd
--! @brief Nanofip control unit
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
use work.wf_package.all;
-------------------------------------------------------------------------------
-- --
-- wf_engine_control --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_control
--
--! @brief Nanofip control unit. It treats variable production and consuptions requests and manage timeouts. \n
--!
--!
--!
--!
--!
--!
--!
--! @author Pablo Alvarez Sanchez (pablo.alvarez.sanchez@cern.ch)
--
--! @date 11/09/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_engine \n
--! tx_engine \n
--! clk_gen \n
--! reset_logic \n
--! consumed_ram \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 11/09/2009 v0.01 EB First version \n
--!
-------------------------------------------------------------------------------
--! @todo
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_engine_control
--============================================================================
entity wf_engine_control is
generic( C_QUARTZ_PERIOD : real := 25.0);
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
-- Transmiter interface
start_send_p_o : out std_logic;
request_byte_p_i : in std_logic;
byte_ready_p_o : out std_logic;
-- byte_o : out std_logic_vector(7 downto 0);
last_byte_p_o : out std_logic;
-- Receiver interface
fss_decoded_p_i : in std_logic; -- The frame decoder has detected the start of a frame
byte_ready_p_i : in std_logic; -- The frame docoder ouputs a new byte on byte_i
byte_i : in std_logic_vector(7 downto 0); -- Decoded byte
frame_ok_p_i : in std_logic;
-- Worldfip bit rate
rate_i : in std_logic_vector(1 downto 0);
subs_i : in std_logic_vector (7 downto 0); --! Subscriber number coding.
--! Produced variable data length \n
--! 000: 2 Bytes \n
--! 001: 8 Bytes \n
--! 010: 16 Bytes \n
--! 011: 32 Bytes \n
--! 100: 64 Bytes \n
--! 101: 124 Bytes \n
--! 110: reserved, do not use \n
--! 111: reserved, do not use \n
--! Actual size: +1 NanoFIP Status byte +1 MPS Status byte (last transmitted)
--! Note: when SLONE=Vcc, p3_lgth_i should be set to 000.
p3_lgth_i : in std_logic_vector (2 downto 0); --! Produced variable data length
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
--! No NanoFIP status transmission
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
nostat_i : in std_logic; --! No NanoFIP status transmission
-------------------------------------------------------------------------------
-- USER INTERFACE, non WISHBONE
-------------------------------------------------------------------------------
--! Signals new data is received and can safely be read (Consumed
--! variable 05xyh). In stand-alone mode one may sample the data on the
--! first clock edge VAR1_RDY is high.
var1_rdy_o: out std_logic; --! Variable 1 ready
--! Signals new data is received and can safely be read (Consumed
--! broadcast variable 04xyh). In stand-alone mode one may sample the
--! data on the first clock edge VAR1_RDY is high.
var2_rdy_o: out std_logic; --! Variable 2 ready
--! Signals that the variable can safely be written (Produced variable
--! 06xyh). In stand-alone mode, data is sampled on the first clock after
--! VAR_RDY is deasserted.
var3_rdy_o: out std_logic; --! Variable 3 ready
-- prod_byte_i : in std_logic_vector(7 downto 0);
var_o : out t_var;
append_status_o : out std_logic;
add_offset_o : out std_logic_vector(6 downto 0);
data_length_o : out std_logic_vector(6 downto 0);
cons_byte_we_p_o : out std_logic
);
end entity wf_engine_control;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_control
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_engine_control is
type control_st_t is (cont_idle, cont_w_id_dat_control, cont_w_id_dat_subs, cont_w_id_dat_var, cont_w_id_dat_frame_ok,
cont_w_prod_watchdog, cont_w_cons_watchdog, cont_cons_var, cont_prod_var);
signal control_st, nx_control_st : control_st_t;
signal temp_var, var, nx_temp_var : t_var;
signal s_watchdog_c, s_watchdog_top, s_response_time, s_silence_time : signed(16 downto 0);
signal s_reset_watchdog_c : std_logic;
signal s_p3_length_decoded : unsigned(6 downto 0);
--signal produce, consume : std_logic;
signal data_length : unsigned(6 downto 0);
signal s_reset_id_data : std_logic;
signal s_watchdog_is_zero : std_logic;
signal s_broadcast : std_logic;
signal s_byte_c : unsigned(6 downto 0);
signal s_inc_bytes_c, s_reset_bytes_c : std_logic;
signal s_prodcons : std_logic_vector(1 downto 0);
signal nx_last_byte_p : std_logic;
signal s_load_temp_var : std_logic;
signal s_load_var : std_logic;
signal data_length_match : std_logic;
signal nx_byte_ready_p : std_logic;
signal s_append_status : std_logic;
signal var1_was_received, var2_was_received : std_logic;
begin
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
control_st <= cont_idle;
else
control_st <= nx_control_st;
end if;
end if;
end process;
process(control_st, fss_decoded_p_i, nx_last_byte_p, nx_temp_var, byte_ready_p_i, byte_i, subs_i, s_prodcons, frame_ok_p_i, s_broadcast, nx_temp_var, s_watchdog_is_zero)
begin
nx_control_st <= cont_idle;
case control_st is
when cont_idle => if fss_decoded_p_i = '1' then
nx_control_st <= cont_w_id_dat_control;
else
nx_control_st <= cont_idle;
end if;
when cont_w_id_dat_control => if (byte_ready_p_i = '1') and (byte_i = c_id_dat) then
nx_control_st <= cont_w_id_dat_subs;
elsif (byte_ready_p_i = '1') then
nx_control_st <= cont_idle;
else
nx_control_st <= cont_w_id_dat_control;
end if;
when cont_w_id_dat_subs =>
if (byte_ready_p_i = '1') and (byte_i = subs_i) then
nx_control_st <= cont_w_id_dat_var;
elsif (byte_ready_p_i = '1') and (s_broadcast = '1') then
nx_control_st <= cont_w_id_dat_var;
elsif (byte_ready_p_i = '1') then
nx_control_st <= cont_idle;
else
nx_control_st <= cont_w_id_dat_subs;
end if;
when cont_w_id_dat_var =>
if (byte_ready_p_i = '1') and (nx_temp_var /= c_st_var_whatever) then
nx_control_st <= cont_w_id_dat_frame_ok;
elsif (byte_ready_p_i = '1') and (nx_temp_var = c_st_var_whatever) then
nx_control_st <= cont_idle;
else
nx_control_st <= cont_w_id_dat_var;
end if;
when cont_w_id_dat_frame_ok => if (frame_ok_p_i = '1') and (s_prodcons = "10") then
nx_control_st <= cont_w_prod_watchdog;
elsif (frame_ok_p_i = '1') and (s_prodcons = "01") then
nx_control_st <= cont_w_cons_watchdog;
elsif (frame_ok_p_i = '1') then
nx_control_st <= cont_idle;
elsif fss_decoded_p_i = '1' then
nx_control_st <= cont_w_id_dat_control;
else
nx_control_st <= cont_w_id_dat_frame_ok;
end if;
when cont_w_prod_watchdog => if s_watchdog_is_zero = '1' then
nx_control_st <= cont_prod_var;
else
nx_control_st <= cont_w_prod_watchdog;
end if;
-- when cont_w_cons_watchdog => if s_watchdog_is_zero = '1' then
-- nx_control_st <= cont_cons_var;
-- else
-- nx_control_st <= cont_w_cons_watchdog;
-- end if;
when cont_cons_var => if frame_ok_p_i = '1' or s_watchdog_is_zero = '1' then
nx_control_st <= cont_idle;
else
nx_control_st <= cont_cons_var;
end if;
when cont_prod_var => if nx_last_byte_p = '1' then
nx_control_st <= cont_idle;
else
nx_control_st <= cont_prod_var;
end if;
when others => nx_control_st <= cont_idle;
end case;
end process;
process(control_st, frame_ok_p_i, s_prodcons, s_response_time, s_silence_time, request_byte_p_i, s_watchdog_is_zero, byte_ready_p_i, data_length_match)
begin
s_reset_watchdog_c <= '1';
s_inc_bytes_c <= '0';
s_reset_bytes_c <= '1';
s_load_temp_var <= '0';
s_load_var <= '0';
s_watchdog_top <= s_silence_time;
cons_byte_we_p_o <= '0';
start_send_p_o <= '0';
nx_last_byte_p <= '0';
s_reset_id_data <= '0';
nx_byte_ready_p <= '0';
case control_st is
when cont_w_id_dat_var =>
s_load_temp_var <= byte_ready_p_i;
when cont_w_id_dat_frame_ok =>
if s_prodcons = "10" then
s_watchdog_top <= s_response_time;
else
s_watchdog_top <= s_silence_time;
end if;
s_reset_watchdog_c <= '1';
s_load_var <= '1';
when cont_w_prod_watchdog =>
start_send_p_o <= s_watchdog_is_zero;
s_reset_watchdog_c <= '0';
when cont_cons_var =>
s_reset_watchdog_c <= '0';
s_inc_bytes_c <= byte_ready_p_i;
cons_byte_we_p_o <= byte_ready_p_i;
s_reset_id_data <= frame_ok_p_i or s_watchdog_is_zero;
when cont_prod_var =>
s_reset_watchdog_c <= '0';
nx_last_byte_p <= data_length_match and request_byte_p_i;
nx_byte_ready_p <= request_byte_p_i;
s_inc_bytes_c <= request_byte_p_i;
s_reset_bytes_c <= '0';
s_reset_id_data <= nx_last_byte_p;
when others =>
end case;
end process;
--
--process(byte_i)
--begin
--nx_temp_var <= c_st_var_whatever;
--case byte_i is
-- when c_var_presence => nx_temp_var <= c_st_var_presence;
--
-- when c_var_identification => nx_temp_var <= c_st_var_identification;
-- when c_var_1 => nx_temp_var <= c_st_var_1;
-- when c_var_2 => nx_temp_var <= c_st_var_2;
-- when c_var_3 => nx_temp_var <= c_st_var_3;
-- when c_var_reset => nx_temp_var <= c_st_var_reset;
-- when others => nx_temp_var <= c_st_var_whatever;
--end case;
--end process;
process(byte_i)
begin
nx_temp_var <= c_st_var_whatever;
for I in c_var_array'range loop
if byte_i = c_var_array(I).hexvalue then
nx_temp_var <= c_var_array(I).var;
exit;
end if;
end loop;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
var <= c_st_var_whatever;
else
if s_reset_id_data = '1' then
temp_var <= c_st_var_whatever;
elsif s_load_temp_var = '1' then
temp_var <= nx_temp_var;
end if;
if s_reset_id_data = '1' then
var <= c_st_var_whatever;
elsif s_load_var = '1' then
var <= temp_var;
end if;
end if;
end if;
end process;
process(temp_var)
begin
s_prodcons <= "00";
for I in c_var_array'range loop
if temp_var = c_var_array(I).var then
if c_var_array(I).response = produce then
s_prodcons <= "10";
else
s_prodcons <= "01";
end if;
exit;
end if;
end loop;
end process;
process(temp_var)
begin
s_broadcast <= '0';
if temp_var = c_st_var_2 then
s_broadcast <= '1';
end if;
end process;
process(var, s_p3_length_decoded, nostat_i)
variable v_nostat : std_logic_vector(1 downto 0);
begin
v_nostat := ('0'& ((not nostat_i) and (not slone_i)));
s_append_status <= '0';
data_length <= to_unsigned(0,data_length'length);
case var is
when c_st_var_presence =>
data_length <= to_unsigned(6,data_length'length);
when c_st_var_identification =>
data_length <= to_unsigned(9,data_length'length);
when c_st_var_1 =>
when c_st_var_2 =>
when c_st_var_3 =>
s_append_status <= not nostat_i;
if nostat_i = '1' then
data_length <= to_unsigned(3,data_length'length);
else
data_length <= s_p3_length_decoded + unsigned(v_nostat) ;
end if;
when c_st_var_reset =>
when others =>
end case;
end process;
append_status_o <= s_append_status;
data_length_o <= std_logic_vector(data_length);
--process(p3_lgth_i)
--begin
-- s_p3_length_decoded <= to_unsigned(0, s_p3_length_decoded'length);
--case p3_lgth_i is
-- when "000" => s_p3_length_decoded <= to_unsigned(2, s_p3_length_decoded'length);
-- when "001" => s_p3_length_decoded <= to_unsigned(8, s_p3_length_decoded'length);
-- when "010" => s_p3_length_decoded <= to_unsigned(16, s_p3_length_decoded'length);
-- when "011" => s_p3_length_decoded <= to_unsigned(32, s_p3_length_decoded'length);
-- when "100" => s_p3_length_decoded <= to_unsigned(64, s_p3_length_decoded'length);
-- when "101" => s_p3_length_decoded <= to_unsigned(124, s_p3_length_decoded'length);
-- when "110" => s_p3_length_decoded <= to_unsigned(0, s_p3_length_decoded'length);
-- when "111" => s_p3_length_decoded <= to_unsigned(0, s_p3_length_decoded'length);
-- when others => s_p3_length_decoded <= to_unsigned(0, s_p3_length_decoded'length);
--end case;
--end process;
s_p3_length_decoded <= to_unsigned(c_p3_var_length_table(to_integer(unsigned(p3_lgth_i))), s_p3_length_decoded'length);
--process(rate_i)
--begin
-- s_response_time <= to_signed(integer(c_response_time_31k25/C_QUARTZ_PERIOD), s_response_time'length);
-- s_silence_time <= to_signed(integer(c_silence_time_31k25/C_QUARTZ_PERIOD), s_silence_time'length);
--case rate_i is
-- when "00" => s_response_time <= to_signed(integer(c_response_time_31k25/C_QUARTZ_PERIOD), s_response_time'length);
-- s_silence_time <= to_signed(integer(c_silence_time_31k25/C_QUARTZ_PERIOD), s_silence_time'length);
--
-- when "01" => s_response_time <= to_signed(integer(c_response_time_1M/C_QUARTZ_PERIOD), s_response_time'length);
-- s_silence_time <= to_signed(integer(c_silence_time_1M/C_QUARTZ_PERIOD), s_silence_time'length);
-- when "10" => s_response_time <= to_signed(integer(c_response_time_2M5/C_QUARTZ_PERIOD), s_response_time'length);
-- s_silence_time <= to_signed(integer(c_silence_time_2M5/C_QUARTZ_PERIOD), s_silence_time'length);
--
-- when others =>
-- s_response_time <= to_signed(integer(c_response_time_31k25/C_QUARTZ_PERIOD), s_response_time'length);
-- s_silence_time <= to_signed(integer(c_silence_time_31k25/C_QUARTZ_PERIOD), s_silence_time'length);
--
--end case;
--end process;
s_response_time <= to_signed((c_timeouts_table(to_integer(unsigned(rate_i))).response), s_response_time'length);
s_silence_time <= to_signed((c_timeouts_table(to_integer(unsigned(rate_i))).silence), s_response_time'length);
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
s_byte_c <= to_unsigned(0, s_byte_c'length);
elsif s_reset_bytes_c = '1' then
s_byte_c <= to_unsigned(0, s_byte_c'length);
elsif s_inc_bytes_c = '1' then
s_byte_c <= s_byte_c + 1;
end if;
end if;
end process;
add_offset_o <= std_logic_vector(s_byte_c);
data_length_match <= '1' when s_byte_c = data_length else '0';
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
s_watchdog_c <= to_signed(-1, s_watchdog_c'length);
elsif s_reset_watchdog_c = '1' then
s_watchdog_c <= s_watchdog_top;
else
s_watchdog_c <= s_watchdog_c -1;
end if;
end if;
end process;
s_watchdog_is_zero <= '1' when s_watchdog_c = 0 else '0';
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
last_byte_p_o <= '0';
byte_ready_p_o <= '0';
else
last_byte_p_o <= nx_last_byte_p;
byte_ready_p_o <= nx_byte_ready_p;
end if;
end if;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
var1_rdy_o<= '0';
var1_was_received <= '0';
elsif var = c_st_var_1 then
var1_rdy_o <= '0';
var1_was_received <= '1'; -- After a reset var1_rdy must not be asserted
else
var1_rdy_o <= var1_was_received; -- After a reset var1_rdy must not be asserted
end if;
if rst_i = '1' then
var2_rdy_o<= '0';
var2_was_received <= '0';
elsif var = c_st_var_2 then
var2_rdy_o <= '0';
var2_was_received <= '1';
else
var2_rdy_o <= var2_was_received; -- After a reset var2_rdy must not be asserted
end if;
if rst_i = '1' then
var3_rdy_o<= '0';
elsif var = c_st_var_3 then
var3_rdy_o <= '1';
else
var3_rdy_o <= '0';
end if;
end if;
end process;
var_o <= var;
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
-- Package File Template
--
-- Purpose: This package defines supplemental types, subtypes,
-- constants, and functions
library IEEE;
use IEEE.STD_LOGIC_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
package wf_package is
constant C_QUARTZ_PERIOD : real := 25.0;
type t_timeouts is
record
response : integer;
silence : integer;
end record;
constant c_31k25_rate_pos : integer := 0;
constant c_1M_rate_pos : integer := 1;
constant c_2M5_rate_pos : integer := 2;
constant c_11_rate_pos : integer := 3;
type t_timeouts_table is array (natural range <>) of t_timeouts;
constant c_timeouts_table : t_timeouts_table(0 to 3) := -- Time in ns
(c_31k25_rate_pos => (response => integer(640000.0/C_QUARTZ_PERIOD), silence => integer(5160000.0/C_QUARTZ_PERIOD)),
c_1M_rate_pos => (response => integer(10000.0/C_QUARTZ_PERIOD), silence => integer(150000.0/C_QUARTZ_PERIOD)),
c_2M5_rate_pos => (response => integer(16000.0/C_QUARTZ_PERIOD), silence => integer(100000.0/C_QUARTZ_PERIOD)),
c_11_rate_pos => (response => integer(640000.0/C_QUARTZ_PERIOD), silence => integer(5160000.0/C_QUARTZ_PERIOD))
);
type t_integer_array is array (natural range <>) of integer;
constant c_p3_var_length_table : t_integer_array(0 to 7) :=
(0 => 2, 1 => 8, 2 => 16, 3 => 32, 4 => 64, 5 => 124, others => 0);
constant c_id_dat : std_logic_vector(7 downto 0) := "11000000";
constant c_rp_dat : std_logic_vector(7 downto 0) := "01000000";
--constant c_var_presence : std_logic_vector(7 downto 0) := x"14";
--constant c_var_identification : std_logic_vector(7 downto 0) := x"10";
--constant c_var_1 : std_logic_vector(7 downto 0) := x"05";
--constant c_var_2 : std_logic_vector(7 downto 0) :=x"04";
--constant c_var_3 : std_logic_vector(7 downto 0) := x"06";
--constant c_var_reset : std_logic_vector(7 downto 0) := x"e0";
type t_var is (c_st_var_presence, c_st_var_identification, c_st_var_1, c_st_var_2, c_st_var_3, c_st_var_reset, c_st_var_whatever);
type t_byte_array is array (natural range <>) of std_logic_vector(7 downto 0);
--constant c_pres_byte_array : t_byte_array(1 to 7) := (1 => x"50", 2 => x"05", 3 => x"80", 4 => x"03", 5 => x"00", 6 => x"f0", 7 => x"00");
--constant c_id_byte_array : t_byte_array(1 to 10) := (1 => x"52", 2 => x"08", 3 => x"01", 4 => x"00", 5 => x"00", 6 => x"f0", 7 => x"00", 8 => x"00", 9 => X"00", 10 => X"00");
--
type t_var_response is (produce, consume, reset);
type t_var_record is record
response : t_var_response;
hexvalue : std_logic_vector(7 downto 0);
var : t_var;
base_add : std_logic_vector(9 downto 0);
array_length : integer; --! -1 represents a variable length
byte_array : t_byte_array(0 to 15);
end record;
--
type t_var_array is array (natural range <>) of t_var_record;
constant c_var_length_add : integer := 2;
constant c_pdu_byte_add : integer := 1;
constant c_cons_byte_add : integer := 6;
constant c_model_byte_add : integer := 7;
constant c_var_presence_pos : integer := 0;
constant c_var_identification_pos : integer := 1;
constant c_var_var3_pos : integer := 2;
constant c_var_var1_pos : integer := 3;
constant c_var_var2_pos : integer := 4;
constant c_var_reset_pos : integer := 5;
constant c_byte_0_add : integer := 2;
constant c_byte_1_add : integer := 3;
constant c_var_array : t_var_array(0 to 5):=
(c_var_presence_pos => (var => c_st_var_presence,
hexvalue => x"14",
response => produce,
base_add => "----------",
array_length => 7,
byte_array => (0 => x"50", 1 => x"05", 2 => x"80", 3 => x"03", 4 => x"00",
5 => x"f0", 6 => x"00", others => x"ff")),
c_var_identification_pos => (var => c_st_var_identification,
hexvalue => x"10",
response => produce,
array_length => 10,
base_add => "----------",
byte_array => (0 => x"52", 1 => x"08", 2 => x"01", 3 => x"00", 4 => x"00",
5 => x"f0", 6 => x"00", 7 => x"00", 8 => X"00", 9 => X"00",
others => x"ff")),
c_var_var3_pos => (var => c_st_var_3,
hexvalue => x"06",
response => produce,
base_add => "0000000000",
array_length => 1,
byte_array => (0 => x"40", others => x"ff")),
c_var_var1_pos => (var => c_st_var_1,
hexvalue => x"05",
response => consume,
base_add => "0000000000",
array_length => 7,
byte_array => (0 => x"50", 1 => x"05", 2 => x"80", 3 => x"03", 4 => x"00",
5 => x"f0", 6 => x"00", others => x"ff")),
c_var_var2_pos => (var => c_st_var_2,
hexvalue => x"04",
response => consume,
base_add => "0100000000",
array_length => 1,
byte_array => (0 => x"40", others => x"ff")),
c_var_reset_pos => (var => c_st_var_reset,
hexvalue => x"e0",
response => reset,
base_add => "0100000000",
array_length => 1,
byte_array => (0 => x"40", others => x"ff")));
function calc_data_length(var : t_var;
p3_length : std_logic_vector(2 downto 0);
nostat : std_logic;
slone : std_logic) return std_logic_vector;
component wf_rx_osc
generic (C_OSC_LENGTH : integer := 20;
C_QUARTZ_PERIOD : real := 25.0;
C_CLKFCDLENTGTH : natural := 3
);
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
d_edge_i : in std_logic;
load_phase_i : in std_logic;
--! Bit rate \n
--! 00: 31.25 kbit/s => 62.5 KHz \n
--! 01: 1 Mbit/s => 2 MHz \n
--! 10: 2.5 Mbit/s => 5 MHz \n
--! 11: reserved, do not use
rate_i : in std_logic_vector (1 downto 0); --! Bit rate
clk_fixed_carrier_p_o : out std_logic;
clk_fixed_carrier_p_d_o : out std_logic_vector(C_CLKFCDLENTGTH -1 downto 0);
clk_fixed_carrier_o : out std_logic;
clk_carrier_p_o : out std_logic;
clk_carrier_180_p_o : out std_logic;
clk_bit_p_o : out std_logic;
clk_bit_90_p_o : out std_logic;
clk_bit_180_p_o : out std_logic;
clk_bit_270_p_o : out std_logic;
edge_window_o : out std_logic;
edge_180_window_o : out std_logic;
phase_o : out std_logic_vector(C_OSC_LENGTH -1 downto 0)
);
end component wf_rx_osc;
component wf_crc
generic(
c_poly_length : natural := 16);
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
start_p_i : in std_logic;
d_i : in std_logic;
d_rdy_p_i : in std_logic;
data_fcs_sel_n : in std_logic;
crc_o : out std_logic_vector(c_poly_length - 1 downto 0);
crc_rdy_p_o : out std_logic;
crc_ok_p : out std_logic
);
end component wf_crc;
component deglitcher
Generic (C_ACULENGTH : integer := 10);
Port ( uclk_i : in STD_LOGIC;
d_i : in STD_LOGIC;
d_o : out STD_LOGIC;
carrier_p_i : in STD_LOGIC;
d_ready_p_o : out STD_LOGIC);
end component deglitcher;
component wf_rx
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
byte_ready_p_o : out std_logic;
byte_o : out std_logic_vector(7 downto 0);
last_byte_p_o : out std_logic;
fss_decoded_p_o : out std_logic;
crc_ok_p_o : out std_logic;
d_re_i : in std_logic;
d_fe_i : in std_logic;
d_filtered_i : in std_logic;
s_d_ready_p_i : in std_logic;
load_phase_o : out std_logic;
clk_bit_180_p_i : in std_logic;
edge_window_i : in std_logic;
edge_180_window_i : in std_logic
);
end component wf_rx;
component wf_tx
generic(
C_CLKFCDLENTGTH : natural := 3 );
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
start_send_p_i : in std_logic;
request_byte_p_o : out std_logic;
byte_ready_p_i : in std_logic; -- byte_ready_p_i is not used
byte_i : in std_logic_vector(7 downto 0);
last_byte_p_i : in std_logic;
-- clk_fixed_carrier_p_d_i(0) : in std_logic;
clk_fixed_carrier_p_d_i : in std_logic_vector(C_CLKFCDLENTGTH -1 downto 0);
d_o : out std_logic;
d_e_o : out std_logic
);
end component wf_tx;
component dpblockram
generic (dl : integer := 42; -- Length of the data word
al : integer := 10; -- Size of the addr map (10 = 1024 words)
nw : integer := 1024); -- Number of words
-- 'nw' has to be coherent with 'al'
port (clk : in std_logic; -- Global Clock
we : in std_logic; -- Write Enable
aw : in std_logic_vector(al - 1 downto 0); -- Write Address
ar : in std_logic_vector(al - 1 downto 0); -- Read Address
di : in std_logic_vector(dl - 1 downto 0); -- Data input
dw : out std_logic_vector(dl - 1 downto 0); -- Data write, normaly open
do : out std_logic_vector(dl - 1 downto 0)); -- Data output
end component dpblockram;
component wf_engine_control
generic( C_QUARTZ_PERIOD : real := 25.0);
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
-- Transmiter interface
start_send_p_o : out std_logic;
request_byte_p_i : in std_logic;
byte_ready_p_o : out std_logic;
-- byte_o : out std_logic_vector(7 downto 0);
last_byte_p_o : out std_logic;
-- Receiver interface
fss_decoded_p_i : in std_logic; -- The frame decoder has detected the start of a frame
byte_ready_p_i : in std_logic; -- The frame docoder ouputs a new byte on byte_i
byte_i : in std_logic_vector(7 downto 0); -- Decoded byte
frame_ok_p_i : in std_logic;
-- Worldfip bit rate
rate_i : in std_logic_vector(1 downto 0);
subs_i : in std_logic_vector (7 downto 0); --! Subscriber number coding.
--! Produced variable data length \n
--! 000: 2 Bytes \n
--! 001: 8 Bytes \n
--! 010: 16 Bytes \n
--! 011: 32 Bytes \n
--! 100: 64 Bytes \n
--! 101: 124 Bytes \n
--! 110: reserved, do not use \n
--! 111: reserved, do not use \n
--! Actual size: +1 NanoFIP Status byte +1 MPS Status byte (last transmitted)
--! Note: when SLONE=Vcc, p3_lgth_i should be set to 000.
p3_lgth_i : in std_logic_vector (2 downto 0); --! Produced variable data length
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
--! No NanoFIP status transmission
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
nostat_i : in std_logic; --! No NanoFIP status transmission
-------------------------------------------------------------------------------
-- USER INTERFACE, non WISHBONE
-------------------------------------------------------------------------------
--! Signals new data is received and can safely be read (Consumed
--! variable 05xyh). In stand-alone mode one may sample the data on the
--! first clock edge VAR1_RDY is high.
var1_rdy_o: out std_logic; --! Variable 1 ready
--! Signals new data is received and can safely be read (Consumed
--! broadcast variable 04xyh). In stand-alone mode one may sample the
--! data on the first clock edge VAR1_RDY is high.
var2_rdy_o: out std_logic; --! Variable 2 ready
--! Signals that the variable can safely be written (Produced variable
--! 06xyh). In stand-alone mode, data is sampled on the first clock after
--! VAR_RDY is deasserted.
var3_rdy_o: out std_logic; --! Variable 3 ready
-- prod_byte_i : in std_logic_vector(7 downto 0);
var_o : out t_var;
append_status_o : out std_logic;
add_offset_o : out std_logic_vector(6 downto 0);
data_length_o : out std_logic_vector(6 downto 0);
cons_byte_we_p_o : out std_logic
);
end component wf_engine_control;
component wf_consumed_vars
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
byte_ready_p_i : in std_logic;
var_i : in t_var;
-- append_status_i : in std_logic;
add_offset_i : in std_logic_vector(6 downto 0);
-- data_length_i : in std_logic_vector(6 downto 0);
byte_i : in std_logic_vector(7 downto 0);
-------------------------------------------------------------------------------
--! USER INTERFACE. Data and address lines synchronized with uclk_i
-------------------------------------------------------------------------------
-- dat_i : in std_logic_vector (15 downto 0); --!
dat_o : out std_logic_vector (15 downto 0); --!
adr_i : in std_logic_vector ( 9 downto 0) --!
-- stb_p_i : in std_logic; --! Strobe
-- ack_p_o : out std_logic; --! Acknowledge
-- we_p_i : in std_logic --! Write enable
);
end component wf_consumed_vars;
component wf_produced_vars is
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
--! Identification selection (see M_ID, C_ID)
-- s_id_o : out std_logic_vector (1 downto 0); --! Identification selection
--! Identification variable settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! M_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Model [2*i] 0 1 0 1 \n
--! Model [2*i+1] 0 0 1 1
m_id_i : in std_logic_vector (3 downto 0); --! Model identification settings
--! Constructor identification settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! C_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Constructor[2*i] 0 1 0 1 \n
--! Constructor[2*i+1] 0 0 1 1
c_id_i : in std_logic_vector (3 downto 0); --! Constructor identification settings
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
--! No NanoFIP status transmission
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
nostat_i : in std_logic; --! No NanoFIP status transmission
stat_i : in std_logic_vector(7 downto 0); -- NanoFIP status
-- prod_byte_i : in std_logic_vector(7 downto 0);
var_i : in t_var;
append_status_i : in std_logic;
add_offset_i : in std_logic_vector(6 downto 0);
data_length_i : in std_logic_vector(6 downto 0);
byte_o : out std_logic_vector(7 downto 0);
-------------------------------------------------------------------------------
--! USER INTERFACE. Data and address lines synchronized with uclk_i
-------------------------------------------------------------------------------
dat_i : in std_logic_vector (15 downto 0); --!
-- dat_o : out std_logic_vector (15 downto 0); --!
adr_i : in std_logic_vector ( 9 downto 0); --!
-- stb_p_i : in std_logic; --! Strobe
-- ack_p_o : out std_logic; --! Acknowledge
we_p_i : in std_logic --! Write enable
);
end component wf_produced_vars;
component wf_tx_rx
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
start_send_p_i : in std_logic;
request_byte_p_o : out std_logic;
byte_ready_p_i : in std_logic;
byte_i : in std_logic_vector(7 downto 0);
last_byte_p_i : in std_logic;
-- clk_fixed_carrier_p_o : out std_logic;
d_o : out std_logic;
d_e_o : out std_logic;
d_clk_o : out std_logic;
d_a_i : in std_logic;
rate_i : in std_logic_vector(1 downto 0);
byte_ready_p_o : out std_logic;
byte_o : out std_logic_vector(7 downto 0);
last_byte_p_o : out std_logic;
fss_decoded_p_o : out std_logic;
crc_ok_p_o : out std_logic
);
end component wf_tx_rx;
component nanofip
port (
-------------------------------------------------------------------------------
-- WorldFIP settings
-------------------------------------------------------------------------------
--! Bit rate \n
--! 00: 31.25 kbit/s \n
--! 01: 1 Mbit/s \n
--! 10: 2.5 Mbit/s \n
--! 11: reserved, do not use
rate_i : in std_logic_vector (1 downto 0); --! Bit rate
--! Subscriber number coding. Station address.
subs_i : in std_logic_vector (7 downto 0); --! Subscriber number coding.
--! Identification selection (see M_ID, C_ID)
s_id_o : out std_logic_vector (1 downto 0); --! Identification selection
--! Identification variable settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! M_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Model [2*i] 0 1 0 1 \n
--! Model [2*i+1] 0 0 1 1
m_id_i : in std_logic_vector (3 downto 0); --! Model identification settings
--! Constructor identification settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! C_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Constructor[2*i] 0 1 0 1 \n
--! Constructor[2*i+1] 0 0 1 1
c_id_i : in std_logic_vector (3 downto 0); --! Constructor identification settings
--! Produced variable data length \n
--! 000: 2 Bytes \n
--! 001: 8 Bytes \n
--! 010: 16 Bytes \n
--! 011: 32 Bytes \n
--! 100: 64 Bytes \n
--! 101: 124 Bytes \n
--! 110: reserved, do not use \n
--! 111: reserved, do not use \n
--! Actual size: +1 NanoFIP Status byte +1 MPS Status byte (last transmitted)
--! Note: when SLONE=Vcc, p3_lgth_i should be set to 000.
p3_lgth_i : in std_logic_vector (2 downto 0); --! Produced variable data length
-------------------------------------------------------------------------------
-- FIELDRIVE connections
-------------------------------------------------------------------------------
fd_rstn_o : out std_logic; --! Initialisation control, active low
fd_wdgn_i : in std_logic; --! Watchdog on transmitter
fd_txer_i : in std_logic; --! Transmitter error
fd_txena_o: out std_logic; --! Transmitter enable
fd_txck_o : out std_logic; --! Line driver half bit clock
fx_txd_o : out std_logic; --! Transmitter data
fx_rxa_i : in std_logic; --! Reception activity detection
fx_rxd_i : in std_logic; --! Receiver data
-------------------------------------------------------------------------------
-- USER INTERFACE, General signals
-------------------------------------------------------------------------------
uclk_i : in std_logic; --! 40 MHz clock
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
--! No NanoFIP status transmission
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
nostat_i : in std_logic; --! No NanoFIP status transmission
rstin_i : in std_logic; --! Initialisation control, active low
--! Reset output, active low. Active when the reset variable is received
--! and the second byte contains the station address.
rston_o : out std_logic; --! Reset output, active low
-------------------------------------------------------------------------------
-- USER INTERFACE, non WISHBONE
-------------------------------------------------------------------------------
--! Signals new data is received and can safely be read (Consumed
--! variable 05xyh). In stand-alone mode one may sample the data on the
--! first clock edge VAR1_RDY is high.
var1_rdy_o: out std_logic; --! Variable 1 ready
--! Signals that the user logic is accessing variable 1. Only used to
--! generate a status that verifies that VAR1_RDY was high when
--! accessing. May be grounded.
var1_acc_i: in std_logic; --! Variable 1 access
--! Signals new data is received and can safely be read (Consumed
--! broadcast variable 04xyh). In stand-alone mode one may sample the
--! data on the first clock edge VAR1_RDY is high.
var2_rdy_o: out std_logic; --! Variable 2 ready
--! Signals that the user logic is accessing variable 2. Only used to
--! generate a status that verifies that VAR2_RDY was high when
--! accessing. May be grounded.
var2_acc_i: in std_logic; --! Variable 2 access
--! Signals that the variable can safely be written (Produced variable
--! 06xyh). In stand-alone mode, data is sampled on the first clock after
--! VAR_RDY is deasserted.
var3_rdy_o: out std_logic; --! Variable 3 ready
--! Signals that the user logic is accessing variable 3. Only used to
--! generate a status that verifies that VAR3_RDY was high when
--! accessing. May be grounded.
var3_acc_i: in std_logic; --! Variable 3 access
-------------------------------------------------------------------------------
-- USER INTERFACE, WISHBONE SLAVE
-------------------------------------------------------------------------------
wclk_i : in std_logic; --! Wishbone clock. May be independent of UCLK.
--! Data in. Wishbone access only on bits 7-0. Bits 15-8 only used
--! in stand-alone mode.
dat_i : in std_logic_vector (15 downto 0); --! Data in
--! Data out. Wishbone access only on bits 7-0. Bits 15-8 only used
--! in stand-alone mode.
dat_o : out std_logic_vector (15 downto 0); --! Data out
-- dat_i : in std_logic_vector(15 downto 0);
adr_i : in std_logic_vector ( 9 downto 0); --! Address
rst_i : in std_logic; --! Wishbone reset. Does not reset other internal logic.
stb_i : in std_logic; --! Strobe
ack_o : out std_logic; --! Acknowledge
we_i : in std_logic --! Write enable
);
end component nanofip;
end wf_package;
package body wf_package is
function calc_data_length(var : t_var;
p3_length : std_logic_vector(2 downto 0);
nostat : std_logic;
slone : std_logic) return std_logic_vector is
variable v_nostat : std_logic_vector(1 downto 0);
variable v_p3_length_decoded, v_data_length: unsigned(7 downto 0);
begin
v_nostat := ('0'& ((not nostat) and (not slone)));
v_p3_length_decoded := to_unsigned(c_p3_var_length_table(to_integer(unsigned(p3_length))), v_p3_length_decoded'length);
v_data_length := to_unsigned(0,v_data_length'length);
case var is
when c_st_var_presence =>
v_data_length := to_unsigned(6,v_data_length'length);
when c_st_var_identification =>
v_data_length := to_unsigned(9,v_data_length'length);
when c_st_var_1 =>
when c_st_var_2 =>
when c_st_var_3 =>
if nostat = '1' then
v_data_length := to_unsigned(3,v_data_length'length);
else
v_data_length := v_p3_length_decoded + unsigned(v_nostat) ;
end if;
when c_st_var_reset =>
when others =>
end case;
return std_logic_vector(v_data_length);
end;
end wf_package;
--===========================================================================
--! @file wf_produced_vars.vhd
--! @brief Nanofip control unit
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
use work.wf_package.all;
-------------------------------------------------------------------------------
-- --
-- wf_produced_vars --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_produced_vars
--
--! @brief Nanofip control unit. It provides with a transparent interface between the wf_control state machine and the RAM and special \n
--! variable bytes not stored in RAM. wf_wishbone has write access and wf_control read access.\n
--!
--! @author Pablo Alvarez Sanchez (pablo.alvarez.sanchez@cern.ch)
--
--! @date 11/09/2009
--!
--! @version v0.01
--!
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_package \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author:
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 11/09/2009 v0.01 EB First version \n
--!
-------------------------------------------------------------------------------
--! @todo
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_produced_vars
--============================================================================
entity wf_produced_vars is
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
--! Identification selection (see M_ID, C_ID)
-- s_id_o : out std_logic_vector (1 downto 0); --! Identification selection
--! Identification variable settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! M_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Model [2*i] 0 1 0 1 \n
--! Model [2*i+1] 0 0 1 1
m_id_i : in std_logic_vector (3 downto 0); --! Model identification settings
--! Constructor identification settings.
--! Connect the ID inputs either to Gnd, Vcc, S_ID[0] or S_ID[1] to
--! obtain different values for the Model data (i=0,1,2,3).\n
--! C_ID[i] connected to: Gnd S_ID0 SID1 Vcc \n
--! Constructor[2*i] 0 1 0 1 \n
--! Constructor[2*i+1] 0 0 1 1
c_id_i : in std_logic_vector (3 downto 0); --! Constructor identification settings
--! Stand-alone mode
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
slone_i : in std_logic; --! Stand-alone mode
--! No NanoFIP status transmission
--! If connected to Vcc, disables sending of NanoFIP status together with
--! the produced data.
nostat_i : in std_logic; --! No NanoFIP status transmission
stat_i : in std_logic_vector(7 downto 0); -- NanoFIP status
-- prod_byte_i : in std_logic_vector(7 downto 0);
var_i : in t_var;
append_status_i : in std_logic;
add_offset_i : in std_logic_vector(6 downto 0);
data_length_i : in std_logic_vector(6 downto 0);
byte_o : out std_logic_vector(7 downto 0);
-------------------------------------------------------------------------------
--! USER INTERFACE. Data and address lines synchronized with uclk_i
-------------------------------------------------------------------------------
dat_i : in std_logic_vector (15 downto 0); --!
-- dat_o : out std_logic_vector (15 downto 0); --!
adr_i : in std_logic_vector ( 9 downto 0); --!
-- stb_p_i : in std_logic; --! Strobe
-- ack_p_o : out std_logic; --! Acknowledge
we_p_i : in std_logic --! Write enable
);
end entity wf_produced_vars;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_produced_vars
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_produced_vars is
constant c_presence_pos : natural := 0;
constant c_identification_pos : natural := 1;
constant c_mem_pos : natural := 2;
constant c_last_pos : natural := 2;
signal s_byte: std_logic_vector(7 downto 0);
signal s_mem_byte : std_logic_vector(7 downto 0);
signal s_io_byte : std_logic_vector(7 downto 0);
signal base_add, add: std_logic_vector(9 downto 0);
begin
production_dpram : dpblockram
generic map(dl => 8, -- Length of the data word
al => 7, -- Size of the addr map (10 = 1024 words)
nw => 2**7) -- Number of words
-- 'nw' has to be coherent with 'al'
port map(clk => uclk_i, -- Global Clock
we => we_p_i, -- Write Enable
aw => adr_i(6 downto 0), -- Write Address
ar => add(6 downto 0), -- Read Address
di => dat_i(7 downto 0), -- Data input
dw => open, -- Data write, normaly open
do => s_mem_byte); -- Data output
-- For the moment there is only one variable produced, but I think it is nice to have
-- defined an offset for every variable in case we produce more variables in the future
add <= std_logic_vector(unsigned(add_offset_i) + unsigned(base_add));
process(s_mem_byte, var_i, add_offset_i, s_io_byte, data_length_i, append_status_i, stat_i, slone_i, c_id_i, m_id_i)
begin
s_byte <= (others => '0');
base_add <= (others => '0');
for I in c_var_array'range loop
if (c_var_array(I).response = produce) then
if c_var_array(I).var = var_i then
base_add <= c_var_array(I).base_add;
if c_var_array(I).var = c_st_var_identification then
if unsigned(add_offset_i) = c_cons_byte_add then
s_byte(c_id_i'range) <= c_id_i;
exit;
elsif unsigned(add_offset_i) = c_model_byte_add then
s_byte(m_id_i'range) <= m_id_i;
exit;
end if;
end if;
if unsigned(add_offset_i) = c_pdu_byte_add then
s_byte <= c_var_array(I).byte_array(to_integer(unsigned(add_offset_i(3 downto 0))));
elsif unsigned(add_offset_i) = c_var_length_add then
s_byte(data_length_i'range) <= data_length_i;
elsif (unsigned(add_offset_i) = unsigned(data_length_i)) and append_status_i = '1' then
s_byte <= stat_i;
elsif unsigned(add_offset_i) < c_var_array(I).array_length then
s_byte <= s_mem_byte;
elsif slone_i = '1' then
s_byte <= s_io_byte;
else
s_byte <= c_var_array(I).byte_array(to_integer(unsigned(add_offset_i(3 downto 0))));
end if;
exit;
end if;
end if;
end loop;
end process;
s_io_byte <= dat_i(15 downto 8) when add_offset_i(0) = '1' else dat_i(7 downto 0);
byte_o <= s_byte;
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file wf_rx.vhd
--! @brief Deserialises the WorldFIP data
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
use work.wf_package.all;
-------------------------------------------------------------------------------
-- --
-- wf_rx --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_rx
--
--! @brief Serialises and deserialises the WorldFIP data.
--!
--! Used in the NanoFIP design. \n
--! This unit serializes the data.
--!
--!
--! @author Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
--!
--! @date 10/08/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_engine \n
--! tx_engine \n
--! clk_gen \n
--! reset_logic \n
--! consumed_ram \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Erik van der Bij
--! Pablo Alvarez Sanchez
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 07/08/2009 v0.02 PAAS Entity Ports added, start of architecture content
--!
-------------------------------------------------------------------------------
--! @todo Define I/O signals \n
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_tx
--============================================================================
entity wf_rx is
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
byte_ready_p_o : out std_logic;
byte_o : out std_logic_vector(7 downto 0);
last_byte_p_o : out std_logic;
fss_decoded_p_o : out std_logic;
crc_ok_p_o : out std_logic;
d_re_i : in std_logic;
d_fe_i : in std_logic;
d_filtered_i : in std_logic;
s_d_ready_p_i : in std_logic;
load_phase_o : out std_logic;
clk_bit_180_p_i : in std_logic;
edge_window_i : in std_logic;
edge_180_window_i : in std_logic
);
end entity wf_rx;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_tx_rx
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_rx is
constant ONE : std_logic_vector(1 downto 0) := "10";
constant ZERO : std_logic_vector(1 downto 0) := "01";
constant VP : std_logic_vector(1 downto 0) := "11";
constant VN : std_logic_vector(1 downto 0) := "00";
constant PREAMBLE : std_logic_vector(15 downto 0) := ONE&ZERO&ONE&ZERO&ONE&ZERO&ONE&ZERO;
constant FRAME_START : std_logic_vector(15 downto 0) := ONE&VP&VN&ONE&ZERO&VN&VP&ZERO;
--constant HEADER : std_logic_vector(31 downto 0) := PREAMBLE&FRAME_START;
constant QUEUE : std_logic_vector(15 downto 0) := ONE&VP&VN&VP&VN&ONE&ZERO&ONE;
--constant C_PATTERNS : std_logic_vector(45 downto 0) := HEADER&QUEUE;
--constant RP_DAT : std_logic_vector(11 downto 0) := ZERO&ONE&ZERO&ZERO&ZERO&ZERO;
type rx_st_t is (w_1,w_2,w_3,w_4, w_frame_start, w_byte);
signal rx_st, nx_rx_st : rx_st_t;
signal pointer, s_start_pointer : unsigned(3 downto 0);
signal s_inc_pointer : std_logic;
signal s_re_edge_on_phase, s_fe_edge_on_phase, s_edge_not_on_phase: std_logic;
signal s_re_edge_180_on_phase : std_logic;
signal s_clk_bit_180_p_d : std_logic;
signal s_code_violation : std_logic;
signal s_frame_start_bit : std_logic;
signal s_queue_bit : std_logic;
signal s_good_header_bit : std_logic;
--signal s_good_queue_bit : std_logic;
signal s_bad_frame_start_bit : std_logic;
signal s_bad_queue_bit : std_logic;
signal s_last_frame_start_bit : std_logic;
--signal s_last_queue_bit : std_logic;
signal s_pointer_is_zero : std_logic;
--signal s_good_zero : std_logic;
signal s_load_pointer : std_logic;
signal s_byte_ok : std_logic;
signal s_write_bit_to_byte : std_logic;
--signal edge_window_i : std_logic;
signal s_d_filtered_d : std_logic;
signal s_byte : std_logic_vector(7 downto 0);
signal s_good_queue_detected_p, s_good_queue_detected : std_logic;
signal s_crc_ok_p, s_crc_ok, s_start_crc_p : std_logic;
begin
uwf_crc : wf_crc
generic map(
c_poly_length => 16)
port map(
uclk_i => uclk_i, --! User Clock
rst_i => rst_i,
start_p_i => s_start_crc_p,
d_i => s_d_filtered_d,
d_rdy_p_i => s_write_bit_to_byte,
data_fcs_sel_n => '1',
crc_o => open,
crc_rdy_p_o => open,
crc_ok_p => s_crc_ok_p
);
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
rx_st <= w_1;
else
rx_st <= nx_rx_st;
end if;
end if;
end process;
process(rx_st,d_fe_i, s_good_queue_detected_p, s_bad_queue_bit, s_bad_frame_start_bit, d_re_i, s_bad_frame_start_bit, s_fe_edge_on_phase, s_re_edge_on_phase, s_re_edge_180_on_phase, s_edge_not_on_phase, s_last_frame_start_bit, s_code_violation)
begin
nx_rx_st <= w_1;
case rx_st is
--w_x states verify the unfiltered signal timing
when w_1 => -- I start detecting the first one, falling edge
if d_fe_i = '1' then
nx_rx_st <= w_2;
else
nx_rx_st <= w_1;
end if;
when w_2 => -- If there is a zero ,rising edge, then I jump to 3
if s_re_edge_on_phase = '1' then
nx_rx_st <= w_3;
elsif s_edge_not_on_phase = '1' then
nx_rx_st <= w_1;
else
nx_rx_st <= w_2;
end if;
when w_3 => -- I wait for a one (falling edge)
if s_fe_edge_on_phase = '1' then
nx_rx_st <= w_4;
elsif s_edge_not_on_phase = '1' then
nx_rx_st <= w_1;
else
nx_rx_st <= w_3;
end if;
when w_4 => -- If the preamble is still being sent I will detect a zero, re, and jump to w3
-- If the start delimeter is received I will detect a one (fe)
-- Receiveing an edge not in phase means the header is going to be received next
-- Eventually a glitch could be confused with such an event, but the header decoding
-- and CRC should indicate that a bad frame has been decoded
if s_re_edge_180_on_phase = '1' then
nx_rx_st <= w_frame_start ;
elsif s_re_edge_on_phase = '1' then
nx_rx_st <= w_3;
elsif s_fe_edge_on_phase = '1' then
nx_rx_st <= w_1;
elsif s_edge_not_on_phase = '1' then -- In c
nx_rx_st <= w_1;
else
nx_rx_st <= w_4;
end if;
-- w_header and w_byte use the filtered serial data
when w_frame_start =>
if s_last_frame_start_bit = '1' then
nx_rx_st <= w_byte;
elsif s_bad_frame_start_bit = '1' then
nx_rx_st <= w_1;
else
nx_rx_st <= w_frame_start;
end if;
when w_byte =>
if s_good_queue_detected_p = '1' then
nx_rx_st <= w_1;
-- Is there a code violation that does not correspond to the queue pattern?
elsif s_bad_queue_bit = '1' and s_code_violation = '1' then
nx_rx_st <= w_1;
else
nx_rx_st <= w_byte;
end if;
when others =>
nx_rx_st <= w_1;
end case;
end process;
process(rx_st, s_last_frame_start_bit, s_good_queue_detected_p, d_re_i, s_pointer_is_zero, s_re_edge_180_on_phase, edge_window_i, s_d_ready_p_i, s_clk_bit_180_p_d, s_code_violation)
begin
load_phase_o <= '0';
s_inc_pointer <= '0';
s_load_pointer <= '0';
s_byte_ok <= '0';
s_write_bit_to_byte <= '0';
s_start_pointer <= to_unsigned(0,s_start_pointer'length);
s_start_crc_p <= '0';
fss_decoded_p_o <= '0';
case rx_st is
when w_1 =>
load_phase_o <= '1';
when w_2 =>
load_phase_o <= edge_window_i;
when w_3 =>
load_phase_o <= edge_window_i;
when w_4 =>
load_phase_o <= edge_window_i;
s_start_pointer <= to_unsigned(FRAME_START'left-1,s_start_pointer'length);
s_load_pointer <= s_re_edge_180_on_phase;
when w_frame_start =>
load_phase_o <= edge_window_i;
s_inc_pointer <= s_d_ready_p_i;
s_start_pointer <= to_unsigned(QUEUE'left,s_start_pointer'length);
s_load_pointer <= s_pointer_is_zero and s_clk_bit_180_p_d;
s_start_crc_p <= '1';
fss_decoded_p_o <= s_last_frame_start_bit;
when w_byte =>
load_phase_o <= edge_window_i;
s_inc_pointer <= s_d_ready_p_i;
s_write_bit_to_byte <= s_clk_bit_180_p_d;
s_byte_ok <= s_pointer_is_zero and s_clk_bit_180_p_d and (not s_good_queue_detected_p) and (not s_code_violation);
s_start_pointer <= to_unsigned(QUEUE'left,s_start_pointer'length);
s_load_pointer <= s_pointer_is_zero and s_clk_bit_180_p_d;
when others =>
end case;
end process;
s_re_edge_on_phase <= edge_window_i and d_re_i;
s_fe_edge_on_phase <= edge_window_i and d_fe_i;
s_re_edge_180_on_phase <= edge_180_window_i and ( d_re_i);
s_edge_not_on_phase <= (not edge_window_i)and (d_re_i or d_fe_i);
process(uclk_i)
begin
if rising_edge(uclk_i) then
if s_d_ready_p_i = '1' then
s_d_filtered_d <= d_filtered_i;
end if;
s_clk_bit_180_p_d <= clk_bit_180_p_i;
end if;
end process;
s_code_violation <= (not(s_d_filtered_d xor d_filtered_i)) and s_clk_bit_180_p_d;
--s_good_zero <= (s_d_filtered_d and (not d_filtered_i)) and s_clk_bit_180_p_d;
s_frame_start_bit <= FRAME_START(to_integer(pointer));
s_queue_bit <= QUEUE(to_integer(resize(pointer,4)));
s_good_header_bit <= (s_frame_start_bit xnor d_filtered_i )and s_d_ready_p_i;
--s_good_queue_bit <= (s_queue_bit xnor d_filtered_i) and s_d_ready_p_i;
s_bad_frame_start_bit <= (s_frame_start_bit xor d_filtered_i )and s_d_ready_p_i;
s_bad_queue_bit <= (s_queue_bit xor d_filtered_i) and s_d_ready_p_i;
s_last_frame_start_bit <= s_pointer_is_zero and s_good_header_bit and s_clk_bit_180_p_d;
--s_last_queue_bit <= s_pointer_is_zero and s_good_queue_detected;
s_good_queue_detected_p <= s_good_queue_detected and s_clk_bit_180_p_d and s_pointer_is_zero;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
s_good_queue_detected <= '1';
elsif s_clk_bit_180_p_d = '1' and s_pointer_is_zero = '1' then
s_good_queue_detected <= '1';
elsif s_bad_queue_bit = '1' then
s_good_queue_detected <= '0';
end if;
end if;
end process;
s_pointer_is_zero <= '1' when pointer = 0 else '0';
process(uclk_i)
begin
if rising_edge(uclk_i) then
if s_load_pointer = '1' then
pointer <= s_start_pointer;
elsif s_inc_pointer = '1' then
pointer <= pointer - 1;
end if;
end if;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if s_write_bit_to_byte = '1' then
s_byte <= s_byte(6 downto 0) & s_d_filtered_d;
end if;
end if;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
s_crc_ok <= '0';
elsif s_byte_ok = '1' then
s_crc_ok <= '0';
elsif s_crc_ok_p = '1' then
s_crc_ok <= '1';
end if;
end if;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
byte_ready_p_o <= '0';
else
byte_ready_p_o <= s_byte_ok and (not s_good_queue_detected_p);
end if;
end if;
end process;
byte_o <= s_byte;
last_byte_p_o <= s_good_queue_detected_p;
crc_ok_p_o <= s_good_queue_detected_p and s_crc_ok;
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file wf_rx_osc.vhd
--! @brief Deserialises the WorldFIP data
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
-------------------------------------------------------------------------------
-- --
-- wf_rx --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_rx_osc
--
--! @brief Numeric oscillator that generates a 1MHz pulse locked to a
--!
--! Used in the NanoFIP design. \n
--! This unit serializes the data.
--!
--!
--! @author Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
--!
--! @date 10/08/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_engine \n
--! tx_engine \n
--! clk_gen \n
--! reset_logic \n
--! consumed_ram \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Erik van der Bij
--! Pablo Alvarez Sanchez
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 07/08/2009 v0.02 PAAS Entity Ports added, start of architecture content
--!
-------------------------------------------------------------------------------
--! @todo Define I/O signals \n
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_rx_osc
--============================================================================
entity wf_rx_osc is
generic (C_OSC_LENGTH : integer := 20;
C_QUARTZ_PERIOD : real := 25.0;
C_CLKFCDLENTGTH : natural := 3
);
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
d_edge_i : in std_logic;
load_phase_i : in std_logic;
--! Bit rate \n
--! 00: 31.25 kbit/s => 62.5 KHz \n
--! 01: 1 Mbit/s => 2 MHz \n
--! 10: 2.5 Mbit/s => 5 MHz \n
--! 11: reserved, do not use
rate_i : in std_logic_vector (1 downto 0); --! Bit rate
clk_fixed_carrier_p_o : out std_logic;
clk_fixed_carrier_p_d_o : out std_logic_vector(C_CLKFCDLENTGTH -1 downto 0);
clk_fixed_carrier_o : out std_logic;
clk_carrier_p_o : out std_logic;
clk_carrier_180_p_o : out std_logic;
clk_bit_p_o : out std_logic;
clk_bit_90_p_o : out std_logic;
clk_bit_180_p_o : out std_logic;
clk_bit_270_p_o : out std_logic;
edge_window_o : out std_logic;
edge_180_window_o : out std_logic;
phase_o : out std_logic_vector(C_OSC_LENGTH -1 downto 0)
);
end entity wf_rx_osc;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_rx_osc
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_rx_osc is
--! Bit rate \n
--! 31.25 kbit => 62.5 KHz carrier \n
constant c_period_31_25kbit : real := (C_QUARTZ_PERIOD*real(2**C_OSC_LENGTH))/32000.0;
--! 1 Mbit/s => 2MHz carrier \n
constant c_period_1_mbit : real := (C_QUARTZ_PERIOD*real(2**C_OSC_LENGTH))/1000.0;
--! 2.5 Mbit/s => 5MHz carrier \n
constant c_period_2_5mbit : real := (C_QUARTZ_PERIOD*real(2**C_OSC_LENGTH))/400.0;
--
--constant c_period_31_25kbit_signed : signed(C_OSC_LENGTH -1 downto 0) := to_signed(integer(c_period_31_25kbit), C_OSC_LENGTH);
-- --! 1 Mbit/s \n
--constant c_period_1_mbit_signed : signed(C_OSC_LENGTH -1 downto 0) := to_signed(integer(c_period_1_mbit), C_OSC_LENGTH);
-- --! 2.5 Mbit/s \n
--constant c_period_2_5mbit_signed : signed(C_OSC_LENGTH -1 downto 0) := to_signed(integer(c_period_2_5mbit), C_OSC_LENGTH);
type t_period is array (Natural range <>) of signed(C_OSC_LENGTH -1 downto 0);
constant C_PERIOD : t_period(3 downto 0) := (0 => to_signed(integer(c_period_31_25kbit), C_OSC_LENGTH),
1 => to_signed(integer(c_period_1_mbit), C_OSC_LENGTH),
2 => to_signed(integer(c_period_2_5mbit), C_OSC_LENGTH),
3 => to_signed(integer(c_period_2_5mbit), C_OSC_LENGTH));
signal s_tag, s_phase, s_free_c : signed(C_OSC_LENGTH -1 downto 0);
signal s_period : signed(C_OSC_LENGTH -1 downto 0);
signal s_nx_clk_bit : std_logic;
signal s_nx_clk_bit_90 : std_logic;
signal s_nx_clk_bit_180 : std_logic;
signal s_nx_clk_bit_270 : std_logic;
signal s_clk_bit : std_logic;
signal s_clk_bit_90 : std_logic;
signal s_clk_bit_180 : std_logic;
signal s_clk_bit_270 : std_logic;
signal s_clk_fixed_carrier, s_nx_clk_fixed_carrier, s_clk_fixed_carrier_p : std_logic;
signal s_clk_fixed_carrier_p_d : std_logic_vector(C_CLKFCDLENTGTH -1 downto 0);
begin
s_period <= C_PERIOD(to_integer(unsigned(rate_i)));
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
s_free_c <= to_signed(0, s_free_c'length);
s_tag <= to_signed(0, s_free_c'length);
s_clk_bit <= '0';
s_clk_bit_90 <= '0';
s_clk_bit_180 <= '0';
s_clk_bit_270 <= '0';
s_clk_fixed_carrier <= '0';
s_clk_fixed_carrier_p_d <= (others => '0');
else
s_free_c <= s_free_c + s_period;
if load_phase_i = '1' and d_edge_i = '1' then
s_tag <= s_free_c;
end if;
s_clk_bit <= s_nx_clk_bit;
s_clk_bit_90 <= s_nx_clk_bit_90;
s_clk_bit_180 <= s_nx_clk_bit_180;
s_clk_bit_270 <= s_nx_clk_bit_270;
s_clk_fixed_carrier <= s_nx_clk_fixed_carrier;
s_clk_fixed_carrier_p_d <=s_clk_fixed_carrier_p_d(s_clk_fixed_carrier_p_d'left -1 downto 0)&s_clk_fixed_carrier_p;
end if;
end if;
end process;
clk_fixed_carrier_o <= s_clk_fixed_carrier;
clk_fixed_carrier_p_d_o <= s_clk_fixed_carrier_p_d;
clk_bit_p_o <= s_nx_clk_bit and (not s_clk_bit);
clk_bit_90_p_o <= s_nx_clk_bit_90 and (not s_clk_bit_90);
clk_bit_180_p_o <= s_nx_clk_bit_180 and (not s_clk_bit_180);
clk_bit_270_p_o <= s_nx_clk_bit_270 and (not s_clk_bit_270);
s_clk_fixed_carrier_p <= s_nx_clk_fixed_carrier and (not s_clk_fixed_carrier);
clk_fixed_carrier_p_o <= s_clk_fixed_carrier_p;
clk_carrier_p_o <= s_nx_clk_bit xor s_clk_bit;
clk_carrier_180_p_o <= s_nx_clk_bit_90 xor s_clk_bit_90;
s_phase <= s_tag - s_free_c;
phase_o <= std_logic_vector(s_phase);
process( s_phase, s_period, s_free_c)
begin
edge_window_o <= '0';
edge_180_window_o <= '1';
s_nx_clk_bit <= '0';
s_nx_clk_bit_90 <= '0';
s_nx_clk_bit_180 <= '0';
s_nx_clk_bit_270 <= '0';
s_nx_clk_fixed_carrier <= '0';
if (signed(s_free_c(s_free_c'left -1 downto 0)) < 0) then
s_nx_clk_fixed_carrier<= '1';
else
s_nx_clk_fixed_carrier <= '0';
end if;
if (s_phase < (4*s_period)) and (s_phase > (-4*s_period)) then
edge_window_o <= '1';
else
edge_window_o <= '0';
end if;
if ((s_phase - 2**(s_phase'length-1)) < (4*s_period)) and ((s_phase - 2**(s_phase'length-1)) > (-4*s_period)) then
edge_180_window_o <= '1';
else
edge_180_window_o <= '0';
end if;
if (s_phase < 0) then
s_nx_clk_bit <= '1';
s_nx_clk_bit_180 <= '0';
else
s_nx_clk_bit <= '0';
s_nx_clk_bit_180 <= '1';
end if;
if ((s_phase - (2**(C_OSC_LENGTH-2))) < 0) then
s_nx_clk_bit_90 <= '0';
s_nx_clk_bit_270 <= '1';
else
s_nx_clk_bit_90 <= '1';
s_nx_clk_bit_270 <= '0';
end if;
end process;
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 14:47:37 08/13/2009
-- Design Name: wf_rx_osc
-- Module Name: C:/ohr/CernFIP/trunk/software/ISE/CernFIP/wf_rx_osc_tb.vhd
-- Project Name: CernFIP
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: wf_rx_osc
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY wf_rx_osc_tb_vhd IS
END wf_rx_osc_tb_vhd;
ARCHITECTURE behavior OF wf_rx_osc_tb_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT wf_rx_osc
PORT(
uclk_i : IN std_logic;
rst_i : IN std_logic;
d_re_i : IN std_logic;
load_phase_i : IN std_logic;
rate_i : IN std_logic_vector(1 downto 0);
clk_carrier_p_o : out std_logic;
clk_carrier_180_p_o : out std_logic;
clk_bit_p_o : OUT std_logic;
clk_bit_90_p_o : OUT std_logic;
clk_bit_180_p_o : OUT std_logic;
clk_bit_270_p_o : OUT std_logic;
edge_window_o : OUT std_logic;
phase_o : OUT std_logic_vector(19 downto 0)
);
END COMPONENT;
--Inputs
SIGNAL uclk_i : std_logic := '0';
SIGNAL rst_i : std_logic := '0';
SIGNAL d_re_i : std_logic := '0';
SIGNAL load_phase_i : std_logic := '0';
SIGNAL rate_i : std_logic_vector(1 downto 0) := (others=>'0');
--Outputs
SIGNAL clk_bit_p_o : std_logic;
SIGNAL clk_bit_90_p_o : std_logic;
SIGNAL clk_bit_180_p_o : std_logic;
SIGNAL clk_bit_270_p_o : std_logic;
SIGNAL edge_window_o : std_logic;
signal clk_carrier_p_o : std_logic;
signal clk_carrier_180_p_o : std_logic;
SIGNAL phase_o : std_logic_vector(19 downto 0);
signal s_bit_period : time;
BEGIN
process
begin
uclk_i <= '0';
wait for 13 ns;
uclk_i <= '1';
wait for 12 ns;
end process;
rst_i <= '0', '1' after 110 ns, '0' after 130 ns;
s_bit_period <= 2 us;
rate_i <= "01";
process
begin
wait for 1 ns;
while true loop
d_re_i <= '0';
wait for s_bit_period - 30 ns;
wait until falling_edge(uclk_i);
d_re_i <= '1';
wait until falling_edge(uclk_i);
end loop;
end process;
load_phase_i <= '0', '1' after 210 ns, '0' after 100030 ns;
-- Instantiate the Unit Under Test (UUT)
uut: wf_rx_osc PORT MAP(
uclk_i => uclk_i,
rst_i => rst_i,
d_re_i => d_re_i,
load_phase_i => load_phase_i,
rate_i => rate_i,
clk_carrier_p_o => clk_carrier_p_o,
clk_carrier_180_p_o => clk_carrier_180_p_o,
clk_bit_p_o => clk_bit_p_o,
clk_bit_90_p_o => clk_bit_90_p_o,
clk_bit_180_p_o => clk_bit_180_p_o,
clk_bit_270_p_o => clk_bit_270_p_o,
edge_window_o => edge_window_o,
phase_o => phase_o
);
-- tb : PROCESS
-- BEGIN
--
-- -- Wait 100 ns for global reset to finish
-- wait for 100 ns;
--
-- -- Place stimulus here
--
-- wait; -- will wait forever
-- END PROCESS;
END;
--------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 17:42:52 08/14/2009
-- Design Name: wf_rx
-- Module Name: C:/ohr/CernFIP/trunk/hdl/design/wf_rx_tb.vhd
-- Project Name: CernFIP
-- Target Device:
-- Tool versions:
-- Description:
--
-- VHDL Test Bench Created by ISE for module: wf_rx
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes:
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test. Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY wf_rx_tb_vhd IS
END wf_rx_tb_vhd;
ARCHITECTURE behavior OF wf_rx_tb_vhd IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT wf_rx
PORT(
uclk_i : IN std_logic;
rst_i : IN std_logic;
d_a_i : IN std_logic;
rate_i : IN std_logic_vector(1 downto 0);
start_send_p_i : IN std_logic;
byte_ready_p_i : IN std_logic;
byte_i : IN std_logic_vector(7 downto 0);
last_byte_i : IN std_logic;
request_byte_p_o : OUT std_logic;
send_ended_p_o : OUT std_logic;
bit_strobe_p_o : OUT std_logic;
data_o : OUT std_logic_vector(7 downto 0);
data_e_o : OUT std_logic
);
END COMPONENT;
--Inputs
SIGNAL uclk_i : std_logic := '0';
SIGNAL rst_i : std_logic := '0';
SIGNAL d_a_i : std_logic := '0';
SIGNAL start_send_p_i : std_logic := '0';
SIGNAL byte_ready_p_i : std_logic := '0';
SIGNAL last_byte_i : std_logic := '0';
SIGNAL rate_i : std_logic_vector(1 downto 0) := (others=>'0');
SIGNAL byte_i : std_logic_vector(7 downto 0) := (others=>'0');
--Outputs
SIGNAL request_byte_p_o : std_logic;
SIGNAL send_ended_p_o : std_logic;
SIGNAL bit_strobe_p_o : std_logic;
SIGNAL data_o : std_logic_vector(7 downto 0);
SIGNAL data_e_o : std_logic;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: wf_rx PORT MAP(
uclk_i => uclk_i,
rst_i => rst_i,
d_a_i => d_a_i,
rate_i => rate_i,
start_send_p_i => start_send_p_i,
request_byte_p_o => request_byte_p_o,
byte_ready_p_i => byte_ready_p_i,
byte_i => byte_i,
last_byte_i => last_byte_i,
send_ended_p_o => send_ended_p_o,
bit_strobe_p_o => bit_strobe_p_o,
data_o => data_o,
data_e_o => data_e_o
);
tb : PROCESS
BEGIN
-- Wait 100 ns for global reset to finish
wait for 100 ns;
-- Place stimulus here
wait; -- will wait forever
END PROCESS;
END;
--===========================================================================
--! @file wf_tx.vhd
--! @brief Serialises and deserialises the WorldFIP data
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
use work.wf_package.all;
-------------------------------------------------------------------------------
-- --
-- wf_tx --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_tx
--
--! @brief Serialises and deserialises the WorldFIP data.
--!
--! Used in the NanoFIP design. \n
--! This unit serializes the data.
--!
--!
--! @author Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
--!
--! @date 10/08/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_engine \n
--! tx_engine \n
--! clk_gen \n
--! reset_logic \n
--! consumed_ram \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Erik van der Bij
--! Pablo Alvarez Sanchez
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 07/08/2009 v0.02 PAAS Entity Ports added, start of architecture content
--!
-------------------------------------------------------------------------------
--! @todo Define I/O signals \n
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_tx_rx
--============================================================================
entity wf_tx is
generic(
C_CLKFCDLENTGTH : natural := 3 );
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
start_send_p_i : in std_logic;
request_byte_p_o : out std_logic;
byte_ready_p_i : in std_logic; -- byte_ready_p_i is not used
byte_i : in std_logic_vector(7 downto 0);
last_byte_p_i : in std_logic;
-- clk_fixed_carrier_p_d_i(0) : in std_logic;
clk_fixed_carrier_p_d_i : in std_logic_vector(C_CLKFCDLENTGTH -1 downto 0);
d_o : out std_logic;
d_e_o : out std_logic
);
end entity wf_tx;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_tx_rx
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_tx is
constant ONE : std_logic_vector(1 downto 0) := "10";
constant ZERO : std_logic_vector(1 downto 0) := "01";
constant VP : std_logic_vector(1 downto 0) := "11";
constant VN : std_logic_vector(1 downto 0) := "00";
constant PREAMBLE : std_logic_vector(15 downto 0) := ONE&ZERO&ONE&ZERO&ONE&ZERO&ONE&ZERO;
constant FRAME_START : std_logic_vector(15 downto 0) := ONE&VP&VN&ONE&ZERO&VN&VP&ZERO;
constant HEADER : std_logic_vector(31 downto 0) := PREAMBLE&FRAME_START;
constant QUEUE : std_logic_vector(15 downto 0) := ONE&VP&VN&VP&VN&ONE&ZERO&ONE;
--constant RP_DAT : std_logic_vector(11 downto 0) := ZERO&ONE&ZERO&ZERO&ZERO&ZERO;
type tx_st_t is (tx_idle, tx_header, tx_byte, tx_last_byte, tx_crc_byte, tx_queue);
signal tx_st, nx_tx_st : tx_st_t;
signal s_pointer, s_top_pointer : unsigned(4 downto 0);
signal s_manchester_byte : std_logic_vector(15 downto 0);
signal s_reset_pointer, s_inc_pointer, s_pointer_is_zero, s_pointer_is_one : std_logic;
signal s_nx_data, s_nx_data_e : std_logic;
signal s_byte : std_logic_vector(7 downto 0);
signal s_d_to_crc_rdy_p : std_logic;
signal s_crc : std_logic_vector(15 downto 0);
signal s_manchester_crc : std_logic_vector(31 downto 0);
signal s_start_crc_p : std_logic;
signal s_calc_crc, s_nx_data_to_crc : std_logic;
begin
uwf_crc : wf_crc
generic map(
c_poly_length => 16)
port map(
uclk_i => uclk_i, --! User Clock
rst_i => rst_i,
start_p_i => s_start_crc_p,
d_i => s_nx_data_to_crc,
d_rdy_p_i => s_d_to_crc_rdy_p,
data_fcs_sel_n => s_calc_crc,
crc_o => s_crc,
crc_rdy_p_o => open,
crc_ok_p => open
);
s_nx_data_to_crc <= s_calc_crc and s_nx_data;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if byte_ready_p_i = '1' then
s_byte <= byte_i;
end if;
end if;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if rst_i = '1' then
tx_st <= tx_idle;
else
tx_st <= nx_tx_st;
end if;
end if;
end process;
process(tx_st, last_byte_p_i, s_pointer_is_zero, start_send_p_i, clk_fixed_carrier_p_d_i)
begin
nx_tx_st <= tx_idle;
case tx_st is
when tx_idle => if start_send_p_i = '1' then
nx_tx_st <= tx_header;
else
nx_tx_st <= tx_idle;
end if;
when tx_header => if s_pointer_is_zero = '1' and clk_fixed_carrier_p_d_i(2) = '1' then
nx_tx_st <= tx_byte;
else
nx_tx_st <= tx_header;
end if;
when tx_byte => if last_byte_p_i = '1' then
nx_tx_st <= tx_last_byte;
else
nx_tx_st <= tx_byte;
end if;
when tx_last_byte => if s_pointer_is_zero = '1' and clk_fixed_carrier_p_d_i(1) = '1' then
nx_tx_st <= tx_crc_byte;
else
nx_tx_st <= tx_last_byte;
end if;
when tx_crc_byte => if s_pointer_is_zero = '1' and clk_fixed_carrier_p_d_i(1) = '1' then
nx_tx_st <= tx_queue;
else
nx_tx_st <= tx_crc_byte;
end if;
when tx_queue => if s_pointer_is_zero = '1' and clk_fixed_carrier_p_d_i(1) = '1' then
nx_tx_st <= tx_idle;
else
nx_tx_st <= tx_queue;
end if;
when others =>
nx_tx_st <= tx_idle;
end case;
end process;
process(tx_st, s_pointer_is_zero, s_pointer, s_manchester_crc, clk_fixed_carrier_p_d_i, s_manchester_byte)
begin
s_top_pointer <= to_unsigned(0,s_pointer'length);
s_reset_pointer <= '0';
s_inc_pointer <= '0';
s_nx_data <= '0';
s_nx_data_e <= '0';
request_byte_p_o <= '0';
s_d_to_crc_rdy_p <= '0';
s_start_crc_p <= '0';
s_calc_crc <= '0';
case tx_st is
when tx_idle =>
s_top_pointer <= to_unsigned(HEADER'length-1,s_pointer'length);
s_reset_pointer <= '1';
when tx_header =>
s_reset_pointer <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(2);
s_inc_pointer <= clk_fixed_carrier_p_d_i(2);
s_nx_data <= HEADER(to_integer(s_pointer));
s_nx_data_e <= '1';
s_top_pointer <= to_unsigned(15,s_pointer'length);
s_start_crc_p <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(2);
when tx_byte =>
request_byte_p_o <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(0);
s_inc_pointer <= clk_fixed_carrier_p_d_i(2);
s_nx_data <= s_manchester_byte(to_integer(resize(s_pointer,4)));
s_nx_data_e <= '1';
s_d_to_crc_rdy_p <= clk_fixed_carrier_p_d_i(2) and s_pointer(0);
s_top_pointer <= to_unsigned(QUEUE'length-1,s_pointer'length);
s_reset_pointer <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(2);
s_calc_crc <= '1';
when tx_last_byte =>
request_byte_p_o <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(0);
s_inc_pointer <= clk_fixed_carrier_p_d_i(2);
s_nx_data <= s_manchester_byte(to_integer(resize(s_pointer,4)));
s_nx_data_e <= '1';
s_d_to_crc_rdy_p <= clk_fixed_carrier_p_d_i(2) and s_pointer(0);
s_reset_pointer <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(2);
s_top_pointer <= to_unsigned(QUEUE'length-1,s_pointer'length);
s_calc_crc <= '1';
when tx_crc_byte =>
-- I enable the crc shift register at the bit boundaries by
-- inverting s_pointer(0)
-- s_d_to_crc_rdy_p <= clk_fixed_carrier_p_d_i(2) and (not s_pointer(0));
s_inc_pointer <= clk_fixed_carrier_p_d_i(2);
s_nx_data <= s_manchester_crc(to_integer(resize(s_pointer,4)));
-- s_nx_data <= (not s_crc(s_crc'left)) xor ( s_pointer(0)); -- s_crc(s_crc'left) is xored with s_pointer(0) to mimic
-- a manchester encoder
s_nx_data_e <= '1';
s_reset_pointer <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(2);
s_top_pointer <= to_unsigned(s_manchester_crc'length-1,s_pointer'length);
when tx_queue =>
s_top_pointer <= to_unsigned(QUEUE'length-1,s_pointer'length);
s_reset_pointer <= s_pointer_is_zero and clk_fixed_carrier_p_d_i(2);
s_inc_pointer <= clk_fixed_carrier_p_d_i(2);
s_nx_data <= QUEUE(to_integer(resize(s_pointer,4)));
s_nx_data_e <= '1';
when others =>
end case;
end process;
process(s_byte)
begin
for I in byte_i'range loop
s_manchester_byte(I*2) <= not s_byte(I);
s_manchester_byte(I*2+1) <= s_byte(I);
end loop;
end process;
process(s_crc)
begin
for I in s_crc'range loop
s_manchester_crc(I*2) <= not s_crc(I);
s_manchester_crc(I*2+1) <= s_crc(I);
end loop;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if clk_fixed_carrier_p_d_i(0) = '1' then
d_o <= s_nx_data;
end if;
d_e_o <= s_nx_data_e;
end if;
end process;
process(uclk_i)
begin
if rising_edge(uclk_i) then
if s_reset_pointer = '1' then
s_pointer <= s_top_pointer;
elsif s_inc_pointer = '1' then
s_pointer <= s_pointer - 1;
end if;
end if;
end process;
s_pointer_is_zero <= '1' when s_pointer = to_unsigned(0,s_pointer'length) else '0';
s_pointer_is_one <= '1' when s_pointer = to_unsigned(1,s_pointer'length) else '0';
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file wf_tx_rx.vhd
--! @brief Serialises and deserialises the WorldFIP data
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
-------------------------------------------------------------------------------
-- --
-- wf_tx_rx --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_tx_rx
--
--! @brief Serialises and deserialises the WorldFIP data.
--!
--! Used in the NanoFIP design. \n
--! On reception it depacketises the data and only presents the actual data
--! contents. It also verifies the FCS (Frame Checksum, CRC).\n
--! On transmission it packetises the data and adds the FCS.
--!
--!
--! @author Erik van der Bij (Erik.van.der.Bij@cern.ch)
--
--! @date 07/07/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_engine \n
--! tx_engine \n
--! clk_gen \n
--! reset_logic \n
--! consumed_ram \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Erik van der Bij
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 07/07/2009 v0.01 EB First version \n
--!
-------------------------------------------------------------------------------
--! @todo Define I/O signals \n
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_tx_rx
--============================================================================
entity wf_tx_rx is
port (
-------------------------------------------------------------------------------
-- Connections to wf_tx_rx
-------------------------------------------------------------------------------
du1_i : in std_logic; --! Strobe
du2_o : out std_logic; --! Acknowledge
du3_i : in std_logic --! Write enable
);
end entity wf_tx_rx;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- COMPONENT DECLARATIONS
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_tx_rx
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_tx_rx is
begin
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
--===========================================================================
--! @file wf_tx_rx.vhd
--! @brief Serialises and deserialises the WorldFIP data
--===========================================================================
--! Standard library
library IEEE;
--! Standard packages
use IEEE.STD_LOGIC_1164.all; --! std_logic definitions
use IEEE.NUMERIC_STD.all; --! conversion functions
use work.wf_package.all;
-------------------------------------------------------------------------------
-- --
-- wf_tx_rx --
-- --
-- CERN, BE/CO/HT --
-- --
-------------------------------------------------------------------------------
--
-- unit name: wf_tx_rx
--
--! @brief Serialises and deserialises the WorldFIP data.
--!
--! Used in the NanoFIP design. \n
--! On reception it depacketises the data and only presents the actual data
--! contents. It also verifies the FCS (Frame Checksum, CRC).\n
--! On transmission it packetises the data and adds the FCS.
--! The unit wf_rx_osc recovers the carrier clock during
--!
--! @author Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
--
--! @date 07/07/2009
--
--! @version v0.01
--
--! @details
--!
--! <b>Dependencies:</b>\n
--! wf_engine \n
--! tx_engine \n
--! clk_gen \n
--! reset_logic \n
--! consumed_ram \n
--!
--!
--! <b>References:</b>\n
--!
--!
--!
--! <b>Modified by:</b>\n
--! Author: Pablo Alvarez Sanchez
-------------------------------------------------------------------------------
--! \n\n<b>Last changes:</b>\n
--! 07/07/2009 v0.01 PAAS First version \n
--!
-------------------------------------------------------------------------------
--! @todo Define I/O signals \n
--!
-------------------------------------------------------------------------------
--============================================================================
--! Entity declaration for wf_tx_rx
--============================================================================
entity wf_tx_rx is
port (
uclk_i : in std_logic; --! User Clock
rst_i : in std_logic;
start_send_p_i : in std_logic;
request_byte_p_o : out std_logic;
byte_ready_p_i : in std_logic;
byte_i : in std_logic_vector(7 downto 0);
last_byte_p_i : in std_logic;
-- clk_fixed_carrier_p_o : out std_logic;
d_o : out std_logic;
d_e_o : out std_logic;
d_clk_o : out std_logic;
d_a_i : in std_logic;
rate_i : in std_logic_vector(1 downto 0);
byte_ready_p_o : out std_logic;
byte_o : out std_logic_vector(7 downto 0);
last_byte_p_o : out std_logic;
fss_decoded_p_o : out std_logic;
crc_ok_p_o : out std_logic
);
end entity wf_tx_rx;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--! ARCHITECTURE OF wf_tx_rx
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture rtl of wf_tx_rx is
constant C_CLKFCDLENTGTH : natural := 3;
signal s_d_d : std_logic_vector(2 downto 0);
signal s_d_re, s_d_fe : std_logic;
signal s_clk_fixed_carrier_p : std_logic;
signal s_d_filtered : std_logic;
signal s_d_ready_p : std_logic;
signal s_load_phase : std_logic;
signal s_clk_carrier_p : std_logic;
signal s_clk_bit_180_p : std_logic;
signal s_edge_window, edge_180_window : std_logic;
signal s_d_edge : std_logic;
signal s_clk_fixed_carrier_p_d : std_logic_vector(C_CLKFCDLENTGTH - 1 downto 0);
begin
process(uclk_i)
begin
if rising_edge(uclk_i) then
s_d_d <= s_d_d(1 downto 0) & d_a_i;
s_d_re <= (not s_d_d(2)) and s_d_d(1) and s_d_d(0);
s_d_fe <= (s_d_d(2)) and (not s_d_d(1)) and (not s_d_d(0));
end if;
end process;
s_d_edge <= s_d_fe or s_d_re;
uwf_tx: wf_tx
generic map(C_CLKFCDLENTGTH => C_CLKFCDLENTGTH)
PORT MAP(
uclk_i => uclk_i,
rst_i => rst_i,
start_send_p_i => start_send_p_i,
request_byte_p_o => request_byte_p_o,
byte_ready_p_i => byte_ready_p_i,
byte_i => byte_i,
last_byte_p_i => last_byte_p_i,
-- clk_fixed_carrier_p_i => s_clk_fixed_carrier_p,
clk_fixed_carrier_p_d_i => s_clk_fixed_carrier_p_d,
d_o => d_o,
d_e_o => d_e_o
);
uwf_rx: wf_rx
PORT MAP(
uclk_i => uclk_i,
rst_i => rst_i,
byte_ready_p_o => byte_ready_p_o,
byte_o => byte_o,
last_byte_p_o => last_byte_p_o,
fss_decoded_p_o => fss_decoded_p_o,
crc_ok_p_o => crc_ok_p_o,
d_fe_i => s_d_fe,
d_re_i => s_d_re,
d_filtered_i => s_d_filtered,
s_d_ready_p_i => s_d_ready_p,
load_phase_o => s_load_phase,
clk_bit_180_p_i => s_clk_bit_180_p,
edge_window_i => s_edge_window,
edge_180_window_i => edge_180_window
);
uwf_rx_osc :wf_rx_osc
generic map(C_OSC_LENGTH => 20,
C_QUARTZ_PERIOD => 25.0,
C_CLKFCDLENTGTH => C_CLKFCDLENTGTH)
port map(
uclk_i => uclk_i, --! User Clock
rst_i => rst_i,
d_edge_i => s_d_fe,
load_phase_i => s_load_phase,
--! Bit rate \n
--! 00: 31.25 kbit/s \n
--! 01: 1 Mbit/s \n
--! 10: 2.5 Mbit/s \n
--! 11: reserved, do not use
rate_i => rate_i, --! Bit rate
clk_fixed_carrier_p_o => s_clk_fixed_carrier_p,
clk_fixed_carrier_p_d_o => s_clk_fixed_carrier_p_d,
clk_fixed_carrier_o => d_clk_o,
clk_carrier_p_o => s_clk_carrier_p,
clk_carrier_180_p_o => open,
clk_bit_p_o => open,
clk_bit_90_p_o => open,
clk_bit_180_p_o => s_clk_bit_180_p,
clk_bit_270_p_o => open,
edge_window_o => s_edge_window,
edge_180_window_o => edge_180_window,
phase_o => open
);
Udeglitcher : deglitcher
generic map (C_ACULENGTH => 10)
Port map( uclk_i => uclk_i,
d_i => s_d_d(2),
d_o => s_d_filtered,
carrier_p_i => s_clk_carrier_p,
d_ready_p_o => s_d_ready_p);
end architecture rtl;
-------------------------------------------------------------------------------
-- E N D O F F I L E
-------------------------------------------------------------------------------
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