Commit abca22fd authored by Manoel Barros Marin's avatar Manoel Barros Marin
Browse files

- Added BST decoder in System

- Minor modifications
parent da31c525
......@@ -37,6 +37,7 @@ module VfcHdApplication
inout TestIo1_io,
inout TestIo2_io,
// FMC connector:
output VfmcEnableN_oen,
inout [33:0] FmcLaP_iob34,
inout [33:0] FmcLaN_iob34,
inout [23:0] FmcHaP_iob24,
......@@ -123,10 +124,13 @@ module VfcHdApplication
output [ 3:0] BottomLed_ob4,
// BST input:
input BstOn_i,
input BunchClk_ik,
input TurnClk_ip,
input [ 5:0] BstByteAddress_ib5,
input BstClk_ik, // Comment: 160 MHz
input BunchClkFlag_i,
input TurnClkFlag_i,
input [ 7:0] BstByteAddress_ib8,
input [ 7:0] BstByte_ib8,
output BstByteStrobe_i,
output BstByteError_i,
// Interrupt:
output [23:0] InterruptRequest_opb24,
// Ethernet streamer:
......
......@@ -63,6 +63,8 @@ always @(posedge Clk_ik) begin
StbCtrlReg_o <= #dly 1'b0;
StbStatReg_o <= #dly 1'b0;
StbPllRef_o <= #dly 1'b0;
StbGbtCtrlReg_o <= #dly 1'b0;
StbGbtStatReg_o <= #dly 1'b0;
case(SelectedModule_b3)
c_SelAppRevisionId: begin
StbAppReleaseId_o <= #dly Stb_i;
......
......@@ -37,6 +37,7 @@ module VfcHdApplication
inout TestIo1_io,
inout TestIo2_io,
// FMC connector:
output VfmcEnableN_oen,
inout [33:0] FmcLaP_iob34,
inout [33:0] FmcLaN_iob34,
inout [23:0] FmcHaP_iob24,
......@@ -123,10 +124,13 @@ module VfcHdApplication
output [ 3:0] BottomLed_ob4,
// BST input:
input BstOn_i,
input BunchClk_ik,
input TurnClk_ip,
input [ 5:0] BstByteAddress_ib5,
input BstClk_ik,
input BunchClkFlag_i,
input TurnClkFlag_i,
input [ 7:0] BstByteAddress_ib8,
input [ 7:0] BstByte_ib8,
output BstByteStrobe_i,
output BstByteError_i,
// Interrupt:
output [23:0] InterruptRequest_opb24,
// Ethernet streamer:
......
-------------------------------------------------------------------------------
-- Title : BiPhaseMark Decoder
-- Project :
-------------------------------------------------------------------------------
-- File : BiPhaseMark_Decoder.vhd
-- Author : Jan Kral <jan.kral@cern.ch>
-- Company :
-- Created : 2014-07-21
-- Last update: 2014-07-22
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: the entity decodes a BiPhaseMark code which is used for outer
-- BST encoding. The bi-phase mark code encodes data and clock phase which
-- allows to receiver to recover both. Output clock frequency is half of the
-- input clock frequency.
-------------------------------------------------------------------------------
-- Copyright (c) 2014
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2014-07-21 1.0 jakral Created
-------------------------------------------------------------------------------
-- _______ _______________ _______
-- RData \_______________/ \_______/ \______________
-- ___ ___ ___ ___ ___ ___ ___ ___ ___
-- Rclk \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \__
-- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-- ClkxC \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \
-- ___ _______ ___ ___ _______ ___ ______
-- DxD \___/ \_______/ \___/ \___/ \___/ \_______/
-- _______ _______________ _______
-- QxD ---/ \_______________/ \_______/ \__________
-- ___ ___ ___ ___ ___ ___ ___ ___ ___
-- QxE \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \__
-- __________________________________________________________
-- ValidQxS _________/
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity BiPhaseMark_Decoder is
port (
ClkxC : in std_logic; -- input clock
ResetxRNA : in std_logic; -- reset input
DxD : in std_logic; -- input data stream
QxD : out std_logic; -- decoded data stream
QxE : out std_logic; -- identifies the rising edge of output clock
ValidQxS : out std_logic -- set when output data stream is valid
);
end entity BiPhaseMark_Decoder;
architecture BiPhaseMark_Decoder_v1 of BiPhaseMark_Decoder is
type BiPhaseStatesxQ is (Idle, DataX_L, DataX_H, Data0_L, Data0_H, Data1_L, Data1_H, Error_H, Error_L); --! state machine type
signal CodeStatexS : BiPhaseStatesxQ; --! state machine signal declaration
begin -- architecture BiPhaseMark_Decoder_v1
process (ClkxC, ResetxRNA) is
begin -- process
if ResetxRNA = '0' then --! asynchronous reset (active low)
CodeStatexS <= Idle; --! reset state
ValidQxS <= '0';
QxD <= '0';
QxE <= '0';
elsif rising_edge(ClkxC) then --! rising clock edge
QxE <= '0'; -- when not specified otherwise, clock flag is not set
case CodeStatexS is
when Idle =>
ValidQxS <= '0';
-- as the first bit arrived it is not clear whether it is zero or one
if DxD = '1' then
CodeStatexS <= DataX_H;
else
CodeStatexS <= DataX_L;
end if;
when DataX_L =>
-- generate enable pulse as it is just before change of the output
QxE <= '1';
-- received first half of output data bit,
-- based on the second half (waiting for it here) deciding which
-- output bit recover
if DxD = '1' then -- data = 'LH'
CodeStatexS <= Data1_H;
else -- data = 'LL'
CodeStatexS <= Data0_L;
end if;
when DataX_H =>
-- generate enable pulse as it is just before change of the output
QxE <= '1';
-- received first half of output data bit,
-- based on the second half (waiting for it here) deciding which
-- output bit recover
if DxD = '1' then -- data = 'HH'
CodeStatexS <= Data0_H;
else -- data = 'HL'
CodeStatexS <= Data1_L;
end if;
when Data0_L =>
-- received bit is zero in low level
QxD <= '0';
ValidQxS <= '1';
-- when low level received now it means three subsequent low levels
-- which is an error
if DxD = '1' then -- data = 'LLH'
CodeStatexS <= DataX_H;
else -- data = 'LLL'
CodeStatexS <= Error_L;
end if;
when Data0_H =>
-- received bit is zero in high level
QxD <= '0';
ValidQxS <= '1';
-- when high level received now it means three subsequent high levels
-- which is an error
if DxD = '1' then -- data = 'HHH'
CodeStatexS <= Error_H;
else -- data = 'HHL'
CodeStatexS <= DataX_L;
end if;
when Data1_L =>
-- received bit is one ending with low level
QxD <= '1';
-- when low level received now it means that received bit is not one
-- but it is zero and synchronisation is performed automatically
if DxD = '1' then -- data = 'HLH'
CodeStatexS <= DataX_H;
else -- data = 'HLL'
CodeStatexS <= Data0_L;
end if;
when Data1_H =>
-- received bit is one ending with high level
QxD <= '1';
-- when low level received now it means that received bit is not one
-- but it is zero and synchronisation is performed automatically
if DxD = '1' then -- data = 'LHH'
CodeStatexS <= Data0_H;
else -- data = 'LHL'
CodeStatexS <= DataX_L;
end if;
when Error_H =>
-- three bits of high level received which is an error
ValidQxS <= '0';
-- stay here until error lasts
if DxD = '0' then -- data = 'HHHL'
CodeStatexS <= DataX_L;
end if;
when Error_L =>
-- three bits of high level received which is an error
ValidQxS <= '0';
-- stay here until error lasts
if DxD = '1' then -- data = 'LLLH'
CodeStatexS <= DataX_H;
end if;
when others =>
CodeStatexS <= Idle;
end case;
end if;
end process;
end architecture BiPhaseMark_Decoder_v1;
//----------------------------------------------------------------------
// Title : BST Decoder
// Project : BST Decoder Core
//----------------------------------------------------------------------
// File : BstDecoder.v
// Author : T. Levens, J. Olexa
// Modified by: M. Barros Marin
// Company : CERN BE-BI-QP
// Created : 2016-10-04
// Last update: 2016-11-03
// Platform : FPGA-generic
// Standard : Verilog
//----------------------------------------------------------------------
// Description:
//
// Top level of the BST Decoder core
//----------------------------------------------------------------------
`timescale 1ns/100ps
module BstDecoder (
// Module control:
input Reset_ir,
output BstOn_o,
// CDR interface:
input CdrClk_ik,
input CdrDat_i,
input CdrLos_i,
input CdrLol_i,
input SfpLos_i,
input SfpPrsnt_i,
// BST Message:
output [7:0] BstByteAddr_ob8,
output [7:0] BstByte_ob8,
output BstByteStrobe_o,
output BstByteError_o,
// Timing:
output BstClk_ok, // Comment: 160 MHz
output reg BunchClkFlag_oq, // Comment: 40 MHz
output reg TurnClkFlag_oq // Comment: 11 kHz (LHC) | 44Khz (SPS)
);
wire Reset_ra;
reg [ 1:0] Reset_rnx2;
wire Reset_rn;
reg CdrDat_q;
wire BiPhaseqxD1; // Comment: Decoded data stream
wire BiPhaseqxE1; // Comment: Identifies the rising edge of output clock
wire BiPhaseValidqxS1; // Comment: Set when output data stream is valid
wire TurnFlagxS1; // Comment: Channel A data output
wire DemuxedxD1; // Comment: Channel B data output
wire DxE1; // Comment: Output enable
wire SyncqxS1; // Comment: Synchronisation output
wire ValidqxS1; // Comment: Output data valid
wire [31:0] HammingqxD1; // Comment: Output data vector 32b
wire HammingValidqxS1; // Comment: Valid output
wire HammingErrorqxS1; // Comment: Error flag set when non-correctable error detected
//----------------------------------------------------------------------
// Module control
//----------------------------------------------------------------------
assign Reset_ra = ~SfpPrsnt_i | SfpLos_i | CdrLos_i | CdrLol_i | Reset_ir;
always @(posedge CdrClk_ik) Reset_rnx2 <= #1 {Reset_rnx2[0], ~Reset_ra};
assign Reset_rn = Reset_rnx2[1];
assign BstOn_o = Reset_rnx2[1];
//----------------------------------------------------------------------
// CDR interface & BST Message
//----------------------------------------------------------------------
always @(posedge CdrClk_ik) CdrDat_q <= #1 CdrDat_i;
BiPhaseMark_Decoder i_BiPhaseMark_Decoder (
.ClkxC (CdrClk_ik),
.DxD (CdrDat_q),
.ResetxRNA (Reset_rn),
.QxD (BiPhaseqxD1), // Comment: Decoded data stream
.QxE (BiPhaseqxE1), // Comment: Identifies the rising edge of output clock
.ValidQxS (BiPhaseValidqxS1)); // Comment: Set when output data stream is valid
TTCrx_AB_Demux i_TTCrx_AB_Demux (
.ClkxC (CdrClk_ik),
.ResetxRNA (Reset_rn),
.DxD (BiPhaseqxD1), // Comment: Input data stream
.DxE (BiPhaseqxE1), // Comment: Input enable
.ValidDxS (BiPhaseValidqxS1), // Comment: Input data valid
.AChanQxD (TurnFlagxS1), // Comment: Channel A data output
.BChanQxD (DemuxedxD1), // Comment: Channel B data output
.QxE (DxE1), // Comment: Output enable
.SyncQxS (SyncqxS1), // Comment: Synchronisation output
.ValidQxS (ValidqxS1)); // Comment: Output data valid
TTCrx_Hamming_Decoder i_TTCrx_Hamming_Decoder (
.ClkxC (CdrClk_ik),
.ResetxRNA (Reset_rn),
.DxD (DemuxedxD1), // Comment: Input data stream
.DxE (DxE1), // Comment: Input clock enable
.ValidDxS (ValidqxS1), // Comment: Valid flag
.SyncDxS (SyncqxS1), // Comment: Synchronisation flag
.QxD (HammingqxD1), // Comment: Output data vector
.ValidQxS (HammingValidqxS1), // Comment: Valid output
.ErrorQxS (HammingErrorqxS1)); // Comment: Non-correctable error detected
TTCrx_Frame_Decoder i_TTCrx_Frame_Decoder (
.ClkxC (CdrClk_ik),
.ResetxRNA (Reset_rn),
.DxE (DxE1), // Comment: Input clock enable
.DxD (HammingqxD1), // Comment: Input data stream
.ValidDxD (HammingValidqxS1), // Comment: Valid flag
.ErrorDxS (HammingErrorqxS1), // Comment: Error flag set when non-correctable error detected
.SubAddrQxD (BstByteAddr_ob8), // Comment: Address vector
.CmdDataQxD (BstByte_ob8), // Comment: Data vector
.ValidQxS (BstByteStrobe_o), // Comment: Valid output
.ErrorQxS (BstByteError_o)); // Comment: Error flag
//----------------------------------------------------------------------
// Timing
//----------------------------------------------------------------------
assign BstClk_ok = CdrClk_ik;
always @(posedge CdrClk_ik) BunchClkFlag_oq <= #1 DxE1;
always @(posedge CdrClk_ik)
if (~Reset_rn) TurnClkFlag_oq <= #1 1'b0;
else if (DxE1) TurnClkFlag_oq <= #1 ValidqxS1 ? TurnFlagxS1 : 1'b0;
endmodule
\ No newline at end of file
-------------------------------------------------------------------------------
-- Title : TTC receiver AB demultiplexer
-- Project :
-------------------------------------------------------------------------------
-- File : TTCrx_AB_Demux.vhd
-- Author : Jan Kral <jan.kral@cern.ch>
-- Company :
-- Created : 2014-07-22
-- Last update: 2014-08-01
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: In TTC signal there are two channels with time division
-- multiplex. Two slots are regularly consecutively alternating containing
-- channel A and B. Channel A contains a global trigger (BST Turn Clock).
-- Channel B then command and data frames.
-- The way to identify A/B channels is to count the number of consecutive "1"
-- in each channel and, as soon as there is 23 of them, that this is the B.
-- When there is 23 consecutive ones in both channels output is not valid.
--
-------------------------------------------------------------------------------
-- Copyright (c) 2014
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2014-07-22 1.0 jakral Created
-------------------------------------------------------------------------------
-- _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-- ClkxC / \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
-- _______ _______ _______ _______ _______ _______ _______ _______ ____
-- DxD X__A1___X__B1___X__A2___X__B2___X__A3___X__B3___X__A4___X__B4___X__A5
-- ___ ___ ___ ___ ___ ___ ___ ___
-- DxE \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/
-- _______________ _______________ _______________ _______________
-- AChanQxD X______A0_______X______A1_______X______A2_______X______A3_______X
-- _______________ _______________ _______________ _______________
-- BChanQxD X______B0_______X______B1_______X______B2_______X______B3_______X
-- ___ ___ ___ ___ ___
-- QxE / \___________/ \___________/ \___________/ \___________/ \
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity TTCrx_AB_Demux is
port (
ClkxC : in std_logic; -- clock
ResetxRNA : in std_logic; -- reset
DxD : in std_logic; -- input data stream
DxE : in std_logic; -- input enable
ValidDxS : in std_logic; -- input data valid
AChanQxD : out std_logic; -- channel A data output
BChanQxD : out std_logic; -- channel B data output
QxE : out std_logic; -- output enable
SyncQxS : out std_logic; -- synchronisation output
ValidQxS : out std_logic -- output data valid
);
end entity TTCrx_AB_Demux;
architecture TTCrx_AB_Demux_v1 of TTCrx_AB_Demux is
--! @brief calculates number of bits needed to to fit number 'N'
function bits_to_fit (N : natural) return natural is
variable vIntermediatexD : natural;
variable vBitCountxD : natural;
begin
vIntermediatexD := N;
vBitCountxD := 0;
loop
exit when vIntermediatexD = 0;
vIntermediatexD := vIntermediatexD / 2;
vBitCountxD := vBitCountxD + 1;
end loop;
if vBitCountxD = 0 then
return 1;
end if;
return vBitCountxD;
end;
constant NUM_CONSECUTIVE_ONES : natural := 23; -- number of consecutive ones which defines channel B
signal DelayedxD : std_logic; -- delayed input data stream
signal ChannelMismatchedxS : std_logic; -- flag is set when channels have to be swapped
signal BChanxE : std_logic; -- flag set when receiving channel A bit
signal CntAxD : unsigned(bits_to_fit(NUM_CONSECUTIVE_ONES)-1 downto 0); -- counter of consecutive ones in channel A
signal CntBxD : unsigned(CntAxD'range); -- counter of consecutive ones in channel B
signal QxEI : std_logic; -- internal copy of the QxE
signal ValidQxSI : std_logic; -- internal non delayed valid output
signal SyncQxSI : std_logic; -- internal synchronisation output
begin -- architecture TTCrx_AB_Demux_v1
-- purpose: generates pulses when bit of channel B is received
-- type : sequential
-- inputs : ClkxC, ResetxRNA, DxE, ChannelMismatchedxS
-- outputs: BChanxE
ChanAIdentification : process (ClkxC, ResetxRNA) is
begin -- process ChanAIdentification
if ResetxRNA = '0' then -- asynchronous reset (active low)
BChanxE <= '0';
elsif rising_edge(ClkxC) then -- rising clock edge
if DxE = '1' then
-- alternate channels each time new bit arrives, but only when mismatch
-- flag is not asserted
-- when it is asserted channel flag stays the same which ensures that
-- next time channels are in right order
if ChannelMismatchedxS = '0' then
BChanxE <= not BChanxE;
end if;
end if;
end if;
end process ChanAIdentification;
-- purpose: this counts consecutive bits in both channels
-- when number of consecutive ones in channel A is reached,
-- channels are mismatched and therefore swap signal is generated
-- first time defined number of consecutive ones is found in channel B,
-- the valid output is asserted
-- type : sequential
-- inputs : ClkxC, ResetxRNA, DxD, DxE, BChanxE, CntAxD, CntBxD
-- outputs: CntAxD, CntBxD, ChannelMismatchedxS, ValidQxSI
ChannelCounters : process (ClkxC, ResetxRNA) is
begin -- process ChannelCounters
if ResetxRNA = '0' then -- asynchronous reset (active low)
CntAxD <= (others => '0');
CntBxD <= (others => '0');
ChannelMismatchedxS <= '0';
ValidQxSI <= '0';
elsif rising_edge(ClkxC) then -- rising clock edge
if DxE = '1' then
ChannelMismatchedxS <= '0'; -- if not specified otherwise, channels are right
SyncQxSI <= '0';
-- counter for channel B
if BChanxE = '0' then
if DxD = '1' then
CntBxD <= CntBxD + 1;
else
-- received zero flushes the counter
CntBxD <= (others => '0');
end if;
end if;
-- compare counter B
if CntBxD = to_unsigned(NUM_CONSECUTIVE_ONES, CntAxD'length) then
-- this means that channels are in right order
-- output is therefore valid
ValidQxSI <= '1';
SyncQxSI <= '1';
end if;
-- counter for channel A
if BChanxE = '1' then
if DxD = '1' then
CntAxD <= CntAxD + 1;
else
-- received zero flushes the counter
CntAxD <= (others => '0');
end if;
end if;
-- compare counter A
if CntAxD = to_unsigned(NUM_CONSECUTIVE_ONES, CntAxD'length) and
ChannelMismatchedxS = '0' then
-- this means that channels are mismatched
ChannelMismatchedxS <= '1';
-- output is therefore not valid
ValidQxSI <= '0';
end if;
-- if channels were mismatched both counters have to be flushed
-- same behaviour if input is not valid
if ChannelMismatchedxS = '1' or ValidDxS = '0' then
CntAxD <= (others => '0');
CntBxD <= (others => '0');
ValidQxSI <= '0';
end if;
end if;
end if;
end process ChannelCounters;
-- purpose: delay input data stream
-- type : sequential
-- inputs : ClkxC, ResetxRNA, DxD, DxE
-- outputs: DelayedxD
InputDelay : process (ClkxC, ResetxRNA) is
begin -- process InputDelay
if ResetxRNA = '0' then -- asynchronous reset (active low)
DelayedxD <= '0';
elsif rising_edge(ClkxC) then -- rising clock edge
if DxE = '1' then
DelayedxD <= DxD;
end if;
end if;
end process InputDelay;
-- purpose: generate output enable signal
-- type : sequential
-- inputs : ClkxC, ResetxRNA, DxE, BChanxE
-- outputs: QxEI
GenOutEnable : process (ClkxC, ResetxRNA) is
begin -- process GenOutEnable
if ResetxRNA = '0' then -- asynchronous reset (active low)
QxEI <= '0';
elsif rising_edge(ClkxC) then -- rising clock edge
if DxE = '1' and BChanxE = '1' then
-- generate output enable signal when channel B is received
QxEI <= '1';
else
QxEI <= '0';