Commit a1350268 authored by egousiou's avatar egousiou

JTAG_contoller: added a counter for the bits that are being played to avoid…

JTAG_contoller: added a counter for the bits that are being played to avoid complicated combinatorial calculations

git-svn-id: http://svn.ohwr.org/cern-fip/trunk/hdl/design@231 7f0067c9-7624-46c7-bd39-3fb5400c0213
parent e91158c9
......@@ -53,9 +53,9 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.WF_PACKAGE.all; -- definitions of types, constants, entities
-- Component specific library
library PROASIC3; -- ProASIC3 library
use PROASIC3.all;
--=================================================================================================
......
--_________________________________________________________________________________________________
-- |
-- |The nanoFIP| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- --
-- nanoFIP --
-- --
---------------------------------------------------------------------------------------------------
-- File nanofip.vhd
--
-- Description The nanoFIP is an FPGA component implementing the WorldFIP protocol that can be
-- used in field devices. The nanoFIP is designed to be radiation tolerant by using different
-- single event upset mitigation techniques such as Triple Module Redundancy and several reset
-- possibilities. The nanoFIP design is to be implemented in an Actel ProASIC3 Flash family FPGA
-- that is preserving its configuration and has high tolerance to total dose radiation effects.
-- The device is used in conjunction with a FIELDRIVE chip and FIELDTR insulating transformer,
-- both available from the company ALSTOM.
--
-- In the WorldFIP protocol, the master of the bus, Bus Arbitrer (BA) initiates all the activity
-- in the bus. The BA is broadcasting ID_DAT frames, requesting for a particular variable, to all
-- the stations connected to the same network segment. Figure 1 shows the structure of an ID_DAT
-- frame:
-- ___________ ______ _______ ______ ___________ _______
-- |____FSS____|_Ctrl_||__Var__|_SUBS_||____FCS____|__FES__|
--
-- Figure 1 : ID_DAT frame structure
--
-- nanoFIP is handling the following set of variables addressed by:
-- o ID_DAT Var_Subs = 14_xy: for the presence variable
-- o ID_DAT Var_Subs = 10_xy: for the identification variable
-- o ID_DAT Var_Subs = 05_xy: for the consumed variable of any length up to 124 bytes
-- o ID_DAT Var_Subs = 91_..: for the broadcast consumed variable of any length up to 124 bytes
-- o ID_DAT Var_Subs = 06_xy: for the produced variable of a user-settable length (P3_LGTH)
-- o ID_DAT Var_Subs = E0_..: for the broadcast consumed reset variable
--
-- After a 14xy or a 10xy or a 06xy ID_DAT, if nanoFIP's address (SUBS) is xy, it will respond
-- with a "produced" RP_DAT frame, containing the variable requested. Figure 2 shows the structure
-- of a RP_DAT frame:
-- ___________ ______ ____________________ ___________ _______
-- |____FSS____|_Ctrl_||_____...Data..._____||____FCS____|__FES__|
--
-- Figure 2 : RP_DAT frame structure
--
-- After a 05xy ID_DAT, if nanoFIP's address (SUBS) is xy, or after a broadcast ID_DAT 91..h or
-- E0..h, nanoFIP will "consume" the incoming RP_DAT frame.
--
-- Regarding the interface with the user, nanoFIP provides:
-- o variable data transfer over an integrated memory accessible with an 8-bit WISHBONE
-- System-On-Chip interconnection
-- o possibility of stand-alone mode with a 16 bits input bus and 16 bits output bus, without
-- the need to transfer data to or from the memory
-- o separate data valid outputs for each variable (consumed and produced)
--
-- nanoFIP provides several reset possibilities:
-- o External reset input pin, RSTIN, activated by the user logic
-- o External reset input pin, RST_I, activated by the user, that resets only the WISHBONE logic
-- o Addressed reset by the reset broadcast consumed variable (E0..h),
-- validated by station address as data
-- o External Power On Reset input pin, RSTPON
--
-- nanoFIP also provides resets to the user and to the FIELDRIVE:
-- o Reset output available to external logic (RSTON) by the reset broadcast consumed variable
-- (E0..h), validated by station address as data
-- o FIELDRIVE reset output (FD_RSTN) by the reset broadcast consumed variable (E0..h),
-- validated by station address as data
--
-- nanoFIP's main building blocks are (Figure 3):
--
-- o WF_reset_unit : for the treatment of the reset input signals & the generation
-- of the reset outputs
--
-- o WF_consumption : for the processing, storage & validation of consumed RP_DAT frames
--
-- o WF_fd_receiver : for the deserialization of the FIELDRIVE input and the formation
-- of ID_DAT or consumed RP_DAT bytes of data
--
-- o WF_production : for the retreival of bytes for produced RP_DAT frames
--
-- o WF_fd_transmitter : for the serialization of produced RP_DAT frames
--
-- o WF_engine_control : for the processing of the ID_DAT frames and the coordination of the
-- WF_consumption, WF_fd_receiver, WF_production & WF_fd_transmitter units
--
-- o WF_model_constr_dec : for the decoding of the WorldFIP settings M_ID and C_ID and the
-- generation of the S_ID
--
-- o WF_wb_controller : for the handling of the "User Interface WISHBONE Slave" control
-- signals.
--
-- _____________ ____________________________________________________
-- | | | WF_WB_controller |
-- | | |____________________________________________________|
-- | | _____________ _____________
-- | | | | ______________ | |
-- | WF_reset | | | | | | |
-- | _unit | | WF_ | | | | WF_ |
-- | | | consumption | | | | production |
-- | | | | | | | |
-- | | | | | | | |
-- | | |_____________| | WF_ | |_____________|
-- |_____________| _____________ |engine_control| _____________
-- | | | | | |
-- _____________ | | | | | |
-- | | | | | | | |
-- | | | WF_FD_ | | | | WF_FD_ |
-- | WF_model_ | | receiver | | | | transmitter |
-- | constr_dec | | | | | | |
-- | | | | | | | |
-- |_____________| |_____________| |______________| |_____________|
--
-- Figure 3: nanoFIP block diagram
--
-- The design is based on the nanoFIP functional specification document, available at:
-- http://www.ohwr.org/projects/cern-fip/documents
-- Complete information about this project at: http://www.ohwr.org/projects/cern-fip
--
--
-- Authors Erik Van der Bij (Erik.Van.der.Bij@cern.ch)
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch)
-- Date 20/01/2011
-- Version v0.05
-- Depends on WF_reset_unit
-- WF_model_constr_dec
-- WF_tx_rx_osc
-- WF_consumption
-- WF_production
-- WF_engine_control
-- WF_wb_controller
----------------
-- Last changes
-- 30/06/2009 v0.010 EB First version
-- 06/07/2009 v0.011 EB Dummy blocks
-- 07/07/2009 v0.011 EB Comments
-- 15/09/2009 v0.v2 PA
-- 09/12/2010 v0.v3 EG Logic removed (new unit inputs_synchronizer added)
-- 7/01/2011 v0.04 EG major restructuring; only 7 units on top level
-- 20/01/2011 v0.05 EG new unit WF_wb_controller(removes the or gate from top level)
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.WF_PACKAGE.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for nanoFIP
--=================================================================================================
entity nanofip is
port (
--INPUTS
-- WorldFIP settings
c_id_i : in std_logic_vector (3 downto 0); -- Constructor identification settings
m_id_i : in std_logic_vector (3 downto 0); -- Model identification settings
p3_lgth_i : in std_logic_vector (2 downto 0); -- Produced variable data length
rate_i : in std_logic_vector (1 downto 0); -- WorldFIP bit rate
subs_i : in std_logic_vector (7 downto 0); -- Subscriber number coding (station address)
-- FIELDRIVE
fd_rxcdn_i : in std_logic; -- Reception activity detection, active low
fd_rxd_i : in std_logic; -- Receiver data
fd_txer_i : in std_logic; -- Transmitter error
fd_wdgn_i : in std_logic; -- Watchdog on transmitter
-- User Interface, General signals
nostat_i : in std_logic; -- No nanoFIP status with produced data
rstin_i : in std_logic; -- Initialization control, active low
-- Resets nanoFIP & the FIELDRIVE
rstpon_i : in std_logic; -- Power On Reset, active low
slone_i : in std_logic; -- Stand-alone mode
uclk_i : in std_logic; -- 40 MHz clock
-- User Interface, NON-WISHBONE
var1_acc_i : in std_logic; -- Signals that the user logic is accessing var 1
var2_acc_i : in std_logic; -- Signals that the user logic is accessing var 2
var3_acc_i : in std_logic; -- Signals that the user logic is accessing var 3
-- User Interface, WISHBONE Slave
wclk_i : in std_logic; -- WISHBONE clock; may be independent of uclk
adr_i : in std_logic_vector (9 downto 0); -- WISHBONE address
cyc_i : in std_logic; -- WISHBONE cycle
dat_i : in std_logic_vector (15 downto 0);-- dat_i(7 downto 0) : WISHBONE data in, memory mode
-- dat_i(15 downto 0): data in, stand-alone mode
rst_i : in std_logic; -- WISHBONE reset
-- Does not reset other internal logic
stb_i : in std_logic; -- WISHBONE strobe
we_i : in std_logic; -- WISHBONE write enable
-- User Interface, JTAG Controller
jc_tdo_i : in std_logic;
-- OUTPUTS
-- WorldFIP settings
s_id_o : out std_logic_vector (1 downto 0);-- Identification selection
-- FIELDRIVE
fd_rstn_o : out std_logic; -- Initialization control, active low
fd_txck_o : out std_logic; -- Line driver half bit clock
fd_txd_o : out std_logic; -- Transmitter data
fd_txena_o : out std_logic; -- Transmitter enable
-- User Interface, General signals
rston_o : out std_logic; -- Reset output, active low
-- User Interface, NON-WISHBONE
r_fcser_o : out std_logic; -- nanoFIP status byte, bit 5
r_tler_o : out std_logic; -- nanoFIP status byte, bit 4
u_cacer_o : out std_logic; -- nanoFIP status byte, bit 2
u_pacer_o : out std_logic; -- nanoFIP status byte, bit 3
var1_rdy_o : out std_logic; -- Signals new data received & can safely be read
var2_rdy_o : out std_logic; -- Signals new data received & can safely be read
var3_rdy_o : out std_logic; -- Signals that the var 3 can safely be written
-- User Interface, WISHBONE Slave
dat_o : out std_logic_vector (15 downto 0);-- dat_o(7 downto 0) : WISHBONE data out, memory mode
-- dat_o(15 downto 0): data out, stand-alone mode
ack_o : out std_logic; -- WISHBONE acknowledge
-- User Interface, JTAG Controller
jc_tms_o : out std_logic;
jc_tdi_o : out std_logic;
jc_tck_o : out std_logic
);
end entity nanofip;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture struc of nanofip is
---------------------------------------------------------------------------------------------------
-- Synplify Triple Module Redundancy --
---------------------------------------------------------------------------------------------------
-- attribute syn_radhardlevel : string; --
-- attribute syn_radhardlevel of struc : architecture is "tmr"; --
---------------------------------------------------------------------------------------------------
-- WF_reset_unit iutputs
signal s_nfip_intern_rst, s_wb_rst : std_logic;
-- WF_consumption outputs
signal s_var1_rdy, s_var2_rdy, s_var3_rdy : std_logic;
signal s_assert_RSTON_p, s_reset_nFIP_and_FD_p, s_nfip_status_r_tler : std_logic;
signal s_jc_start_p : std_logic;
signal s_jc_mem_data : std_logic_vector (7 downto 0);
-- WF_fd_receiver outputs
signal s_rx_fss_received_p, s_rx_fss_crc_fes_ok_p, s_rx_crc_wrong_p : std_logic;
signal s_rx_byte_ready_p : std_logic;
signal s_rx_byte : std_logic_vector (7 downto 0);
-- WF_production outputs
signal s_byte_to_tx : std_logic_vector (7 downto 0);
-- WF_fd_transmitter outputs
signal s_tx_last_byte_p, s_tx_completed_p : std_logic;
-- WF_engine_control outputs
signal s_tx_start_p, s_tx_request_byte_p, s_byte_request_accepted_p : std_logic;
signal s_cons_bytes_excess, s_rx_rst : std_logic;
signal s_var : t_var;
signal s_prod_data_lgth, s_prod_cons_byte_index : std_logic_vector (7 downto 0);
-- WF_model_constr_dec outputs
signal s_model_id_dec, s_constr_id_dec : std_logic_vector (7 downto 0);
-- WF_wb_controller outputs
signal s_wb_ack_prod : std_logic;
-- WF_model_constr_dec outputs
signal s_jc_mem_adr_rd : std_logic_vector (8 downto 0);
signal s_jc_tdo_byte : std_logic_vector (7 downto 0);
signal s_jc_tdi_o, s_jc_tms_o, s_jc_tck_o, s_fd_txd_o,s_rston : std_logic;
--=================================================================================================
-- architecture declaration
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- WF_reset_unit --
---------------------------------------------------------------------------------------------------
reset_unit : WF_reset_unit
port map (
uclk_i => uclk_i,
wb_clk_i => wclk_i,
rstin_a_i => rstin_i,
rstpon_a_i => rstpon_i,
rate_i => rate_i,
rst_i => rst_i,
rst_nFIP_and_FD_p_i => s_reset_nFIP_and_FD_p,
assert_RSTON_p_i => s_assert_RSTON_p,
-------------------------------------------------------------
nFIP_rst_o => s_nfip_intern_rst,
wb_rst_o => s_wb_rst,
rston_o => s_rston,
fd_rstn_o => fd_rstn_o);
-------------------------------------------------------------
rston_o <= s_rston;
---------------------------------------------------------------------------------------------------
-- WF_consumption --
---------------------------------------------------------------------------------------------------
Consumption: WF_consumption
port map (
uclk_i => uclk_i,
slone_i => slone_i,
nfip_rst_i => s_nfip_intern_rst,
subs_i => subs_i,
rx_byte_i => s_rx_byte,
rx_byte_ready_p_i => s_rx_byte_ready_p,
rx_fss_crc_fes_ok_p_i => s_rx_fss_crc_fes_ok_p,
rx_crc_wrong_p_i => s_rx_crc_wrong_p,
wb_clk_i => wclk_i,
wb_adr_i => adr_i (8 downto 0),
cons_bytes_excess_i => s_cons_bytes_excess,
var_i => s_var,
byte_index_i => s_prod_cons_byte_index,
jc_mem_adr_rd_i => s_jc_mem_adr_rd,
-------------------------------------------------------------
var1_rdy_o => s_var1_rdy,
var2_rdy_o => s_var2_rdy,
jc_start_p_o => s_jc_start_p,
data_o => dat_o,
nfip_status_r_tler_p_o => s_nfip_status_r_tler,
assert_rston_p_o => s_assert_RSTON_p,
rst_nfip_and_fd_p_o => s_reset_nFIP_and_FD_p,
jc_mem_data_o => s_jc_mem_data);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_fd_receiver --
---------------------------------------------------------------------------------------------------
FIELDRIVE_Receiver: WF_fd_receiver
port map (
uclk_i => uclk_i,
rate_i => rate_i,
fd_rxd_a_i => fd_rxd_i,
nfip_rst_i => s_nfip_intern_rst,
rx_rst_i => s_rx_rst,
-------------------------------------------------------------
rx_byte_o => s_rx_byte,
rx_byte_ready_p_o => s_rx_byte_ready_p,
rx_fss_crc_fes_ok_p_o => s_rx_fss_crc_fes_ok_p,
rx_fss_received_p_o => s_rx_fss_received_p,
rx_crc_wrong_p_o => s_rx_crc_wrong_p);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_production --
---------------------------------------------------------------------------------------------------
Production: WF_production
port map (
uclk_i => uclk_i,
slone_i => slone_i,
nostat_i => nostat_i,
nfip_rst_i => s_nfip_intern_rst,
wb_clk_i => wclk_i,
wb_data_i => dat_i(7 downto 0),
wb_adr_i => adr_i(8 downto 0),
wb_ack_prod_p_i => s_wb_ack_prod,
slone_data_i => dat_i,
var1_acc_a_i => var1_acc_i,
var2_acc_a_i => var2_acc_i,
var3_acc_a_i => var3_acc_i,
fd_txer_a_i => fd_txer_i,
fd_wdgn_a_i => fd_wdgn_i,
var_i => s_var,
data_lgth_i => s_prod_data_lgth,
byte_index_i => s_prod_cons_byte_index,
byte_request_accept_p_i => s_byte_request_accepted_p,
nfip_status_r_tler_p_i => s_nfip_status_r_tler,
nfip_status_r_fcser_p_i => s_rx_crc_wrong_p,
var1_rdy_i => s_var1_rdy,
var2_rdy_i => s_var2_rdy,
model_id_dec_i => s_model_id_dec,
constr_id_dec_i => s_constr_id_dec,
jc_tdo_byte_i => s_jc_tdo_byte,
-------------------------------------------------------------
byte_o => s_byte_to_tx,
u_cacer_o => u_cacer_o,
u_pacer_o => u_pacer_o,
r_tler_o => r_tler_o,
r_fcser_o => r_fcser_o,
var3_rdy_o => s_var3_rdy);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_fd_Transmitter --
---------------------------------------------------------------------------------------------------
FIELDRIVE_Transmitter: WF_fd_transmitter
port map (
uclk_i => uclk_i,
rate_i => rate_i,
nfip_rst_i => s_nfip_intern_rst,
tx_byte_i => s_byte_to_tx,
tx_byte_request_accept_p_i => s_byte_request_accepted_p,
tx_last_data_byte_p_i => s_tx_last_byte_p,
tx_start_p_i => s_tx_start_p,
-------------------------------------------------------------
tx_byte_request_p_o => s_tx_request_byte_p,
tx_completed_p_o => s_tx_completed_p,
tx_data_o => s_fd_txd_o,
tx_enable_o => fd_txena_o,
tx_clk_o => fd_txck_o);
-------------------------------------------------------------
fd_txd_o <= s_fd_txd_o;
---------------------------------------------------------------------------------------------------
-- WF_jtag_controller --
---------------------------------------------------------------------------------------------------
JTAG_controller: WF_jtag_controller
port map (
uclk_i => uclk_i,
nfip_rst_i => s_nfip_intern_rst,
jc_mem_data_i => s_jc_mem_data,
jc_start_p_i => s_jc_start_p,
jc_tdo_i => jc_tdo_i,
-----------------------------------------------------------------
jc_tms_o => jc_tms_o,
jc_tdi_o => jc_tdi_o,
jc_tck_o => jc_tck_o,
jc_tdo_byte_o => s_jc_tdo_byte,
jc_mem_adr_rd_o => s_jc_mem_adr_rd);
-----------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_engine_control --
---------------------------------------------------------------------------------------------------
engine_control : WF_engine_control
port map (
uclk_i => uclk_i,
nfip_rst_i => s_nfip_intern_rst,
tx_byte_request_p_i => s_tx_request_byte_p,
tx_completed_p_i => s_tx_completed_p,
rx_fss_received_p_i => s_rx_fss_received_p,
rx_byte_i => s_rx_byte,
rx_byte_ready_p_i => s_rx_byte_ready_p,
rx_fss_crc_fes_ok_p_i => s_rx_fss_crc_fes_ok_p,
rx_crc_wrong_p_i => s_rx_crc_wrong_p,
rate_i => rate_i,
subs_i => subs_i,
p3_lgth_i => p3_lgth_i,
slone_i => slone_i,
nostat_i => nostat_i,
-------------------------------------------------------------
var_o => s_var,
tx_start_p_o => s_tx_start_p,
tx_byte_request_accept_p_o => s_byte_request_accepted_p,
tx_last_data_byte_p_o => s_tx_last_byte_p,
prod_cons_byte_index_o => s_prod_cons_byte_index,
prod_data_lgth_o => s_prod_data_lgth,
cons_bytes_excess_o => s_cons_bytes_excess,
rx_rst_o => s_rx_rst);
-------------------------------------------------------------
var1_rdy_o <= s_var1_rdy;
var2_rdy_o <= s_var2_rdy;
var3_rdy_o <= s_var3_rdy;
---------------------------------------------------------------------------------------------------
-- WF_model_constr_decoder --
---------------------------------------------------------------------------------------------------
model_constr_decoder : WF_model_constr_decoder
port map (
uclk_i => uclk_i,
nfip_rst_i => s_nfip_intern_rst,
model_id_i => m_id_i,
constr_id_i => c_id_i,
-------------------------------------------------------------
select_id_o => s_id_o,
model_id_dec_o => s_model_id_dec,
constr_id_dec_o => s_constr_id_dec);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_wb_controller --
---------------------------------------------------------------------------------------------------
WISHBONE_controller: WF_wb_controller
port map (
wb_clk_i => wclk_i,
wb_rst_i => s_wb_rst,
wb_stb_i => stb_i,
wb_cyc_i => cyc_i,
wb_we_i => we_i,
wb_adr_id_i => adr_i (9 downto 7),
-------------------------------------------------------------
wb_ack_prod_p_o => s_wb_ack_prod,
wb_ack_p_o => ack_o);
-------------------------------------------------------------
end architecture struc;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
--_________________________________________________________________________________________________
-- |
-- |The nanoFIP| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- --
-- nanoFIP --
-- --
---------------------------------------------------------------------------------------------------
-- File nanofip.vhd
--
-- Description The nanoFIP is an FPGA component implementing the WorldFIP protocol that can be
-- used in field devices. The nanoFIP is designed to be radiation tolerant by using different
-- single event upset mitigation techniques such as Triple Module Redundancy and several reset
-- possibilities. The nanoFIP design is to be implemented in an Actel ProASIC3 Flash family FPGA
-- that is preserving its configuration and has high tolerance to total dose radiation effects.
-- The device is used in conjunction with a FIELDRIVE chip and FIELDTR insulating transformer,
-- both available from the company ALSTOM.
--
-- In the WorldFIP protocol, the master of the bus, Bus Arbitrer (BA) initiates all the activity
-- in the bus. The BA is broadcasting ID_DAT frames, requesting for a particular variable, to all
-- the stations connected to the same network segment. Figure 1 shows the structure of an ID_DAT
-- frame:
-- ___________ ______ _______ ______ ___________ _______
-- |____FSS____|_Ctrl_||__Var__|_SUBS_||____FCS____|__FES__|
--
-- Figure 1 : ID_DAT frame structure
--
-- nanoFIP is handling the following set of variables addressed by:
-- o ID_DAT Var_Subs = 14_xy: for the presence variable
-- o ID_DAT Var_Subs = 10_xy: for the identification variable
-- o ID_DAT Var_Subs = 05_xy: for the consumed variable of any length up to 124 bytes
-- o ID_DAT Var_Subs = 91_..: for the broadcast consumed variable of any length up to 124 bytes
-- o ID_DAT Var_Subs = 06_xy: for the produced variable of a user-settable length (P3_LGTH)
-- o ID_DAT Var_Subs = E0_..: for the broadcast consumed reset variable
--
-- After a 14xy or a 10xy or a 06xy ID_DAT, if nanoFIP's address (SUBS) is xy, it will respond
-- with a "produced" RP_DAT frame, containing the variable requested. Figure 2 shows the structure
-- of a RP_DAT frame:
-- ___________ ______ ____________________ ___________ _______
-- |____FSS____|_Ctrl_||_____...Data..._____||____FCS____|__FES__|
--
-- Figure 2 : RP_DAT frame structure
--
-- After a 05xy ID_DAT, if nanoFIP's address (SUBS) is xy, or after a broadcast ID_DAT 91..h or
-- E0..h, nanoFIP will "consume" the incoming RP_DAT frame.
--
-- Regarding the interface with the user, nanoFIP provides:
-- o variable data transfer over an integrated memory accessible with an 8-bit WISHBONE
-- System-On-Chip interconnection
-- o possibility of stand-alone mode with a 16 bits input bus and 16 bits output bus, without
-- the need to transfer data to or from the memory
-- o separate data valid outputs for each variable (consumed and produced)
--
-- nanoFIP provides several reset possibilities:
-- o External reset input pin, RSTIN, activated by the user logic
-- o External reset input pin, RST_I, activated by the user, that resets only the WISHBONE logic
-- o Addressed reset by the reset broadcast consumed variable (E0..h),
-- validated by station address as data
-- o External Power On Reset input pin, RSTPON
--
-- nanoFIP also provides resets to the user and to the FIELDRIVE:
-- o Reset output available to external logic (RSTON) by the reset broadcast consumed variable
-- (E0..h), validated by station address as data
-- o FIELDRIVE reset output (FD_RSTN) by the reset broadcast consumed variable (E0..h),
-- validated by station address as data
--
-- nanoFIP's main building blocks are (Figure 3):
--
-- o WF_reset_unit : for the treatment of the reset input signals & the generation
-- of the reset outputs
--
-- o WF_consumption : for the processing, storage & validation of consumed RP_DAT frames
--
-- o WF_fd_receiver : for the deserialization of the FIELDRIVE input and the formation
-- of ID_DAT or consumed RP_DAT bytes of data
--
-- o WF_production : for the retreival of bytes for produced RP_DAT frames
--
-- o WF_fd_transmitter : for the serialization of produced RP_DAT frames
--
-- o WF_engine_control : for the processing of the ID_DAT frames and the coordination of the
-- WF_consumption, WF_fd_receiver, WF_production & WF_fd_transmitter units
--
-- o WF_model_constr_dec : for the decoding of the WorldFIP settings M_ID and C_ID and the
-- generation of the S_ID
--
-- o WF_wb_controller : for the handling of the "User Interface WISHBONE Slave" control
-- signals.
--
-- _____________ ____________________________________________________
-- | | | WF_WB_controller |
-- | | |____________________________________________________|
-- | | _____________ _____________
-- | | | | ______________ | |
-- | WF_reset | | | | | | |
-- | _unit | | WF_ | | | | WF_ |
-- | | | consumption | | | | production |
-- | | | | | | | |
-- | | | | | | | |
-- | | |_____________| | WF_ | |_____________|
-- |_____________| _____________ |engine_control| _____________
-- | | | | | |
-- _____________ | | | | | |
-- | | | | | | | |
-- | | | WF_FD_ | | | | WF_FD_ |
-- | WF_model_ | | receiver | | | | transmitter |
-- | constr_dec | | | | | | |
-- | | | | | | | |
-- |_____________| |_____________| |______________| |_____________|
--
-- Figure 3: nanoFIP block diagram
--
-- The design is based on the nanoFIP functional specification document, available at:
-- http://www.ohwr.org/projects/cern-fip/documents
-- Complete information about this project at: http://www.ohwr.org/projects/cern-fip
--
--
-- Authors Erik Van der Bij (Erik.Van.der.Bij@cern.ch)
-- Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch)
-- Date 20/01/2011
-- Version v0.05
-- Depends on WF_reset_unit
-- WF_model_constr_dec
-- WF_tx_rx_osc
-- WF_consumption
-- WF_production
-- WF_engine_control
-- WF_wb_controller
----------------
-- Last changes
-- 30/06/2009 v0.010 EB First version
-- 06/07/2009 v0.011 EB Dummy blocks
-- 07/07/2009 v0.011 EB Comments
-- 15/09/2009 v0.v2 PA
-- 09/12/2010 v0.v3 EG Logic removed (new unit inputs_synchronizer added)
-- 7/01/2011 v0.04 EG major restructuring; only 7 units on top level
-- 20/01/2011 v0.05 EG new unit WF_wb_controller(removes the or gate from top level)
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.WF_PACKAGE.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for nanoFIP
--=================================================================================================
entity nanofip is
port (
--INPUTS
-- WorldFIP settings
c_id_i : in std_logic_vector (3 downto 0); -- Constructor identification settings
m_id_i : in std_logic_vector (3 downto 0); -- Model identification settings
p3_lgth_i : in std_logic_vector (2 downto 0); -- Produced variable data length
rate_i : in std_logic_vector (1 downto 0); -- WorldFIP bit rate
subs_i : in std_logic_vector (7 downto 0); -- Subscriber number coding (station address)
-- FIELDRIVE
fd_rxcdn_i : in std_logic; -- Reception activity detection, active low
fd_rxd_i : in std_logic; -- Receiver data
fd_txer_i : in std_logic; -- Transmitter error
fd_wdgn_i : in std_logic; -- Watchdog on transmitter
-- User Interface, General signals
nostat_i : in std_logic; -- No nanoFIP status with produced data
rstin_i : in std_logic; -- Initialization control, active low
-- Resets nanoFIP & the FIELDRIVE
rstpon_i : in std_logic; -- Power On Reset, active low
slone_i : in std_logic; -- Stand-alone mode
uclk_i : in std_logic; -- 40 MHz clock
-- User Interface, NON-WISHBONE
var1_acc_i : in std_logic; -- Signals that the user logic is accessing var 1
var2_acc_i : in std_logic; -- Signals that the user logic is accessing var 2
var3_acc_i : in std_logic; -- Signals that the user logic is accessing var 3
-- User Interface, WISHBONE Slave
wclk_i : in std_logic; -- WISHBONE clock; may be independent of uclk
adr_i : in std_logic_vector (9 downto 0); -- WISHBONE address
cyc_i : in std_logic; -- WISHBONE cycle
dat_i : in std_logic_vector (15 downto 0);-- dat_i(7 downto 0) : WISHBONE data in, memory mode
-- dat_i(15 downto 0): data in, stand-alone mode
rst_i : in std_logic; -- WISHBONE reset
-- Does not reset other internal logic
stb_i : in std_logic; -- WISHBONE strobe
we_i : in std_logic; -- WISHBONE write enable
-- User Interface, JTAG Controller
jc_tdo_i : in std_logic;
-- OUTPUTS
-- WorldFIP settings
s_id_o : out std_logic_vector (1 downto 0);-- Identification selection
-- FIELDRIVE
fd_rstn_o : out std_logic; -- Initialization control, active low
fd_txck_o : out std_logic; -- Line driver half bit clock
fd_txd_o : out std_logic; -- Transmitter data
fd_txena_o : out std_logic; -- Transmitter enable
-- User Interface, General signals
rston_o : out std_logic; -- Reset output, active low
-- User Interface, NON-WISHBONE
r_fcser_o : out std_logic; -- nanoFIP status byte, bit 5
r_tler_o : out std_logic; -- nanoFIP status byte, bit 4
u_cacer_o : out std_logic; -- nanoFIP status byte, bit 2
u_pacer_o : out std_logic; -- nanoFIP status byte, bit 3
var1_rdy_o : out std_logic; -- Signals new data received & can safely be read
var2_rdy_o : out std_logic; -- Signals new data received & can safely be read
var3_rdy_o : out std_logic; -- Signals that the var 3 can safely be written
-- User Interface, WISHBONE Slave
dat_o : out std_logic_vector (15 downto 0);-- dat_o(7 downto 0) : WISHBONE data out, memory mode
-- dat_o(15 downto 0): data out, stand-alone mode
ack_o : out std_logic; -- WISHBONE acknowledge
TP39 : out std_logic;
-- User Interface, JTAG Controller
jc_tms_o : out std_logic;
jc_tdi_o : out std_logic;
jc_tck_o : out std_logic
);
end entity nanofip;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture struc of nanofip is
---------------------------------------------------------------------------------------------------
-- Synplify Triple Module Redundancy --
---------------------------------------------------------------------------------------------------
attribute syn_radhardlevel : string; --
attribute syn_radhardlevel of struc : architecture is "tmr"; --
---------------------------------------------------------------------------------------------------
-- WF_reset_unit iutputs
signal s_nfip_intern_rst, s_wb_rst : std_logic;
-- WF_consumption outputs
signal s_var1_rdy, s_var2_rdy, s_var3_rdy : std_logic;
signal s_assert_RSTON_p, s_reset_nFIP_and_FD_p, s_nfip_status_r_tler : std_logic;
signal s_jc_start_p : std_logic;
signal s_jc_mem_data : std_logic_vector (7 downto 0);
-- WF_fd_receiver outputs
signal s_rx_fss_received_p, s_rx_fss_crc_fes_ok_p, s_rx_crc_wrong_p : std_logic;
signal s_rx_byte_ready_p : std_logic;
signal s_rx_byte : std_logic_vector (7 downto 0);
-- WF_production outputs
signal s_byte_to_tx : std_logic_vector (7 downto 0);
-- WF_fd_transmitter outputs
signal s_tx_last_byte_p, s_tx_completed_p : std_logic;
-- WF_engine_control outputs
signal s_tx_start_p, s_tx_request_byte_p, s_byte_request_accepted_p : std_logic;
signal s_cons_bytes_excess, s_rx_rst : std_logic;
signal s_var : t_var;
signal s_prod_data_lgth, s_prod_cons_byte_index : std_logic_vector (7 downto 0);
-- WF_model_constr_dec outputs
signal s_model_id_dec, s_constr_id_dec : std_logic_vector (7 downto 0);
-- WF_wb_controller outputs
signal s_wb_ack_prod : std_logic;
-- WF_model_constr_dec outputs
signal s_jc_mem_adr_rd : std_logic_vector (8 downto 0);
signal s_jc_tdo_byte : std_logic_vector (7 downto 0);
--=================================================================================================
-- architecture declaration
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- WF_reset_unit --
---------------------------------------------------------------------------------------------------
reset_unit : WF_reset_unit
port map (
uclk_i => uclk_i,
wb_clk_i => wclk_i,
rstin_a_i => rstin_i,
rstpon_a_i => rstpon_i,
rate_i => rate_i,
rst_i => rst_i,
rst_nFIP_and_FD_p_i => s_reset_nFIP_and_FD_p,
assert_RSTON_p_i => s_assert_RSTON_p,
-------------------------------------------------------------
nFIP_rst_o => s_nfip_intern_rst,
wb_rst_o => s_wb_rst,
rston_o => rston_o,
fd_rstn_o => fd_rstn_o);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_consumption --
---------------------------------------------------------------------------------------------------
Consumption: WF_consumption
port map (
uclk_i => uclk_i,
slone_i => slone_i,
nfip_rst_i => s_nfip_intern_rst,
subs_i => subs_i,
rx_byte_i => s_rx_byte,
rx_byte_ready_p_i => s_rx_byte_ready_p,
rx_fss_crc_fes_ok_p_i => s_rx_fss_crc_fes_ok_p,
rx_crc_wrong_p_i => s_rx_crc_wrong_p,
wb_clk_i => wclk_i,
wb_adr_i => adr_i (8 downto 0),
cons_bytes_excess_i => s_cons_bytes_excess,
var_i => s_var,
byte_index_i => s_prod_cons_byte_index,
jc_mem_adr_rd_i => s_jc_mem_adr_rd,
-------------------------------------------------------------
var1_rdy_o => s_var1_rdy,
var2_rdy_o => s_var2_rdy,
jc_start_p_o => s_jc_start_p,
data_o => dat_o,
nfip_status_r_tler_p_o => s_nfip_status_r_tler,
assert_rston_p_o => s_assert_RSTON_p,
rst_nfip_and_fd_p_o => s_reset_nFIP_and_FD_p,
jc_mem_data_o => s_jc_mem_data);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_fd_receiver --
---------------------------------------------------------------------------------------------------
FIELDRIVE_Receiver: WF_fd_receiver
port map (
uclk_i => uclk_i,
rate_i => rate_i,
fd_rxd_a_i => fd_rxd_i,
nfip_rst_i => s_nfip_intern_rst,
rx_rst_i => s_rx_rst,
-------------------------------------------------------------
rx_byte_o => s_rx_byte,
rx_byte_ready_p_o => s_rx_byte_ready_p,
rx_fss_crc_fes_ok_p_o => s_rx_fss_crc_fes_ok_p,
rx_fss_received_p_o => s_rx_fss_received_p,
rx_crc_wrong_p_o => s_rx_crc_wrong_p);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_production --
---------------------------------------------------------------------------------------------------
Production: WF_production
port map (
uclk_i => uclk_i,
slone_i => slone_i,
nostat_i => nostat_i,
nfip_rst_i => s_nfip_intern_rst,
wb_clk_i => wclk_i,
wb_data_i => dat_i(7 downto 0),
wb_adr_i => adr_i(8 downto 0),
wb_ack_prod_p_i => s_wb_ack_prod,
slone_data_i => dat_i,
var1_acc_a_i => var1_acc_i,
var2_acc_a_i => var2_acc_i,
var3_acc_a_i => var3_acc_i,
fd_txer_a_i => fd_txer_i,
fd_wdgn_a_i => fd_wdgn_i,
var_i => s_var,
data_lgth_i => s_prod_data_lgth,
byte_index_i => s_prod_cons_byte_index,
byte_request_accept_p_i => s_byte_request_accepted_p,
nfip_status_r_tler_p_i => s_nfip_status_r_tler,
nfip_status_r_fcser_p_i => s_rx_crc_wrong_p,
var1_rdy_i => s_var1_rdy,
var2_rdy_i => s_var2_rdy,
model_id_dec_i => s_model_id_dec,
constr_id_dec_i => s_constr_id_dec,
jc_tdo_byte_i => s_jc_tdo_byte,
-------------------------------------------------------------
byte_o => s_byte_to_tx,
u_cacer_o => u_cacer_o,
u_pacer_o => u_pacer_o,
r_tler_o => r_tler_o,
r_fcser_o => r_fcser_o,
var3_rdy_o => s_var3_rdy);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_fd_Transmitter --
---------------------------------------------------------------------------------------------------
FIELDRIVE_Transmitter: WF_fd_transmitter
port map (
uclk_i => uclk_i,
rate_i => rate_i,
nfip_rst_i => s_nfip_intern_rst,
tx_byte_i => s_byte_to_tx,
tx_byte_request_accept_p_i => s_byte_request_accepted_p,
tx_last_data_byte_p_i => s_tx_last_byte_p,
tx_start_p_i => s_tx_start_p,
-------------------------------------------------------------
tx_byte_request_p_o => s_tx_request_byte_p,
tx_completed_p_o => s_tx_completed_p,
tx_data_o => fd_txd_o,
tx_enable_o => fd_txena_o,
tx_clk_o => fd_txck_o);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_jtag_controller --
---------------------------------------------------------------------------------------------------
JTAG_controller: WF_jtag_controller
port map (
uclk_i => uclk_i,
nfip_rst_i => s_nfip_intern_rst,
jc_mem_data_i => s_jc_mem_data,
jc_start_p_i => s_jc_start_p,
jc_tdo_i => jc_tdo_i,
-----------------------------------------------------------------
jc_tms_o => jc_tms_o,
jc_tdi_o => jc_tdi_o,
jc_tck_o => jc_tck_o,
jc_tdo_byte_o => s_jc_tdo_byte,
jc_mem_adr_rd_o => s_jc_mem_adr_rd);
-----------------------------------------------------------------
TP39 <= s_jc_tdo_byte(0);
---------------------------------------------------------------------------------------------------
-- WF_engine_control --
---------------------------------------------------------------------------------------------------
engine_control : WF_engine_control
port map (
uclk_i => uclk_i,
nfip_rst_i => s_nfip_intern_rst,
tx_byte_request_p_i => s_tx_request_byte_p,
tx_completed_p_i => s_tx_completed_p,
rx_fss_received_p_i => s_rx_fss_received_p,
rx_byte_i => s_rx_byte,
rx_byte_ready_p_i => s_rx_byte_ready_p,
rx_fss_crc_fes_ok_p_i => s_rx_fss_crc_fes_ok_p,
rx_crc_wrong_p_i => s_rx_crc_wrong_p,
rate_i => rate_i,
subs_i => subs_i,
p3_lgth_i => p3_lgth_i,
slone_i => slone_i,
nostat_i => nostat_i,
-------------------------------------------------------------
var_o => s_var,
tx_start_p_o => s_tx_start_p,
tx_byte_request_accept_p_o => s_byte_request_accepted_p,
tx_last_data_byte_p_o => s_tx_last_byte_p,
prod_cons_byte_index_o => s_prod_cons_byte_index,
prod_data_lgth_o => s_prod_data_lgth,
cons_bytes_excess_o => s_cons_bytes_excess,
rx_rst_o => s_rx_rst);
-------------------------------------------------------------
var1_rdy_o <= s_var1_rdy;
var2_rdy_o <= s_var2_rdy;
var3_rdy_o <= s_var3_rdy;
---------------------------------------------------------------------------------------------------
-- WF_model_constr_decoder --
---------------------------------------------------------------------------------------------------
model_constr_decoder : WF_model_constr_decoder
port map (
uclk_i => uclk_i,
nfip_rst_i => s_nfip_intern_rst,
model_id_i => m_id_i,
constr_id_i => c_id_i,
-------------------------------------------------------------
select_id_o => s_id_o,
model_id_dec_o => s_model_id_dec,
constr_id_dec_o => s_constr_id_dec);
-------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- WF_wb_controller --
---------------------------------------------------------------------------------------------------
WISHBONE_controller: WF_wb_controller
port map (
wb_clk_i => wclk_i,
wb_rst_i => s_wb_rst,
wb_stb_i => stb_i,
wb_cyc_i => cyc_i,
wb_we_i => we_i,
wb_adr_id_i => adr_i (9 downto 7),
-------------------------------------------------------------
wb_ack_prod_p_o => s_wb_ack_prod,
wb_ack_p_o => ack_o);
-------------------------------------------------------------
end architecture struc;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
\ No newline at end of file
--_________________________________________________________________________________________________
-- |
-- |The nanoFIP| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- --
-- WF_DualClkRAM_clka_rd_clkb_wr --
-- --
---------------------------------------------------------------------------------------------------
-- File WF_DualClkRAM_clka_rd_clkb_wr.vhd
--
-- Description The unit provides the memory triplication, transparently to the outside world.
-- The component DualClkRam (512 bytes) is triplicated: each incoming byte is written
-- at the same position in the three memories, whereas each outgoing byte is the
-- outcome of a majority voter.
-- The memory is dual port; port A is used for reading only, port B for writing only.
--
-- Remark: MajorityVoter(A,B,C) = (A and B) OR (A and C) OR (B and C)
--
--
-- Authors Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch)
-- Date 10/12/2010
-- Version v0.02
-- Depends on DualClkRAM.vhd
----------------
-- Last changes
-- 12/2010 v0.02 EG code cleaned-up+commented
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.WF_PACKAGE.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for WF_DualClkRAM_clka_rd_clkb_wr
--=================================================================================================
entity WF_DualClkRAM_clka_rd_clkb_wr is
generic (g_ram_data_lgth : integer; -- length of data word
g_ram_addr_lgth : integer); -- memory depth
port (
-- INPUTS
-- Inputs concerning port A
clk_porta_i : in std_logic;
addr_porta_i : in std_logic_vector (g_ram_addr_lgth - 1 downto 0);
-- Inputs concerning port B
clk_portb_i : in std_logic;
addr_portb_i : in std_logic_vector (g_ram_addr_lgth - 1 downto 0);
data_portb_i : in std_logic_vector (g_ram_data_lgth - 1 downto 0);
write_en_portb_i : in std_logic;
-- OUTPUT
-- Output concerning port A
data_porta_o : out std_logic_vector (g_ram_data_lgth -1 downto 0)
);
end WF_DualClkRAM_clka_rd_clkb_wr;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture syn of WF_DualClkRAM_clka_rd_clkb_wr is
-- type t_data_o_A_array is array (natural range <>) of std_logic_vector (7 downto 0);
-- signal s_data_o_A_array : t_data_o_A_array (0 to 2); -- keeps the DOUTA of each one of the memories
signal s_one, s_rwB : std_logic;
signal s_zeros : std_logic_vector (7 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
s_one <= '1';
s_zeros <= (others => '0');
s_rwB <= not write_en_portb_i;
---------------------------------------------------------------------------------------------------
-- memory triplication
-- The component DualClkRam is generated three times.
-- Port A is used for reading only, port B for writing only.
-- The input DINB is written in the same position in the 3 memories.
-- The output DOUTA from each memory is kept in the array s_data_o_A_array.
-- G_memory_triplication: for I in 0 to 2 generate
UDualClkRam : DualClkRam
port map (
DINA => s_zeros,
ADDRA => addr_porta_i,
RWA => s_one,
CLKA => clk_porta_i,
DINB => data_portb_i,
ADDRB => addr_portb_i,
RWB => s_rwB,
CLKB => clk_portb_i,
RESETn => s_one,
DOUTA => data_porta_o, --s_data_o_A_array(I),
DOUTB => open);
-- end generate;
---------------------------------------------------------------------------------------------------
-- Combinatorial Majority_Voter
-- Majority_Voter: data_porta_o <= (s_data_o_A_array(0) and s_data_o_A_array(1)) or
-- (s_data_o_A_array(1) and s_data_o_A_array(2)) or
-- (s_data_o_A_array(2) and s_data_o_A_array(0));
end syn;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
--_________________________________________________________________________________________________
-- |
-- |The nanoFIP| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- --
-- WF_DualClkRAM_clka_rd_clkb_wr --
-- --
---------------------------------------------------------------------------------------------------
-- File WF_DualClkRAM_clka_rd_clkb_wr.vhd
--
-- Description The unit provides the memory triplication, transparently to the outside world.
-- The component DualClkRam (512 bytes) is triplicated: each incoming byte is written
-- at the same position in the three memories, whereas each outgoing byte is the
-- outcome of a majority voter.
-- The memory is dual port; port A is used for reading only, port B for writing only.
--
-- Remark: MajorityVoter(A,B,C) = (A and B) OR (A and C) OR (B and C)
--
--
-- Authors Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch)
-- Date 10/12/2010
-- Version v0.02
-- Depends on DualClkRAM.vhd
----------------
-- Last changes
-- 12/2010 v0.02 EG code cleaned-up+commented
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE |
-- ------------------------------------ |
-- This source file is free software; you can redistribute it and/or modify it under the terms of |
-- the GNU Lesser General Public License as published by the Free Software Foundation; either |
-- version 2.1 of the License, or (at your option) any later version. |
-- This source is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
-- without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
-- See the GNU Lesser General Public License for more details. |
-- You should have received a copy of the GNU Lesser General Public License along with this |
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html |
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.WF_PACKAGE.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for WF_DualClkRAM_clka_rd_clkb_wr
--=================================================================================================
entity WF_DualClkRAM_clka_rd_clkb_wr is
generic (g_ram_data_lgth : integer; -- length of data word
g_ram_addr_lgth : integer); -- memory depth
port (
-- INPUTS
-- Inputs concerning port A
clk_porta_i : in std_logic;
addr_porta_i : in std_logic_vector (g_ram_addr_lgth - 1 downto 0);
-- Inputs concerning port B
clk_portb_i : in std_logic;
addr_portb_i : in std_logic_vector (g_ram_addr_lgth - 1 downto 0);
data_portb_i : in std_logic_vector (g_ram_data_lgth - 1 downto 0);
write_en_portb_i : in std_logic;
-- OUTPUT
-- Output concerning port A
data_porta_o : out std_logic_vector (g_ram_data_lgth -1 downto 0)
);
end WF_DualClkRAM_clka_rd_clkb_wr;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture syn of WF_DualClkRAM_clka_rd_clkb_wr is
type t_data_o_A_array is array (natural range <>) of std_logic_vector (7 downto 0);
signal s_data_o_A_array : t_data_o_A_array (0 to 2); -- keeps the DOUTA of each one of the memories
signal s_one, s_rwB : std_logic;
signal s_zeros : std_logic_vector (7 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
s_one <= '1';
s_zeros <= (others => '0');
s_rwB <= not write_en_portb_i;
---------------------------------------------------------------------------------------------------
-- memory triplication
-- The component DualClkRam is generated three times.
-- Port A is used for reading only, port B for writing only.
-- The input DINB is written in the same position in the 3 memories.
-- The output DOUTA from each memory is kept in the array s_data_o_A_array.
G_memory_triplication: for I in 0 to 2 generate
UDualClkRam : DualClkRam
port map (
DINA => s_zeros,
ADDRA => addr_porta_i,
RWA => s_one,
CLKA => clk_porta_i,
DINB => data_portb_i,
ADDRB => addr_portb_i,
RWB => s_rwB,
CLKB => clk_portb_i,
RESETn => s_one,
DOUTA => s_data_o_A_array(I),--data_porta_o, --s_data_o_A_array(I)
DOUTB => open);
end generate;
---------------------------------------------------------------------------------------------------
-- Combinatorial Majority_Voter
Majority_Voter: data_porta_o <= (s_data_o_A_array(0) and s_data_o_A_array(1)) or
(s_data_o_A_array(1) and s_data_o_A_array(2)) or
(s_data_o_A_array(2) and s_data_o_A_array(0));
end syn;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
\ No newline at end of file
......@@ -19,9 +19,9 @@
-- every JC_TMS/ JC_TDI pair.
-- o JC_TMS and JC_TDI are being retreived from the JC_consumed memory and are
-- put to the corresponding outputs on each falling edge of the JC_TCK.
-- Bytes 0 and 1 of the JC_consumed memory do not contain JC_TMS and JC_TDI bits,
-- but are used to indicate, in big indian order, the amount of JC_TMS and JC_TDI
-- bits that have to be output.
-- The first and second data bytes of the JC_consumed memory do not contain JC_TMS
-- and JC_TDI bits, but are used to indicate, in big indian order, the amount of
-- JC_TMS and JC_TDI bits that have to be output.
--
-- o the JC_TDO input is sampled on the rising edge of JC_TCK; only the last sampled
-- JC_TDO bit is significant and it is registered and sent at the next var_jc2
......@@ -83,8 +83,8 @@ port (
nfip_rst_i : in std_logic; -- nanoFIP internal reset
-- Signals from the WF_consumption unit
jc_mem_data_i : in std_logic_vector (7 downto 0); -- byte retreived from the JC_cons memory
jc_start_p_i : in std_logic; -- pulse upon validation of a jc_var1 RP_DAT frame
jc_mem_data_i : in std_logic_vector (7 downto 0); -- byte retreived from the JC_consumed memory
-- OUTPUTS
......@@ -111,15 +111,15 @@ architecture rtl of WF_jtag_controller is
signal jc_st, nx_jc_st : jc_st_t;
signal s_idle, s_get_byte, s_play_byte, s_set_adr : std_logic;
signal s_bytes_c_reinit, s_bytes_c_incr : std_logic;
signal s_bytes_c, s_bytes_c_d1 : unsigned (6 downto 0);
signal s_frame_bits_lsb, s_frame_bits_msb : std_logic_vector (7 downto 0);
signal s_frame_bits, s_bits_so_far : unsigned (15 downto 0);
signal s_bits_so_far : unsigned (15 downto 0);
signal s_tck_c_reinit, s_tck_c_incr, s_tck_c_is_full: std_logic;
signal s_tck : std_logic;
signal s_frame_bits_lsb, s_frame_bits_msb : std_logic_vector (7 downto 0);
signal s_frame_bits : unsigned (15 downto 0);
signal s_tck, s_tck_transition, s_tck_c_is_full : std_logic;
signal s_tck_c, s_tck_period, s_tck_four_periods : unsigned (c_FOUR_JC_TCK_C_LGTH-1 downto 0);
signal s_tck_half_period, s_tck_quarter_period : unsigned (c_FOUR_JC_TCK_C_LGTH-1 downto 0);
......@@ -151,21 +151,19 @@ begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Combinatorial process JC_FSM_Comb_State_Transitions: Definition of the state
-- transitions of the FSM.
-- 2 first bytes : big indian number of bits to be considered in this frame
-- s_bits_so_far : number of treated TMS and TDI bits
-- (s_frame_bits - s_bits_so_far) srl 1 : remaining number of TMS/ TDI pairs
-- 2 ^ (c_JC_TCK_DIV'left) : number of uclk cycles for 1 JC_TCK period
-- s_frame_bits indicates the amount of TMS/ TDI bits that have to be output, according to the
-- first 2 data bytes in the JC_consumed memory
-- s_bits_so_far indicates the amount of bits that have been output so far
JC_FSM_Comb_State_Transitions: process (jc_st, s_bytes_c, s_frame_bits, s_bits_so_far,
jc_start_p_i, s_tck_c, s_tck_c_is_full)
jc_start_p_i, s_tck_c_is_full, s_tck_transition)
begin
case jc_st is
when idle =>
if jc_start_p_i = '1' then -- consumed jc_var1 frame validated
if jc_start_p_i = '1' then -- consumed jc_var1 frame validated
nx_jc_st <= set_address;
else
......@@ -173,40 +171,33 @@ begin
end if;
when set_address =>
nx_jc_st <= get_byte; -- 1 uclk cycle for the setting of the memory
-- address; byte available at the next cycle
nx_jc_st <= get_byte; -- 1 uclk cycle for the setting of the memory
-- address; byte available at the next cycle
when get_byte =>
if s_bytes_c < 2 then -- 2 first bytes: number of jc_TMS & JC_TDI bits
if s_bytes_c < 2 then -- 2 first bytes: amount of JC_TMS & JC_TDI bits
nx_jc_st <= set_address;
else -- the rest of the bytes have to be output
else -- the rest of the bytes have to be "played"
nx_jc_st <= play_byte;
end if;
when play_byte =>
if s_frame_bits = 0 or s_frame_bits > c_MAX_FRAME_BITS then -- outside expected limits
if s_frame_bits <= 0 or s_frame_bits > c_MAX_FRAME_BITS then -- outside expected limits
nx_jc_st <= idle;
elsif s_frame_bits - s_bits_so_far > 8 then -- full bytes still available
if s_tck_c_is_full = '1' then -- byte completed
elsif s_frame_bits > s_bits_so_far then
if s_tck_c_is_full = '1' then -- byte completed
nx_jc_st <= set_address;
else -- byte being output
else -- byte being output
nx_jc_st <= play_byte;
end if;
elsif s_frame_bits - s_bits_so_far = 8 then -- last full byte
if s_tck_c_is_full = '1' then -- byte completed
nx_jc_st <= idle;
else -- byte being output
nx_jc_st <= play_byte;
end if;
else -- bits of last byte
if s_tck_c < (((s_frame_bits - s_bits_so_far) srl 1) sll c_JC_TCK_DIV'left) -1 then
nx_jc_st <= play_byte;
else -- last bit
if s_tck_transition = '1' then
nx_jc_st <= idle; -- wait until the completion of a JC_TCK cycle
else
nx_jc_st <= idle;
nx_jc_st <= play_byte;
end if;
end if;
......@@ -223,9 +214,9 @@ begin
case jc_st is
when idle =>
---------------------------------
-----------------------------
s_idle <= '1';
---------------------------------
-----------------------------
s_set_adr <= '0';
s_get_byte <= '0';
s_play_byte <= '0';
......@@ -234,9 +225,9 @@ begin
when set_address =>
s_idle <= '0';
---------------------------------
-----------------------------
s_set_adr <= '1';
---------------------------------
-----------------------------
s_get_byte <= '0';
s_play_byte <= '0';
......@@ -244,9 +235,9 @@ begin
s_idle <= '0';
s_set_adr <= '0';
---------------------------------
-----------------------------
s_get_byte <= '1';
---------------------------------
-----------------------------
s_play_byte <= '0';
when play_byte =>
......@@ -254,9 +245,9 @@ begin
s_idle <= '0';
s_set_adr <= '0';
s_get_byte <= '0';
---------------------------------
-----------------------------
s_play_byte <= '1';
---------------------------------
-----------------------------
end case;
end process;
......@@ -265,7 +256,7 @@ begin
---------------------------------------------------------------------------------------------------
-- JC_TCK generation --
---------------------------------------------------------------------------------------------------
-- Instantiation of a WF_incr_counter used for the generation of the 5 MHz JC_TCK output clock.
-- Instantiation of a WF_incr_counter used for the generation of the JC_TCK output clock.
-- The counter is filled up after having counted 4 JC_TCK periods; this corresponds to the amount
-- of periods needed for outputting a full JC_TMS/ JC_TDI byte;
......@@ -273,8 +264,8 @@ begin
generic map (g_counter_lgth => c_FOUR_JC_TCK_C_LGTH)
port map (
uclk_i => uclk_i,
reinit_counter_i => s_tck_c_reinit,
incr_counter_i => s_tck_c_incr,
reinit_counter_i => (not s_play_byte),
incr_counter_i => s_play_byte,
counter_is_full_o => s_tck_c_is_full,
------------------------------------------
counter_o => s_tck_c);
......@@ -288,13 +279,8 @@ begin
s_tck <= '1';
else
if (s_tck_c >= s_tck_quarter_period and s_tck_c < s_tck_half_period+s_tck_quarter_period) or
(s_tck_c >= (2*s_tck_half_period) +s_tck_quarter_period and s_tck_c < (3*s_tck_half_period) +s_tck_quarter_period) or
(s_tck_c >= (4*s_tck_half_period) +s_tck_quarter_period and s_tck_c < (5*s_tck_half_period) +s_tck_quarter_period) or
(s_tck_c >= (6*s_tck_half_period) +s_tck_quarter_period and s_tck_c < (7*s_tck_half_period) +s_tck_quarter_period) then
s_tck <= '0';
else
s_tck <= '1';
if s_tck_transition = '1' then
s_tck <= not s_tck;
end if;
end if;
......@@ -307,9 +293,15 @@ begin
s_tck_half_period <= (s_tck_four_periods srl 3)+1; -- # uclk ticks for 1/2 JC_TCK period
s_tck_quarter_period <= (s_tck_four_periods srl 4)+1; -- # uclk ticks for 1/4 JC_TCK period
s_tck_transition <= '1' when (s_tck_c = s_tck_quarter_period) or (s_tck_c = s_tck_half_period+s_tck_quarter_period) or
(s_tck_c = (2*s_tck_half_period) +s_tck_quarter_period) or (s_tck_c = (3*s_tck_half_period) +s_tck_quarter_period) or
(s_tck_c = (4*s_tck_half_period) +s_tck_quarter_period) or (s_tck_c = (5*s_tck_half_period) +s_tck_quarter_period) or
(s_tck_c = (6*s_tck_half_period) +s_tck_quarter_period) or (s_tck_c = (7*s_tck_half_period) +s_tck_quarter_period) else '0';
jc_tck_o <= s_tck;
---------------------------------------------------------------------------------------------------
-- Bytes counter --
---------------------------------------------------------------------------------------------------
......@@ -319,8 +311,8 @@ begin
generic map (g_counter_lgth => 7)
port map (
uclk_i => uclk_i,
reinit_counter_i => s_bytes_c_reinit,
incr_counter_i => s_bytes_c_incr,
reinit_counter_i => s_idle,
incr_counter_i => s_set_adr,
counter_is_full_o => open,
------------------------------------------
counter_o => s_bytes_c);
......@@ -329,75 +321,10 @@ begin
jc_mem_adr_rd_o <= std_logic_vector (resize((s_bytes_c + 2), jc_mem_adr_rd_o'length));
-- "+2" is bc the first 2 bytes in the memory (PDU_TYPE and Lenght) are not read
s_bits_so_far <= (resize((s_bytes_c-2), s_frame_bits'length)) sll 3;
-- "-2" is bc the first 2 bytes read from the memory, represent the number of TMS
-- and TDI bits and are not to be played
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Combinatorial process that according to the state of the FSM sets values to the
-- JC_TCK_periods_counter and JC_bytes_count inputs.
Bit_Index: process (s_idle, s_set_adr, s_get_byte, s_play_byte)
begin
--------------------------------------
if s_idle ='1' then
-- bytes counter reinitialization
s_bytes_c_reinit <= '1';
s_bytes_c_incr <= '0';
-- JC_TCK counter reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
--------------------------------------
elsif s_set_adr = '1' then
-- bytes counter counting
s_bytes_c_reinit <= '0';
s_bytes_c_incr <= '1';
-- JC_TCK counter reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
--------------------------------------
elsif s_get_byte = '1' then
-- bytes counter retains previous value
s_bytes_c_reinit <= '0';
s_bytes_c_incr <= '0';
-- JC_TCK counter reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
--------------------------------------
elsif s_play_byte = '1' then
-- bytes counter retains previous value
s_bytes_c_reinit <= '0';
s_bytes_c_incr <= '0';
-- JC_TCK counter counting
s_tck_c_reinit <= '0';
s_tck_c_incr <= '1';
--------------------------------------
else
-- bytes counter
s_bytes_c_reinit <= '1';
s_bytes_c_incr <= '0';
-- JC_TCK counter reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
end if;
end process;
---------------------------------------------------------------------------------------------------
-- Number of TMS and TDI bits retreival --
-- Frame bits retreival --
---------------------------------------------------------------------------------------------------
Bits_Number_Retreival: process (uclk_i)
begin
......@@ -409,17 +336,17 @@ begin
else
s_bytes_c_d1 <= s_bytes_c;
if s_bytes_c_d1 = 0 then
if s_set_adr = '1' and s_bytes_c_d1 = 0 then
s_frame_bits_msb <= jc_mem_data_i;
end if;
if s_bytes_c_d1 = 1 then
if s_set_adr = '1' and s_bytes_c_d1 = 1 then
s_frame_bits_lsb <= jc_mem_data_i;
end if;
end if;
end if;
end process;
s_frame_bits <= unsigned(s_frame_bits_msb) & unsigned (s_frame_bits_lsb);
s_frame_bits <= unsigned (s_frame_bits_msb) & unsigned (s_frame_bits_lsb);
......@@ -433,6 +360,7 @@ begin
if nfip_rst_i = '1' then -- asynchronous reset
jc_tms_o <= '0';
jc_tdi_o <= '0';
elsif falling_edge (s_tck) then
......@@ -457,19 +385,32 @@ begin
---------------------------------------------------------------------------------------------------
-- Delivered bits counter --
---------------------------------------------------------------------------------------------------
JC_bits_counter: process (s_tck, nfip_rst_i, s_idle)
begin
if s_idle = '1' then -- asynchronous reset
s_bits_so_far <= (others => '0');
elsif falling_edge (s_tck) then
s_bits_so_far <= s_bits_so_far + 2;
end if;
end process;
--------------------------------------------------------------------------------------------------
-- TDO sampler --
---------------------------------------------------------------------------------------------------
JC_TDO_sampling: process (s_tck)
JC_TDO_sampling: process (s_tck, nfip_rst_i)
begin
if rising_edge (s_tck) then
if s_idle= '1' then
jc_tdo_byte_o <= (others => '0');
else
jc_tdo_byte_o <= "0000000" & jc_tdo_i;
end if;
if nfip_rst_i = '1' then
jc_tdo_byte_o <= (others => '0');
elsif rising_edge (s_tck) then
jc_tdo_byte_o <= "0000000" & jc_tdo_i;
end if;
end process;
......
--_________________________________________________________________________________________________
-- |
-- |The nanoFIP| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
--________________________________________________________________________________________________|
---------------------------------------------------------------------------------------------------
-- File WF_cons_bytes_processor.vhd |
---------------------------------------------------------------------------------------------------
-- Standard library
library IEEE;
-- Standard packages
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific packages
use work.WF_PACKAGE.all; -- definitions of types, constants, entities
---------------------------------------------------------------------------------------------------
-- --
-- WF_cons_bytes_processor --
-- --
---------------------------------------------------------------------------------------------------
--
--
-- Description The unit is consuming the RP_DAT data bytes that are arriving from the
-- WF_fd_receiver, according to the following:
--
-- o If the variable identifier of the preceded ID_DAT was a var_1 or a var_2:
--
-- o If the operation is in memory mode : the unit is registering the
-- application-data bytes along with the PDU_TYPE, Length and MPS bytes in the
-- Consumed memories
--
-- o If the operation is in stand-alone mode: the unit is transferring the 2 appli-
-- cation-data bytes to the "nanoFIP User Interface, NON_WISHBONE" data bus DAT_O
--
-- o If the consumed variable had been a var_rst, the 2 application-data bytes are
-- identified and sent to the WF_reset_unit.
--
-- Note: The validity of the consumed bytes (stored in the memory or transfered to DATO
-- or transfered to the WF_reset_unit) is indicated by the "nanoFIP User Interface,
-- NON_WISHBONE" signals VAR1_RDY/ VAR2_RDY or the nanoFIP internal signals
-- rst_nFIP_and_FD_p/ assert_RSTON_p, which are treated in the WF_cons_outcome unit and
-- are assessed after the end of the reception of a complete frame.
--
--
-- Reminder:
--
-- Consumed RP_DAT frame structure :
-- ___________ ______ _______ ________ __________________ _______ ___________ _______
-- |____FSS____|_Ctrl_||__PDU__|__LGTH__|__..ApplicData..__|__MPS__||____FCS____|__FES__|
--
-- |--------&LGTH bytes-------|
-- |---------write to Consumed memory----------|
-- |-----to DAT_O-----|
-- |---to Reset Unit--|
--
--
--
-- Authors Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch)
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch)
--
--
-- Date 15/12/2010
--
--
-- Version v0.03
--
--
-- Depends on WF_reset_unit
-- WF_fd_receiver
-- WF_engine_control
--
--
---------------------------------------------------------------------------------------------------
--
-- Last changes
-- -> 11/09/2009 v0.01 EB First version
-- -> 09/2010 v0.02 EG Treatment of reset variable added; Bytes_Transfer_To_DATO unit
-- creation for simplification; Signals renamed;
-- Ctrl, PDU_TYPE, Length bytes registered;
-- Code cleaned-up & commented.
-- -> 15/12/2010 v0.03 EG Unit renamed from WF_cons_bytes_from_rx to WF_cons_bytes_processor
-- byte_ready_p comes from the rx_deserializer (no need to pass from
-- the engine) Code cleaned-up & commented (more!)
--
---------------------------------------------------------------------------------------------------
--=================================================================================================
-- Entity declaration for WF_cons_bytes_processor
--=================================================================================================
entity WF_jtag_player is
port (
-- INPUTS
-- nanoFIP User Interface, General signals
uclk_i : in std_logic; -- 40 MHz clock
-- Signal from the WF_reset_unit
nfip_rst_i : in std_logic; -- nanoFIP internal reset
-- Signals from the WF_fd_receiver unit
jc_mem_data_i : in std_logic_vector (7 downto 0); -- input byte
jc_start_p_i : in std_logic;
jc_tdo_i : in std_logic;
-- OUTPUTS
jc_tms_o : out std_logic;
jc_tdi_o : out std_logic;
jc_tck_o : out std_logic;
jc_tdo_byte_o : out std_logic_vector (7 downto 0);
jc_mem_adr_rd_o : out std_logic_vector (8 downto 0)
);
end entity WF_jtag_player;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of WF_jtag_player is
type jtag_pl_st_t is (idle, get_byte, play_byte, set_address);
signal jtag_pl_st, nx_jtag_pl_st : jtag_pl_st_t;
signal s_idle, s_get_size, s_get_byte, s_play_byte, s_set_adr : std_logic;
signal s_bytes_c_reinit, s_bytes_c_incr : std_logic;
signal s_tck_c_reinit, s_tck_c_incr, s_tck, s_tck_c_is_full, s_tck_d1 : std_logic;
signal s_bytes_c, s_bytes_c_d1 : unsigned (6 downto 0);
signal s_tck_c : unsigned (4 downto 0);
signal s_frame_size_lsb, s_frame_size_msb : std_logic_vector (7 downto 0);
signal s_jc_tdo_bit : std_logic;
signal s_frame_size : unsigned (15 downto 0);
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
---------------------------------------------------------------------------------------------------
-- FSM --
---------------------------------------------------------------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Synchronous process JATG_Player_FSM_Sync: storage of the current state of the FSM
JATG_Player_FSM_Sync: process (uclk_i)
begin
if rising_edge (uclk_i) then
if nfip_rst_i = '1' then
jtag_pl_st <= idle;
else
jtag_pl_st <= nx_jtag_pl_st;
end if;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Combinatorial process JATG_Player_FSM_Comb_State_Transitions: Definition of the state
-- transitions of the FSM.
JATG_Player_FSM_Comb_State_Transitions: process (jtag_pl_st, s_bytes_c, s_frame_size, jc_start_p_i, s_tck_c, s_tck_c_is_full)
begin
case jtag_pl_st is
when idle =>
if jc_start_p_i = '1' then
nx_jtag_pl_st <= set_address;
else
nx_jtag_pl_st <= idle;
end if;
when set_address =>
nx_jtag_pl_st <= get_byte;
when get_byte =>
if s_bytes_c < 2 then -- getting size bytes
nx_jtag_pl_st <= set_address;
else
nx_jtag_pl_st <= play_byte;
end if;
when play_byte =>
if s_frame_size = 0 then --
nx_jtag_pl_st <= idle;
elsif s_frame_size - ((resize((s_bytes_c-2), s_frame_size'length)) sll 3) > 8 then -- complete bytes
if s_tck_c_is_full = '1' then
nx_jtag_pl_st <= set_address;
else
nx_jtag_pl_st <= play_byte;
end if;
elsif s_frame_size - ((resize((s_bytes_c-2), s_frame_size'length)) sll 3) = 8 then-- last complete byte
if s_tck_c_is_full = '1' then
nx_jtag_pl_st <= idle;
else
nx_jtag_pl_st <= play_byte;
end if;
else -- last bits
if s_tck_c < ((s_frame_size - (resize((s_bytes_c-2), s_frame_size'length) sll 3)) sll 2)-1 then
nx_jtag_pl_st <= play_byte;
else
nx_jtag_pl_st <= idle;
end if;
end if;
when others =>
nx_jtag_pl_st <= idle;
end case;
end process;
JATG_Player_FSM_Comb_Output_Signals: process (jtag_pl_st)
begin
case jtag_pl_st is
when idle =>
------------------------------------
s_idle <= '1';
------------------------------------
s_get_size <= '0';
s_set_adr <= '0';
s_get_byte <= '0';
s_play_byte <= '0';
when set_address =>
s_idle <= '0';
s_get_size <= '0';
------------------------------------
s_set_adr <= '1';
------------------------------------
s_get_byte <= '0';
s_play_byte <= '0';
when get_byte =>
s_idle <= '0';
s_get_size <= '0';
s_set_adr <= '0';
------------------------------------
s_get_byte <= '1';
------------------------------------
s_play_byte <= '0';
when play_byte =>
s_idle <= '0';
s_get_size <= '0';
s_get_byte <= '0';
s_set_adr <= '0';
------------------------------------
s_play_byte <= '1';
------------------------------------
end case;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Instantiation of a WF_incr_counter for the retreival of bytes from the JTAG consumed memory.
JTAG_player_bytes_count: WF_incr_counter
generic map (g_counter_lgth => 7)
port map (
uclk_i => uclk_i,
reinit_counter_i => s_bytes_c_reinit,
incr_counter_i => s_bytes_c_incr,
counter_is_full_o => open,
------------------------------------------
counter_o => s_bytes_c);
------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Instantiation of a WF_incr_counter for the generation of the JC_TCK output 5 MHz clock
JC_TCK_periods_counter: WF_incr_counter
generic map (g_counter_lgth => 5)
port map (
uclk_i => uclk_i,
reinit_counter_i => s_tck_c_reinit,
incr_counter_i => s_tck_c_incr,
counter_is_full_o => s_tck_c_is_full,
------------------------------------------
counter_o => s_tck_c);
------------------------------------------
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Combinatorial process that according to the state of the FSM sets values to the
-- Incoming_Bits_Index inputs.
Bit_Index: process (s_idle, s_get_size, s_set_adr, s_get_byte, s_play_byte)
begin
if s_idle ='1' then
-- bytes counter reinitialization
s_bytes_c_reinit <= '1';
s_bytes_c_incr <= '0';
-- JC_TCK reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
elsif s_set_adr = '1' then
-- bytes counter counting
s_bytes_c_reinit <= '0';
s_bytes_c_incr <= '1';
-- JC_TCK reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
elsif s_get_byte = '1' then
-- bytes counter counts one byte
s_bytes_c_reinit <= '0';
s_bytes_c_incr <= '0';
-- JC_TCK reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
elsif s_play_byte = '1' then
-- bytes counter doesn t move
s_bytes_c_reinit <= '0';
s_bytes_c_incr <= '0';
-- JC_TCK reinitialization
s_tck_c_reinit <= '0';
s_tck_c_incr <= '1';
else
-- bytes counter
s_bytes_c_reinit <= '1';
s_bytes_c_incr <= '0';
-- JC_TCK reinitialization
s_tck_c_reinit <= '1';
s_tck_c_incr <= '0';
end if;
end process;
s_tck <= '0' when (s_tck_c >1 and s_tck_c < 6) or (s_tck_c > 9 and s_tck_c < 14) or
(s_tck_c > 17 and s_tck_c < 22) or (s_tck_c > 25 and s_tck_c < 30) else '1';
jc_mem_adr_rd_o <= std_logic_vector (resize((s_bytes_c + 2), jc_mem_adr_rd_o'length));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
JC_TCK_Construction: process (uclk_i)
begin
if rising_edge (uclk_i) then
if nfip_rst_i = '1' then
s_tck_d1 <= '0';
s_bytes_c_d1 <= (others => '0');
s_frame_size_msb <= (others => '0');
s_frame_size_lsb <= (others => '0');
else
s_tck_d1 <= s_tck;
s_bytes_c_d1 <= s_bytes_c;
if s_bytes_c_d1 = 0 then
s_frame_size_msb <= jc_mem_data_i;
end if;
if s_bytes_c_d1 = 1 then
s_frame_size_lsb <= jc_mem_data_i;
end if;
end if;
end if;
end process;
s_frame_size <= unsigned(s_frame_size_msb) & unsigned (s_frame_size_lsb);
jc_tck_o <= s_tck_d1;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
JTAG_TMS_TDI_bits_player: process (s_tck_d1)
begin
if falling_edge (s_tck_d1) then
if s_tck_c < 4 then
jc_tms_o <= jc_mem_data_i(7);
jc_tdi_o <= jc_mem_data_i(6);
elsif s_tck_c < 12 then
jc_tms_o <= jc_mem_data_i(5);
jc_tdi_o <= jc_mem_data_i(4);
elsif s_tck_c < 20 then
jc_tms_o <= jc_mem_data_i(3);
jc_tdi_o <= jc_mem_data_i(2);
elsif s_tck_c < 28 then
jc_tms_o <= jc_mem_data_i(1);
jc_tdi_o <= jc_mem_data_i(0);
else
jc_tms_o <= jc_mem_data_i(7);
jc_tdi_o <= jc_mem_data_i(6);
end if;
end if;
end process;
JTAG_TDO_bits_retreiver: process (s_tck_d1)
begin
if rising_edge (s_tck_d1) then
if nfip_rst_i = '1' or s_idle= '1' then
s_jc_tdo_bit <= '0';
else
s_jc_tdo_bit <= jc_tdo_i;
end if;
end if;
end process;
jc_tdo_byte_o <= "0000000" & s_jc_tdo_bit;
end architecture rtl;
--=================================================================================================
-- architecture end
--=================================================================================================
---------------------------------------------------------------------------------------------------
-- E N D O F F I L E
---------------------------------------------------------------------------------------------------
\ No newline at end of file
......@@ -137,13 +137,15 @@ package WF_package is
constant c_MAX_FRAME_BITS : natural := 976; -- maximum number of TMS/ TDI bits that can be sent in
-- one frame : 122 bytes * 8 bits
constant c_JC_TCK_DIV : unsigned (3 downto 0) := "1000"; -- JC_TCK is created by a frequency
-- JC_TCK is created by a frequency
-- division of the 40 MHz uclk.
-- c_JC_TCK_div = 8 gives a JC_TCK of 5 MHz
constant c_FOUR_JC_TCK_C_LGTH : integer := 5; -- length of a counter
-- counting 4 JC_TCK periods
---------------------------------------------------------------------------------------------------
-- Constant regarding the Model & Constructor decoding --
---------------------------------------------------------------------------------------------------
......@@ -890,6 +892,7 @@ end component WF_rx_osc;
dat_o : out std_logic_vector (15 downto 0);
jc_tms_o : out std_logic;
jc_tdi_o : out std_logic;
TP39 : out std_logic;
jc_tck_o : out std_logic);
-----------------------------------------------------------------
end component nanofip;
......
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