From e8253c91c7796ea12f647cb9c2c18039fd01d91a Mon Sep 17 00:00:00 2001 From: hadaq Date: Tue, 19 Mar 2013 14:36:46 +0000 Subject: [PATCH] *** empty log message *** --- soda_source/SODA_source.ldf | 6 + soda_source/TB_soda_source.vhd | 162 +++++++++++++++ soda_source/soda_d8crc8.vhd | 97 +++++++++ soda_source/soda_packet_builder.vhd | 278 ++++++++++++++++++++++++++ soda_source/soda_packet_handler.vhd | 273 +++++++++++++++++++++++++ soda_source/soda_superburst_gen.vhd | 54 +++++ soda_source/super_burst_generator.vhd | 73 +++++++ 7 files changed, 943 insertions(+) create mode 100644 soda_source/TB_soda_source.vhd create mode 100644 soda_source/soda_d8crc8.vhd create mode 100644 soda_source/soda_packet_builder.vhd create mode 100644 soda_source/soda_packet_handler.vhd create mode 100644 soda_source/soda_superburst_gen.vhd create mode 100644 soda_source/super_burst_generator.vhd diff --git a/soda_source/SODA_source.ldf b/soda_source/SODA_source.ldf index d3299ff..d704f73 100644 --- a/soda_source/SODA_source.ldf +++ b/soda_source/SODA_source.ldf @@ -288,6 +288,12 @@ + + + + + + diff --git a/soda_source/TB_soda_source.vhd b/soda_source/TB_soda_source.vhd new file mode 100644 index 0000000..d1b5b46 --- /dev/null +++ b/soda_source/TB_soda_source.vhd @@ -0,0 +1,162 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity TB_soda_source is +end entity; + +architecture TestBench of TB_soda_source is + + -- Clock period definitions + constant clk_period : time := 4ns; + + +component super_burst_generator + generic( + BURST_COUNT : integer range 1 to 64 := 16 -- number of bursts to be counted between super-bursts + ); +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_BURST_PULSE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : out std_logic := '0'; + SUPER_BURST_NR_OUT : out std_logic_vector(30 downto 0) := (others => '0') + ); +end component; + +component soda_packet_builder + port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_CMD_STROBE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : in std_logic := '0'; + SUPER_BURST_NR_IN : in std_logic_vector(30 downto 0) := (others => '0'); + SODA_CMD_WORD_IN : in std_logic_vector(31 downto 0) := (others => '0'); --REGIO_CTRL_REG in trbnet handler is 32 bit + TX_DLM_OUT : out std_logic := '0'; -- + TX_DLM_WORD_OUT : out std_logic_vector(7 downto 0) := (others => '0') + ); +end component; + +component soda_packet_handler +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + RX_DLM_WORD_IN : in std_logic_vector(7 downto 0) := (others => '0'); + RX_DLM_IN : in std_logic + ); +end component; + +--Inputs + signal rst_S : std_logic; + signal clk_S : std_logic; + signal enable_S : std_logic := '0'; + signal soda_cmd_word_S : std_logic_vector(31 downto 0) := (others => '0'); + signal soda_cmd_strobe_S : std_logic := '0'; + signal SOS_S : std_logic := '0'; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal SOB_S : std_logic := '0'; + signal dlm_word_S : std_logic_vector(7 downto 0) := (others => '0'); + signal dlm_valid_S : std_logic; + +begin + + superburst_gen : super_burst_generator + generic map(BURST_COUNT => 16) + port map( + SYSCLK => clk_S, + RESET => rst_S, + CLEAR => '0', + CLK_EN => '0', + --Internal Connection + SODA_BURST_PULSE_IN => SOB_S, + START_OF_SUPERBURST => SOS_S, + SUPER_BURST_NR_OUT => super_burst_nr_S + ); + + packet_builder : soda_packet_builder + port map( + SYSCLK => clk_S, + RESET => rst_S, + CLEAR => '0', + CLK_EN => '0', + --Internal Connection + SODA_CMD_STROBE_IN => soda_cmd_strobe_S, + START_OF_SUPERBURST => SOS_S, + SUPER_BURST_NR_IN => super_burst_nr_S, + SODA_CMD_WORD_IN => soda_cmd_word_S, + TX_DLM_OUT => dlm_valid_S, + TX_DLM_WORD_OUT => dlm_word_S + + ); + + packet_handler : soda_packet_handler + port map( + SYSCLK => clk_S, + RESET => rst_S, + CLEAR => '0', + CLK_EN => '0', + --Internal Connection + RX_DLM_IN => dlm_valid_S, + RX_DLM_WORD_IN => dlm_word_S + ); + +------------------------------------------------------------------------------------------------------------ + -- SODA command packet +------------------------------------------------------------------------------------------------------------ + cmd_proc :process + begin + wait for 2us; + soda_cmd_word_S <= x"40000000"; + soda_cmd_strobe_S <= '1'; + wait for clk_period; + soda_cmd_strobe_S <= '0'; + wait; + end process; + +------------------------------------------------------------------------------------------------------------ + -- Clock process definitions +------------------------------------------------------------------------------------------------------------ + clk_proc :process + begin + clk_S <= '0'; + wait for clk_period/2; + clk_S <= '1'; + wait for clk_period/2; + end process; + + -- reset process + reset_proc: process + begin + rst_S <= '1'; + wait for clk_period * 5; + rst_S <= '0'; + wait; + end process; + + burst_proc :process + begin + SOB_S <= '0'; + wait for 2.35us; + SOB_S <= '1'; + wait for 50ns; + end process; + + +end TestBench; + diff --git a/soda_source/soda_d8crc8.vhd b/soda_source/soda_d8crc8.vhd new file mode 100644 index 0000000..b49827e --- /dev/null +++ b/soda_source/soda_d8crc8.vhd @@ -0,0 +1,97 @@ + +-- ######################################################################## +-- crc engine rtl design +-- copyright (c) www.electronicdesignworks.com +-- source code generated by electronicdesignworks ip generator (crc). +-- documentation can be downloaded from www.electronicdesignworks.com +-- ******************************** +--license +-- ******************************** +-- this source file may be used and distributed freely provided that this +-- copyright notice, list of conditions and the following disclaimer is +-- not removed from the file. +-- any derivative work should contain this copyright notice and associated disclaimer. +-- this source code file is provided "as is" and without any warranty, +-- without even the implied warranty of merchantability or fitness for a +-- particular purpose. +-- ******************************** +-- specification +-- ******************************** +-- file name : crc8_data8.vhd +-- description : crc engine entity +-- clock : positive edge +-- reset : active low +-- first serial: msb +-- data bus width: 8 bits +-- polynomial: (0 4 5 8) +-- date: 12-mar-2013 +-- version : 1.0 +-- ######################################################################## + +library ieee ; +use ieee.std_logic_1164.all ; +use ieee.std_logic_arith.all ; +use ieee.std_logic_unsigned.all ; +entity soda_d8crc8 is + port( + CLOCK : in std_logic; + RESET : in std_logic; + SOC : in std_logic; + DATA : in std_logic_vector(7 downto 0); + DATA_VALID : in std_logic; + EOC : in std_logic; + CRC : out std_logic_vector(7 downto 0); + CRC_VALID : out std_logic + ); +end soda_d8crc8; + +architecture behavioral of soda_d8crc8 is + signal crc_r: std_logic_vector(7 downto 0); + signal crc_c: std_logic_vector(7 downto 0); + signal crc_i: std_logic_vector(7 downto 0); + signal crc_const: std_logic_vector(7 downto 0) := "00000000"; + +begin + + + crc_i<= crc_const when soc = '1' else + crc_r; + + crc_c(0) <= DATA(0) xor DATA(3) xor DATA(4) xor crc_i(0) xor crc_i(4) xor DATA(6) xor crc_i(3) xor crc_i(6); + crc_c(1) <= data(1) xor DATA(4) xor DATA(5) xor crc_i(1) xor crc_i(5) xor DATA(7) xor crc_i(4) xor crc_i(7); + crc_c(2) <= DATA(2) xor DATA(5) xor DATA(6) xor crc_i(2) xor crc_i(6) xor crc_i(5); + crc_c(3) <= DATA(3) xor DATA(6) xor DATA(7) xor crc_i(3) xor crc_i(7) xor crc_i(6); + crc_c(4) <= DATA(0) xor DATA(7) xor crc_i(7) xor DATA(3) xor crc_i(0) xor DATA(6) xor crc_i(3) xor crc_i(6); + crc_c(5) <= DATA(0) xor DATA(1) xor crc_i(1) xor DATA(7) xor crc_i(7) xor DATA(3) xor crc_i(0) xor DATA(6) xor crc_i(3) xor crc_i(6); + crc_c(6) <= DATA(1) xor DATA(2) xor crc_i(2) xor DATA(4) xor crc_i(1) xor DATA(7) xor crc_i(4) xor crc_i(7); + crc_c(7) <= DATA(2) xor DATA(3) xor crc_i(3) xor DATA(5) xor crc_i(2) xor crc_i(5); + + + crc_gen_process : process(clock, reset) + begin + if(reset = '1') then + crc_r <= "00000000" ; + elsif rising_edge(clock) then + if(DATA_valid = '1') then + crc_r <= crc_c; + end if; + end if; + end process crc_gen_process; + + + crc_valid_gen : process(clock, reset) + begin + if(reset = '1') then + CRC_VALID <= '0'; + elsif rising_edge(clock) then + if(DATA_valid = '1' and EOC = '1') then + CRC_VALID <= '1'; + else + CRC_VALID <= '0'; + end if; + end if; + end process crc_valid_gen; + + CRC <= crc_r; + +end behavioral; \ No newline at end of file diff --git a/soda_source/soda_packet_builder.vhd b/soda_source/soda_packet_builder.vhd new file mode 100644 index 0000000..38ced54 --- /dev/null +++ b/soda_source/soda_packet_builder.vhd @@ -0,0 +1,278 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity soda_packet_builder is +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_CMD_STROBE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : in std_logic := '0'; + SUPER_BURST_NR_IN : in std_logic_vector(30 downto 0) := (others => '0'); + SODA_CMD_WORD_IN : in std_logic_vector(31 downto 0) := (others => '0'); --REGIO_CTRL_REG in trbnet handler is 32 bit + TX_DLM_OUT : out std_logic := '0'; -- + TX_DLM_WORD_OUT : out std_logic_vector(7 downto 0) := (others => '0') + ); +end soda_packet_builder; + +architecture Behavioral of soda_packet_builder is + +component soda_d8crc8 + port( + clock : in std_logic; + reset : in std_logic; + soc : in std_logic; + data : in std_logic_vector(7 downto 0); + data_valid : in std_logic; + eoc : in std_logic; + crc : out std_logic_vector(7 downto 0); + crc_valid : out std_logic + ); +end component; + +-- constant c_K287 : std_logic_vector(7 downto 0) := x"FB"; + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal soda_cmd_strobe_S : std_logic; + signal start_of_superburst_S : std_logic; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal soda_cmd_word_S : std_logic_vector(31 downto 0) := (others => '0'); -- from slowcontrol + signal soda_pkt_word_S : std_logic_vector(7 downto 0) := (others => '0'); + signal soda_pkt_valid_S : std_logic; + + signal soc_S : std_logic; + signal eoc_S : std_logic; + signal crc_data_valid_S : std_logic; + signal crc_datain_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_tmp_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_out_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_valid_S : std_logic; + + type packet_state_type is ( c_RST, c_IDLE, c_ERROR, + c_STD1, c_STD2, c_STD3, c_STD4, c_STD5, c_STD6, c_STD7, c_STD8, + c_CMD1, c_CMD2, c_CMD3, c_CMD4, c_CMD5, c_CMD6, c_CMD7, c_CMD8 + ); + signal packet_state_S : packet_state_type := c_IDLE; +-- signal packet_state_S : packet_state_type := c_IDLE; + +begin + + tx_crc8: soda_d8crc8 + port map( + clock => clk_S, + reset => rst_S, + soc => soc_S, + data => crc_datain_S, + data_valid => crc_data_valid_S, + eoc => eoc_S, + crc => crc_out_S, + crc_valid => crc_valid_S + ); + + clk_S <= SYSCLK; + rst_S <= RESET; + soda_cmd_strobe_S <= SODA_CMD_STROBE_IN; + soda_cmd_word_S <= SODA_CMD_WORD_IN; + start_of_superburst_S <= START_OF_SUPERBURST; + super_burst_nr_S <= SUPER_BURST_NR_IN; + + TX_DLM_WORD_OUT <= soda_pkt_word_S; + TX_DLM_OUT <= soda_pkt_valid_S; + +-- packet_state_S <= packet_state_S; + + packet_fsm_proc : process(clk_S, rst_S, packet_state_S, crc_valid_S, start_of_superburst_S, soda_cmd_strobe_S) + begin + if rising_edge(clk_S) then + if (rst_S='1') then + packet_state_S <= c_RST; + else + case packet_state_S is + when c_RST => + if (start_of_superburst_S='1') then + packet_state_S <= c_STD1; + elsif (soda_cmd_strobe_S='1') then + packet_state_S <= c_CMD1; + else + packet_state_S <= c_IDLE; + end if; + when c_IDLE => + if (start_of_superburst_S='1') then + packet_state_S <= c_STD1; + elsif (soda_cmd_strobe_S='1') then + packet_state_S <= c_CMD1; + end if; + when c_STD1 => + packet_state_S <= c_STD2; + when c_STD2 => + packet_state_S <= c_STD3; + when c_STD3 => + packet_state_S <= c_STD4; + when c_STD4 => + packet_state_S <= c_STD5; + when c_STD5 => + packet_state_S <= c_STD6; + when c_STD6 => + packet_state_S <= c_STD7; + when c_STD7 => + packet_state_S <= c_STD8; + when c_STD8 => + if (soda_cmd_strobe_S='0') then + packet_state_S <= c_IDLE; + else + packet_state_S <= c_CMD1; + end if; + when c_CMD1 => + packet_state_S <= c_CMD2; + when c_CMD2 => + packet_state_S <= c_CMD3; + when c_CMD3 => + packet_state_S <= c_CMD4; + when c_CMD4 => + packet_state_S <= c_CMD5; + when c_CMD5 => + packet_state_S <= c_CMD6; + when c_CMD6 => + packet_state_S <= c_CMD7; + when c_CMD7 => + if (crc_valid_S = '0') then + packet_state_S <= c_ERROR; + else + packet_state_S <= c_CMD8; + end if; + when c_CMD8 => + packet_state_S <= c_IDLE; + when c_ERROR => + packet_state_S <= c_IDLE; + when others => + packet_state_S <= c_IDLE; + end case; + end if; + end if; + end process; + + soda_packet_fill_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_IDLE => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + when c_STD1 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= '1' & super_burst_nr_S(30 downto 24); + when c_STD2 => + soda_pkt_valid_S <= '0'; + when c_STD3 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= super_burst_nr_S(23 downto 16); + when c_STD4 => + soda_pkt_valid_S <= '0'; + when c_STD5 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= super_burst_nr_S(15 downto 8); + when c_STD6 => + soda_pkt_valid_S <= '0'; + when c_STD7 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= super_burst_nr_S(7 downto 0); + when c_STD8 => + soda_pkt_valid_S <= '0'; + when c_CMD1 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= '0' & soda_cmd_word_S(30 downto 24); + when c_CMD2 => + soda_pkt_valid_S <= '0'; + when c_CMD3 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= soda_cmd_word_S(23 downto 16); + when c_CMD4 => + soda_pkt_valid_S <= '0'; + when c_CMD5 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= soda_cmd_word_S(15 downto 8); + when c_CMD6 => + soda_pkt_valid_S <= '0'; + when c_CMD7 => + soda_pkt_valid_S <= '1'; + soda_pkt_word_S <= crc_out_S; + when c_CMD8 => + soda_pkt_valid_S <= '0'; + when others => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + end case; + end if; + end process; + + + crc_gen_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_IDLE => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '1'; + eoc_S <= '0'; + when c_CMD1 => + crc_data_valid_S <= '1'; + crc_datain_S <= '0' & soda_cmd_word_S(30 downto 24); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD2 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD3 => + crc_data_valid_S <= '1'; + crc_datain_S <= soda_cmd_word_S(23 downto 16); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD4 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD5 => + crc_data_valid_S <= '1'; + crc_datain_S <= soda_cmd_word_S(15 downto 8); + soc_S <= '0'; + eoc_S <= '1'; + when c_CMD6 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD7 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when c_CMD8 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + when others => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + end case; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/soda_source/soda_packet_handler.vhd b/soda_source/soda_packet_handler.vhd new file mode 100644 index 0000000..7ff2099 --- /dev/null +++ b/soda_source/soda_packet_handler.vhd @@ -0,0 +1,273 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity soda_packet_handler is +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + RX_DLM_IN : in std_logic; + RX_DLM_WORD_IN : in std_logic_vector(7 downto 0) := (others => '0') + ); +end soda_packet_handler; + +architecture Behavioral of soda_packet_handler is + + component soda_d8crc8 + port( + clock : in std_logic; + reset : in std_logic; + soc : in std_logic; + data : in std_logic_vector(7 downto 0); + data_valid : in std_logic; + eoc : in std_logic; + crc : out std_logic_vector(7 downto 0); + crc_valid : out std_logic + ); + end component; + + constant c_K287 : std_logic_vector(7 downto 0) := x"FB"; + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal rx_dlm_in_S : std_logic; + signal rx_dlm_word_in_S : std_logic_vector(7 downto 0) := (others => '0'); + signal soda_cmd_strobe_S : std_logic; + signal start_of_superburst_S : std_logic; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal soda_cmd_word_S : std_logic_vector(30 downto 0) := (others => '0'); -- from slowcontrol + signal soda_pkt_word_S : std_logic_vector(31 downto 0) := (others => '0'); + signal soda_pkt_valid_S : std_logic; + + type packet_state_type is ( c_RST, c_IDLE, c_ERROR, + c_SODA_PKT1, c_SODA_PKT2, c_SODA_PKT3, c_SODA_PKT4, + c_SODA_PKT5, c_SODA_PKT6, c_SODA_PKT7, c_SODA_PKT8 + ); + signal packet_state_S : packet_state_type := c_IDLE; + + signal soc_S : std_logic := '1'; + signal eoc_S : std_logic := '0'; + signal crc_data_valid_S : std_logic := '0'; + signal crc_datain_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_tmp_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_out_S : std_logic_vector(7 downto 0) := (others => '0'); + signal crc_valid_S : std_logic := '0'; + + signal crc_check_S : std_logic := '0'; + signal crc_check_valid_S : std_logic := '0'; + +begin + + rx_crc8: soda_d8crc8 + port map( + clock => clk_S, + reset => rst_S, + soc => soc_S, + data => crc_datain_S, + data_valid => crc_data_valid_S, + eoc => eoc_S, + crc => crc_out_S, + crc_valid => crc_valid_S + ); + + clk_S <= SYSCLK; + rst_S <= RESET; + +-- packet_state_S <= packet_state_S; + + rx_dlm_in_S <= RX_DLM_IN; + rx_dlm_word_in_S <= RX_DLM_WORD_IN; + + packet_fsm_proc : process(clk_S) + begin + if rising_edge(clk_S) then + if (rst_S='1') then + packet_state_S <= c_RST; + else + case packet_state_S is + when c_RST => + if (rx_dlm_in_S='1') then -- received K27.7 #1 + packet_state_S <= c_SODA_PKT1; + else + packet_state_S <= c_IDLE; + end if; + when c_IDLE => + if (rx_dlm_in_S='1') then -- received K27.7 #1 + packet_state_S <= c_SODA_PKT1; + else + packet_state_S <= c_IDLE; + end if; + when c_SODA_PKT1 => + if (rx_dlm_in_S='0') then -- possibly received data-byte + packet_state_S <= c_SODA_PKT2; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT2 => + if (rx_dlm_in_S='1') then -- received K27.7 #2 + packet_state_S <= c_SODA_PKT3; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT3 => + if (rx_dlm_in_S='0') then -- possibly received data-byte + packet_state_S <= c_SODA_PKT4; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT4 => + if (rx_dlm_in_S='1') then -- received K27.7 #3 + packet_state_S <= c_SODA_PKT5; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT5 => + if (rx_dlm_in_S='0') then -- possibly received data-byte + packet_state_S <= c_SODA_PKT6; + else + packet_state_S <= c_ERROR; + end if; + when c_SODA_PKT6 => + if (rx_dlm_in_S='1') then -- received K27.7 #4 + packet_state_S <= c_SODA_PKT7; + else + packet_state_S <= c_ERROR; + -- else do nothing + end if; + when c_SODA_PKT7 => + if (rx_dlm_in_S='1') or (crc_valid_S = '0') or not(crc_out_S = RX_DLM_WORD_IN) then + packet_state_S <= c_ERROR; -- if there's an unexpected K27.7 or no valid CRC-output or the CRC-check doesn't match + else + packet_state_S <= c_SODA_PKT8; + end if; + when c_SODA_PKT8 => + if (rx_dlm_in_S='1') then -- received K27.7 #4+1... must be another packet coming in.... + packet_state_S <= c_SODA_PKT1; + else + packet_state_S <= c_IDLE; + end if; + when c_ERROR => + packet_state_S <= c_IDLE; -- TODO: Insert ERROR_HANDLER + when others => + packet_state_S <= c_IDLE; + end case; + end if; + end if; + end process; + + soda_packet_collector_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_RST => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + when c_IDLE => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + when c_SODA_PKT1 => + soda_pkt_word_S(31 downto 24) <= RX_DLM_WORD_IN; + when c_SODA_PKT2 => + -- do nothing -- disregard k27.7 + when c_SODA_PKT3 => + soda_pkt_word_S(23 downto 16) <= RX_DLM_WORD_IN; + when c_SODA_PKT4 => + -- do nothing -- disregard k27.7 + when c_SODA_PKT5 => + soda_pkt_word_S(15 downto 8) <= RX_DLM_WORD_IN; + when c_SODA_PKT6 => + -- do nothing -- disregard k27.7 + when c_SODA_PKT7 => + soda_pkt_word_S(7 downto 0) <= RX_DLM_WORD_IN; -- get transmitted CRC + when c_SODA_PKT8 => + when others => + soda_pkt_valid_S <= '0'; + soda_pkt_word_S <= (others=>'0'); + end case; + + if (soda_pkt_valid_S ='1') then + if (soda_pkt_word_S(31) = '1') then + super_burst_nr_S <= soda_pkt_word_S(30 downto 0); + start_of_superburst_S <= '1'; + else + soda_cmd_word_S <= soda_pkt_word_S(30 downto 0); + soda_cmd_strobe_S <= '1'; + end if; + else + start_of_superburst_S <= '0'; + soda_cmd_strobe_S <= '0'; + end if; + end if; + end process; + + crc_check_proc : process(clk_S, packet_state_S) + begin + if rising_edge(clk_S) then + case packet_state_S is + when c_RST => + soc_S <= '1'; + eoc_S <= '0'; + crc_check_valid_S <= '0'; + when c_IDLE => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '1'; + eoc_S <= '0'; + when c_SODA_PKT1 => + crc_data_valid_S <= '1'; + crc_datain_S <= RX_DLM_WORD_IN; + soc_S <= '0'; + when c_SODA_PKT2 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + when c_SODA_PKT3 => + crc_data_valid_S <= '1'; + crc_datain_S <= RX_DLM_WORD_IN; + when c_SODA_PKT4 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + when c_SODA_PKT5 => + crc_data_valid_S <= '1'; + crc_datain_S <= RX_DLM_WORD_IN; + eoc_S <= '1'; + when c_SODA_PKT6 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + eoc_S <= '0'; + when c_SODA_PKT7 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + if ((crc_valid_S = '1') and (crc_out_S = RX_DLM_WORD_IN)) then + crc_check_S <= '1'; + else + crc_check_S <= '0'; + end if; + crc_check_valid_S <= '1'; + when c_SODA_PKT8 => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + crc_check_S <= '0'; + crc_check_valid_S <= '0'; + when others => + crc_data_valid_S <= '0'; + crc_datain_S <= (others=>'0'); + soc_S <= '0'; + eoc_S <= '0'; + crc_check_valid_S <= '0'; + end case; + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/soda_source/soda_superburst_gen.vhd b/soda_source/soda_superburst_gen.vhd new file mode 100644 index 0000000..ade1e6c --- /dev/null +++ b/soda_source/soda_superburst_gen.vhd @@ -0,0 +1,54 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.trb_net_std.all; +use work.trb_net_components.all; +use work.trb3_components.all; +use work.med_sync_define.all; +use work.version.all; + +entity soda_packet_builder is +-- generic( +-- INTERCEPT_MODE : integer range 0 to 1 := c_NO --use the RX clock for internal logic and transmission. Should be NO for soda tests! +-- ); +port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + START_OF_BURST : in std_logic := '0'; + SUPER_BURST_NR_OUT : out std_logic_vector(30 downto 0) := (others => '0'); + SUPER_BURST_NR_VALID : out std_logic + START_OF_SUPERBURST : out std_logic + ); +end soda_packet_builder; + +architecture Behavioral of soda_packet_builder is + constant c_K287 : std_logic_vector(7 downto 0) := x"FB"; + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal soda_cmd_strobe_S : std_logic; + signal start_of_burst_S : std_logic; + signal start_of_superburst_S : std_logic; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal superburst_nr_valid_S : std_logic; + + signal burst_count_S : std_logic_vector(3 downto 0) := (others => '0'); + +begin + + clk_S <= SYSCLK; + rst_S <= RESET; + start_of_burst_S <= START_OF_BURST; + + SUPER_BURST_NR_OUT <= soda_pkt_word_S; + SUPER_BURST_NR_VALID <= soda_pkt_valid_S; + START_OF_SUPERBURST <= start_of_burst_S; + + + +end architecture; \ No newline at end of file diff --git a/soda_source/super_burst_generator.vhd b/soda_source/super_burst_generator.vhd new file mode 100644 index 0000000..db15df1 --- /dev/null +++ b/soda_source/super_burst_generator.vhd @@ -0,0 +1,73 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use IEEE.STD_LOGIC_ARITH.ALL; +use ieee.std_logic_signed.all; + +--library work; +--use work.trb_net_std.all; +--use work.trb_net_components.all; +--use work.trb3_components.all; +--use work.med_sync_define.all; +--use work.version.all; + +entity super_burst_generator is + generic( + BURST_COUNT : natural range 1 to 256 := 16 -- number of bursts to be counted between super-bursts + ); + port( + SYSCLK : in std_logic; -- fabric clock + RESET : in std_logic; -- synchronous reset + CLEAR : in std_logic; -- asynchronous reset + CLK_EN : in std_logic; + --Internal Connection + SODA_BURST_PULSE_IN : in std_logic := '0'; -- + START_OF_SUPERBURST : out std_logic := '0'; + SUPER_BURST_NR_OUT : out std_logic_vector(30 downto 0) := (others => '0') + ); +end super_burst_generator; + +architecture Behavioral of super_burst_generator is + + constant cBURST_COUNT : std_logic_vector(7 downto 0) := conv_std_logic_vector(BURST_COUNT - 1,8); + + signal clk_S : std_logic; + signal rst_S : std_logic; + signal soda_burst_pulse_S : std_logic := '0'; + signal start_of_superburst_S : std_logic := '0'; + signal super_burst_nr_S : std_logic_vector(30 downto 0) := (others => '0'); -- from super-burst-nr-generator + signal burst_counter_S : std_logic_vector(7 downto 0) := (others => '0'); -- from super-burst-nr-generator + + +begin + + clk_S <= SYSCLK; + rst_S <= RESET; + START_OF_SUPERBURST <= start_of_superburst_S; + SUPER_BURST_NR_OUT <= super_burst_nr_S; + + burst_pulse_edge_proc : process(clk_S, rst_S, SODA_BURST_PULSE_IN, soda_burst_pulse_S, burst_counter_S) + begin + if rising_edge(clk_S) then + soda_burst_pulse_S <= SODA_BURST_PULSE_IN; + if (rst_S='1') then + burst_counter_S <= cBURST_COUNT; + start_of_superburst_S <= '0'; + super_burst_nr_S <= (others => '0'); + elsif ((SODA_BURST_PULSE_IN = '1') and (soda_burst_pulse_S = '0')) then + if (burst_counter_S = x"00") then + start_of_superburst_S <= '1'; + super_burst_nr_S <= super_burst_nr_S + 1; + burst_counter_S <= cBURST_COUNT; + else + start_of_superburst_S <= '0'; + burst_counter_s <= burst_counter_s - 1; + end if; + else + start_of_superburst_S <= '0'; + end if; + end if; + end process; + + +end Behavioral; \ No newline at end of file -- 2.43.0