-
BRONES Romain authored
* Do not allow to start CRC computation right after a result * CRC word counter up to 12 then roll over to 0
BRONES Romain authored* Do not allow to start CRC computation right after a result * CRC word counter up to 12 then roll over to 0
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
combpm_protocol_electron.vhd 18.31 KiB
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity combpm_protocol_electron is
port(
rst_n : in std_logic;
clk : in std_logic;
pps : in std_logic;
mc_time : in std_logic_vector(39 downto 0);
-- GT interface
gt_datarx : in std_logic_vector(15 downto 0);
gt_interfaceready : in std_logic;
-- AXIS interface
m_axi_tid : out std_logic_vector(0 downto 0);
m_axi_tdest : out std_logic_vector(9 downto 0);
m_axi_tdata : out std_logic_vector(127 downto 0);
m_axi_tstrb : out std_logic_vector(15 downto 0);
m_axi_tkeep : out std_logic_vector(15 downto 0);
m_axi_tlast : out std_logic;
m_axi_tuser : out std_logic_vector(0 downto 0);
m_axi_tvalid : out std_logic;
m_axi_tready : in std_logic;
-- Status and control interface
soft_reset : in std_logic;
frame_seq_cnt : out std_logic_vector(15 downto 0);
frame_valid_cnt : out std_logic_vector(15 downto 0);
frame_invalid_cnt : out std_logic_vector(15 downto 0);
frame_valid_rate : out std_logic_vector(15 downto 0);
frame_invalid_rate : out std_logic_vector(15 downto 0);
cnt_seq_mismatch : out std_logic;
seq_discontinuity : out std_logic;
frame_error : out std_logic
);
end entity combpm_protocol_electron;
architecture rtl of combpm_protocol_electron is
--------------------------
-- CONSTANT DECLARATION --
--------------------------
constant C_SOP : std_logic_vector(15 downto 0) := x"5CFB";
constant C_EOP : std_logic_vector(15 downto 0) := x"FDFE";
constant C_DUMMY : std_logic_vector(31 downto 0) := x"12345678";
constant C_RSVD : std_logic_vector(31 downto 0) := x"00000000";
constant C_CRCINIT : std_logic_vector(31 downto 0) := x"FFFFFFFF";
------------------------
-- SIGNAL DECLARATION --
------------------------
signal packet_reg : std_logic_vector(14*16-1 downto 0); -- Register to hold one packet
signal flag_sop_inc : std_logic;
signal flag_sop : std_logic;
signal flag_eop : std_logic;
signal flag_dummy : std_logic;
signal flag_rsvd : std_logic;
signal flag_crc : std_logic;
signal flag_all : std_logic;
signal flag_frame : std_logic;
signal packet_bpmid : std_logic_vector(9 downto 0);
signal packet_startframe : std_logic;
signal packet_timestamp : std_logic_vector(15 downto 0);
signal packet_xpos : std_logic_vector(31 downto 0);
signal packet_ypos : std_logic_vector(31 downto 0);
signal packet_crc : std_logic_vector(31 downto 0);
signal crc_result : std_logic_vector(31 downto 0);
signal xorinv_crc_reg : std_logic_vector(31 downto 0);
signal inv_crc_reg : std_logic_vector(31 downto 0);
signal crc_reg : std_logic_vector(31 downto 0);
signal lfsr_c : std_logic_vector(31 downto 0);
signal crc_cnt : unsigned(3 downto 0);
signal d : std_logic_vector(15 downto 0);
signal last_seq : std_logic_vector(15 downto 0);
signal last_cnt_seq_r : unsigned(15 downto 0);
signal cnt_frame_seq_r : unsigned(15 downto 0);
signal cnt_valid_r : unsigned(15 downto 0);
signal cnt_invalid_r : unsigned(15 downto 0);
signal rate_valid_r : unsigned(15 downto 0);
signal rate_invalid_r : unsigned(15 downto 0);
begin
---------------------
-- PACKET REGISTER --
---------------------
p_packetreg:process(clk, rst_n)
begin
if rst_n = '0' then
packet_reg <= (others => '0');
elsif rising_edge(clk) then
-- Simple shift register, 16 bits width, 14 word long
for I in 2 to 14 loop
packet_reg(I*16-1 downto (I-1)*16) <= packet_reg((I-1)*16-1 downto (I-2)*16);
end loop;
-- swap bytes in input (first byte is LSB)
packet_reg(15 downto 0) <= gt_datarx(7 downto 0) & gt_datarx(15 downto 8);
end if;
end process;
------------------------
-- PACKET CHECK FLAGS --
------------------------
flag_sop <= '1' when packet_reg(14*16-1 downto 13*16) = C_SOP else
'0';
flag_sop_inc <= '1' when packet_reg(15 downto 0) = C_SOP else
'0';
flag_eop <= '1' when packet_reg(15 downto 0) = C_EOP else
'0';
flag_dummy <= '1' when packet_reg(7*16-1 downto 5*16) = C_DUMMY else
'0';
flag_rsvd <= '1' when packet_reg(5*16-1 downto 3*16) = C_RSVD else
'0';
flag_crc <= '1' when packet_crc = crc_result else
'0';
-- Any and all flag
flag_all <= flag_sop and flag_eop and flag_dummy and flag_rsvd and flag_crc and gt_interfaceready;
flag_frame <= flag_sop and flag_eop and gt_interfaceready;
----------------------------
-- FRAME FIELD EXTRACTION --
----------------------------
packet_bpmid <= packet_reg(185 downto 176);
packet_startframe <= packet_reg(191);
packet_timestamp <= packet_reg(13*16-1 downto 12*16);
packet_xpos <= packet_reg(11*16-1 downto 9*16);
packet_ypos <= packet_reg(9*16-1 downto 7*16);
packet_crc <= packet_reg(3*16-1 downto 16);
-----------------
-- CRC CHECKER --
-----------------
-- RefIn
gen_invert: for I in 0 to 7 generate
d(I) <= packet_reg(7-I);
d(I+8) <= packet_reg(7-I+8);
end generate;
-- RefOut
xorinv_crc_reg <= inv_crc_reg xor x"FFFFFFFF";
gen: for I in 0 to 31 generate
inv_crc_reg(I) <= crc_reg(31-I);
end generate;
-- Byte reorder
crc_result(7 downto 0) <= xorinv_crc_reg(31 downto 24);
crc_result(15 downto 8) <= xorinv_crc_reg(23 downto 16);
crc_result(23 downto 16) <= xorinv_crc_reg(15 downto 8);
crc_result(31 downto 24) <= xorinv_crc_reg(7 downto 0);
-- Register
p_crc:process(clk, rst_n)
begin
if rst_n = '0' then
crc_reg <= C_CRCINIT;
crc_cnt <= (others => '0');
elsif rising_edge(clk) then
case crc_cnt is
when "0000" =>
if flag_sop_inc = '1' then
crc_cnt <= crc_cnt+1;
crc_reg <= C_CRCINIT;
else
crc_cnt <= (others => '0');
end if;
when "1011" =>
crc_reg <= crc_reg;
crc_cnt <= crc_cnt+1;
when "1100" =>
crc_reg <= crc_reg;
crc_cnt <= (others => '0');
when others =>
crc_reg <= lfsr_c;
crc_cnt <= crc_cnt+1;
end case;
end if;
end process p_crc;
-- Combinatorial, 16 turns unrolled
lfsr_c(0) <= crc_reg(16) xor crc_reg(22) xor crc_reg(25) xor crc_reg(26) xor crc_reg(28) xor d(0) xor d(6) xor d(9) xor d(10) xor d(12);
lfsr_c(1) <= crc_reg(16) xor crc_reg(17) xor crc_reg(22) xor crc_reg(23) xor crc_reg(25) xor crc_reg(27) xor crc_reg(28) xor crc_reg(29) xor d(0) xor d(1) xor d(6) xor d(7) xor d(9) xor d(11) xor d(12) xor d(13);
lfsr_c(2) <= crc_reg(16) xor crc_reg(17) xor crc_reg(18) xor crc_reg(22) xor crc_reg(23) xor crc_reg(24) xor crc_reg(25) xor crc_reg(29) xor crc_reg(30) xor d(0) xor d(1) xor d(2) xor d(6) xor d(7) xor d(8) xor d(9) xor d(13) xor d(14);
lfsr_c(3) <= crc_reg(17) xor crc_reg(18) xor crc_reg(19) xor crc_reg(23) xor crc_reg(24) xor crc_reg(25) xor crc_reg(26) xor crc_reg(30) xor crc_reg(31) xor d(1) xor d(2) xor d(3) xor d(7) xor d(8) xor d(9) xor d(10) xor d(14) xor d(15);
lfsr_c(4) <= crc_reg(16) xor crc_reg(18) xor crc_reg(19) xor crc_reg(20) xor crc_reg(22) xor crc_reg(24) xor crc_reg(27) xor crc_reg(28) xor crc_reg(31) xor d(0) xor d(2) xor d(3) xor d(4) xor d(6) xor d(8) xor d(11) xor d(12) xor d(15);
lfsr_c(5) <= crc_reg(16) xor crc_reg(17) xor crc_reg(19) xor crc_reg(20) xor crc_reg(21) xor crc_reg(22) xor crc_reg(23) xor crc_reg(26) xor crc_reg(29) xor d(0) xor d(1) xor d(3) xor d(4) xor d(5) xor d(6) xor d(7) xor d(10) xor d(13);
lfsr_c(6) <= crc_reg(17) xor crc_reg(18) xor crc_reg(20) xor crc_reg(21) xor crc_reg(22) xor crc_reg(23) xor crc_reg(24) xor crc_reg(27) xor crc_reg(30) xor d(1) xor d(2) xor d(4) xor d(5) xor d(6) xor d(7) xor d(8) xor d(11) xor d(14);
lfsr_c(7) <= crc_reg(16) xor crc_reg(18) xor crc_reg(19) xor crc_reg(21) xor crc_reg(23) xor crc_reg(24) xor crc_reg(26) xor crc_reg(31) xor d(0) xor d(2) xor d(3) xor d(5) xor d(7) xor d(8) xor d(10) xor d(15);
lfsr_c(8) <= crc_reg(16) xor crc_reg(17) xor crc_reg(19) xor crc_reg(20) xor crc_reg(24) xor crc_reg(26) xor crc_reg(27) xor crc_reg(28) xor d(0) xor d(1) xor d(3) xor d(4) xor d(8) xor d(10) xor d(11) xor d(12);
lfsr_c(9) <= crc_reg(17) xor crc_reg(18) xor crc_reg(20) xor crc_reg(21) xor crc_reg(25) xor crc_reg(27) xor crc_reg(28) xor crc_reg(29) xor d(1) xor d(2) xor d(4) xor d(5) xor d(9) xor d(11) xor d(12) xor d(13);
lfsr_c(10) <= crc_reg(16) xor crc_reg(18) xor crc_reg(19) xor crc_reg(21) xor crc_reg(25) xor crc_reg(29) xor crc_reg(30) xor d(0) xor d(2) xor d(3) xor d(5) xor d(9) xor d(13) xor d(14);
lfsr_c(11) <= crc_reg(16) xor crc_reg(17) xor crc_reg(19) xor crc_reg(20) xor crc_reg(25) xor crc_reg(28) xor crc_reg(30) xor crc_reg(31) xor d(0) xor d(1) xor d(3) xor d(4) xor d(9) xor d(12) xor d(14) xor d(15);
lfsr_c(12) <= crc_reg(16) xor crc_reg(17) xor crc_reg(18) xor crc_reg(20) xor crc_reg(21) xor crc_reg(22) xor crc_reg(25) xor crc_reg(28) xor crc_reg(29) xor crc_reg(31) xor d(0) xor d(1) xor d(2) xor d(4) xor d(5) xor d(6) xor d(9) xor d(12) xor d(13) xor d(15);
lfsr_c(13) <= crc_reg(17) xor crc_reg(18) xor crc_reg(19) xor crc_reg(21) xor crc_reg(22) xor crc_reg(23) xor crc_reg(26) xor crc_reg(29) xor crc_reg(30) xor d(1) xor d(2) xor d(3) xor d(5) xor d(6) xor d(7) xor d(10) xor d(13) xor d(14);
lfsr_c(14) <= crc_reg(18) xor crc_reg(19) xor crc_reg(20) xor crc_reg(22) xor crc_reg(23) xor crc_reg(24) xor crc_reg(27) xor crc_reg(30) xor crc_reg(31) xor d(2) xor d(3) xor d(4) xor d(6) xor d(7) xor d(8) xor d(11) xor d(14) xor d(15);
lfsr_c(15) <= crc_reg(19) xor crc_reg(20) xor crc_reg(21) xor crc_reg(23) xor crc_reg(24) xor crc_reg(25) xor crc_reg(28) xor crc_reg(31) xor d(3) xor d(4) xor d(5) xor d(7) xor d(8) xor d(9) xor d(12) xor d(15);
lfsr_c(16) <= crc_reg(0) xor crc_reg(16) xor crc_reg(20) xor crc_reg(21) xor crc_reg(24) xor crc_reg(28) xor crc_reg(29) xor d(0) xor d(4) xor d(5) xor d(8) xor d(12) xor d(13);
lfsr_c(17) <= crc_reg(1) xor crc_reg(17) xor crc_reg(21) xor crc_reg(22) xor crc_reg(25) xor crc_reg(29) xor crc_reg(30) xor d(1) xor d(5) xor d(6) xor d(9) xor d(13) xor d(14);
lfsr_c(18) <= crc_reg(2) xor crc_reg(18) xor crc_reg(22) xor crc_reg(23) xor crc_reg(26) xor crc_reg(30) xor crc_reg(31) xor d(2) xor d(6) xor d(7) xor d(10) xor d(14) xor d(15);
lfsr_c(19) <= crc_reg(3) xor crc_reg(19) xor crc_reg(23) xor crc_reg(24) xor crc_reg(27) xor crc_reg(31) xor d(3) xor d(7) xor d(8) xor d(11) xor d(15);
lfsr_c(20) <= crc_reg(4) xor crc_reg(20) xor crc_reg(24) xor crc_reg(25) xor crc_reg(28) xor d(4) xor d(8) xor d(9) xor d(12);
lfsr_c(21) <= crc_reg(5) xor crc_reg(21) xor crc_reg(25) xor crc_reg(26) xor crc_reg(29) xor d(5) xor d(9) xor d(10) xor d(13);
lfsr_c(22) <= crc_reg(6) xor crc_reg(16) xor crc_reg(25) xor crc_reg(27) xor crc_reg(28) xor crc_reg(30) xor d(0) xor d(9) xor d(11) xor d(12) xor d(14);
lfsr_c(23) <= crc_reg(7) xor crc_reg(16) xor crc_reg(17) xor crc_reg(22) xor crc_reg(25) xor crc_reg(29) xor crc_reg(31) xor d(0) xor d(1) xor d(6) xor d(9) xor d(13) xor d(15);
lfsr_c(24) <= crc_reg(8) xor crc_reg(17) xor crc_reg(18) xor crc_reg(23) xor crc_reg(26) xor crc_reg(30) xor d(1) xor d(2) xor d(7) xor d(10) xor d(14);
lfsr_c(25) <= crc_reg(9) xor crc_reg(18) xor crc_reg(19) xor crc_reg(24) xor crc_reg(27) xor crc_reg(31) xor d(2) xor d(3) xor d(8) xor d(11) xor d(15);
lfsr_c(26) <= crc_reg(10) xor crc_reg(16) xor crc_reg(19) xor crc_reg(20) xor crc_reg(22) xor crc_reg(26) xor d(0) xor d(3) xor d(4) xor d(6) xor d(10);
lfsr_c(27) <= crc_reg(11) xor crc_reg(17) xor crc_reg(20) xor crc_reg(21) xor crc_reg(23) xor crc_reg(27) xor d(1) xor d(4) xor d(5) xor d(7) xor d(11);
lfsr_c(28) <= crc_reg(12) xor crc_reg(18) xor crc_reg(21) xor crc_reg(22) xor crc_reg(24) xor crc_reg(28) xor d(2) xor d(5) xor d(6) xor d(8) xor d(12);
lfsr_c(29) <= crc_reg(13) xor crc_reg(19) xor crc_reg(22) xor crc_reg(23) xor crc_reg(25) xor crc_reg(29) xor d(3) xor d(6) xor d(7) xor d(9) xor d(13);
lfsr_c(30) <= crc_reg(14) xor crc_reg(20) xor crc_reg(23) xor crc_reg(24) xor crc_reg(26) xor crc_reg(30) xor d(4) xor d(7) xor d(8) xor d(10) xor d(14);
lfsr_c(31) <= crc_reg(15) xor crc_reg(21) xor crc_reg(24) xor crc_reg(25) xor crc_reg(27) xor crc_reg(31) xor d(5) xor d(8) xor d(9) xor d(11) xor d(15);
--------------
-- AXIS OUT --
--------------
-- Static data
m_axi_tstrb <= (others => '1');
m_axi_tkeep <= (others => '1');
m_axi_tid <= "0";
m_axi_tuser <= "0";
m_axi_tlast <= '1'; -- One transfer is One packet.
p_axis:process(clk, rst_n)
begin
if rst_n = '0' then
m_axi_tdata <= (others => '0');
m_axi_tvalid <= '0';
m_axi_tdest <= (others => '0');
elsif rising_edge(clk) then
if flag_all = '1' then
-- Make AXIS packet
m_axi_tdata(31 downto 0) <= packet_ypos;
m_axi_tdata(63 downto 32) <= packet_xpos;
m_axi_tdata(103 downto 64) <= mc_time;
m_axi_tdata(111 downto 104) <= packet_timestamp(7 downto 0);
m_axi_tdata(127 downto 112) <= "000000" & packet_bpmid;
-- AXIS ancillary data
m_axi_tdest <= packet_bpmid;
-- AXIS TVALID
m_axi_tvalid <= '1';
else
-- Acknowledge transfer
if m_axi_tready = '1' then
m_axi_tvalid <= '0';
end if;
end if;
end if;
end process p_axis;
------------------------
-- CONTROL AND STATUS --
------------------------
frame_error <= flag_frame and not flag_all;
frame_valid_cnt <= std_logic_vector(cnt_valid_r);
frame_invalid_cnt <= std_logic_vector(cnt_invalid_r);
frame_seq_cnt <= std_logic_vector(last_cnt_seq_r);
-- frame counter
p_framecnt:process(clk, rst_n)
begin
if rst_n = '0' then
cnt_frame_seq_r <= (others => '0');
cnt_valid_r <= (others => '0');
cnt_invalid_r <= (others => '0');
rate_valid_r <= (others => '0');
rate_invalid_r <= (others => '0');
frame_valid_rate<= (others => '0');
frame_invalid_rate<= (others => '0');
last_seq <= (others => '0');
last_cnt_seq_r <= (others => '0');
seq_discontinuity <= '0';
cnt_seq_mismatch <= '0';
elsif rising_edge(clk) then
if soft_reset = '1' then
cnt_frame_seq_r <= (others => '0');
cnt_valid_r <= (others => '0');
cnt_invalid_r <= (others => '0');
rate_valid_r <= (others => '0');
rate_invalid_r <= (others => '0');
frame_valid_rate<= (others => '0');
frame_invalid_rate<= (others => '0');
last_seq <= (others => '0');
last_cnt_seq_r <= (others => '0');
seq_discontinuity <= '0';
cnt_seq_mismatch <= '0';
else
-- Valid frame counter
if flag_all = '1' then
cnt_valid_r <= cnt_valid_r+1;
end if;
-- Invalid frame counter
if (flag_frame and not flag_all) = '1' then
cnt_invalid_r <= cnt_invalid_r+1;
end if;
-- Rate counter
if pps = '1' then
frame_valid_rate <= std_logic_vector(rate_valid_r);
frame_invalid_rate <= std_logic_vector(rate_invalid_r);
rate_valid_r <= (others => '0');
rate_invalid_r <= (others => '0');
else
-- Valid frame rate counter
if flag_all = '1' then
rate_valid_r <= rate_valid_r+1;
end if;
-- Invalid frame rate counter
if (flag_frame and not flag_all) = '1' then
rate_invalid_r <= rate_invalid_r+1;
end if;
end if;
-- Sequence detection
cnt_seq_mismatch <= '0'; -- Supercharged in logic below
seq_discontinuity <= '0'; -- Supercharged in logic below
if flag_all = '1' then
if last_seq = packet_timestamp then
-- Same sequence
cnt_frame_seq_r <= cnt_frame_seq_r+1;
else
-- New sequence
cnt_frame_seq_r <= (others => '0');
last_seq <= packet_timestamp;
last_cnt_seq_r <= cnt_frame_seq_r;
-- Check sequence increment
if unsigned(packet_timestamp) - unsigned(last_seq) /= 1 then
seq_discontinuity <= '1';
end if;
-- Check number of frame in sequence
if last_cnt_seq_r /= cnt_frame_seq_r then
cnt_seq_mismatch <= '1';
end if;
end if;
end if;
end if;
end if;
end process p_framecnt;
end architecture rtl;