]> jspc29.x-matter.uni-frankfurt.de Git - soda.git/commitdiff
Source files added for a complete (?) soda-chain comprised of source, hub and client
authorPeter Lemmens <p.j.j.lemmens@rug.nl>
Wed, 4 Sep 2013 06:22:58 +0000 (08:22 +0200)
committerPeter Lemmens <p.j.j.lemmens@rug.nl>
Wed, 4 Sep 2013 06:22:58 +0000 (08:22 +0200)
Source is tested in test-benches (functional tests)

source/TB_soda_chain.vhd [new file with mode: 0644]
source/TB_soda_source.vhd [new file with mode: 0644]
source/soda_calibration_timer.vhd [new file with mode: 0644]
source/soda_client.vhd [new file with mode: 0644]
source/soda_hub.vhd [new file with mode: 0644]
source/soda_reply_handler.vhd [new file with mode: 0644]
source/soda_reply_pkt_builder.vhd [new file with mode: 0644]

diff --git a/source/TB_soda_chain.vhd b/source/TB_soda_chain.vhd
new file mode 100644 (file)
index 0000000..8190462
--- /dev/null
@@ -0,0 +1,203 @@
+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.trb_net16_hub_func.all;
+--     use work.trb3_components.all; 
+--     use work.med_sync_define.all;
+--     use work.version.all;
+use work.soda_components.all;
+
+
+entity TB_soda_chain is
+end entity;
+\r
+architecture TestBench of TB_soda_chain is\r
+\r
+ -- Clock period definitions
+ constant clk_period: time:= 4ns;
+\r
+\r
+--Inputs
+       signal rst_S                                                    : std_logic;
+       signal clk_S                                                    : std_logic;
+       signal enable_S                                         : std_logic := '0';
+       signal SOB_S                                                    : std_logic := '0';
+       signal src_dnstream_dlm_word_S  : std_logic_vector(7 downto 0)  := (others => '0');\r
+       signal src_dnstream_dlm_valid_S : std_logic;\r
+       signal src_upstream_dlm_word_S  : std_logic_vector(7 downto 0)  := (others => '0');\r
+       signal src_upstream_dlm_valid_S : std_logic;\r
+
+       signal hub_dnstream_dlm_word_S  : t_HUB_DLM_WORD;\r
+       signal hub_dnstream_dlm_valid_S : t_HUB_DLM;\r
+       signal hub_upstream_dlm_word_S  : t_HUB_DLM_WORD;\r
+       signal hub_upstream_dlm_valid_S : t_HUB_DLM;\r
+
+       --SODA
+       signal soda_ack                                         : std_logic;
+       signal soda_write                                               : std_logic     := '0';
+       signal soda_read                                                : std_logic     := '0';
+       signal soda_data_in                                     : std_logic_vector(31 downto 0) := (others => '0');
+       signal soda_src_data_out                        : std_logic_vector(31 downto 0);
+       signal soda_hub_data_out                        : std_logic_vector(31 downto 0);
+       signal soda_clt_data_out                        : std_logic_vector(31 downto 0);
+       signal soda_addr                                                : std_logic_vector(3 downto 0)  := (others => '0');
+       signal soda_leds                                                : std_logic_vector(3 downto 0);\r
+begin\r
+\r
+       THE_SODA_SOURCE : soda_source
+               port map(
+                       SYSCLK                                  => clk_S,
+                       RESET                                           => rst_S,
+                       CLEAR                                           => '0',
+                       CLK_EN                                  => '1',
+                       --Internal Connection
+                       SODA_BURST_PULSE_IN     => SOB_S,
+                       RX_DLM_WORD_IN                  => src_upstream_dlm_word_S,
+                       RX_DLM_IN                               => src_upstream_dlm_valid_S,
+                       TX_DLM_OUT                              => src_dnstream_dlm_valid_S, 
+                       TX_DLM_WORD_OUT         => src_dnstream_dlm_word_S,
+
+                       SODA_DATA_IN                    => soda_data_in,
+                       SODA_DATA_OUT                   => soda_src_data_out,
+                       SODA_ADDR_IN                    => soda_addr,
+                       SODA_READ_IN                    => soda_read,
+                       SODA_WRITE_IN                   => soda_write,
+                       SODA_ACK_OUT                    => soda_ack,\r
+                       LEDS_OUT                                        =>      soda_leds,
+                       TEST_LINE                               =>      open,\r
+                       STAT                                            =>      open
+               );
+
+       A_SODA_HUB : soda_hub
+               port map(
+                       SYSCLK                                  => clk_S,
+                       RESET                                           => rst_S,
+                       CLEAR                                           => '0',
+                       CLK_EN                                  => '1',
+                       --Internal Connection
+                       RXTOP_DLM_WORD_IN               => src_dnstream_dlm_word_S,
+                       RXTOP_DLM_IN                    => src_dnstream_dlm_valid_S,
+                       TXTOP_DLM_OUT                   => src_upstream_dlm_valid_S,
+                       TXTOP_DLM_WORD_OUT      => src_upstream_dlm_word_S,
+
+                       RXBTM_DLM_WORD_IN               => hub_upstream_dlm_word_S,
+                       RXBTM_DLM_IN                    => hub_upstream_dlm_valid_S,
+                       TXBTM_DLM_OUT                   => hub_dnstream_dlm_valid_S,
+                       TXBTM_DLM_WORD_OUT      => hub_dnstream_dlm_word_S,
+
+                       SODA_DATA_IN                    => soda_data_in,
+                       SODA_DATA_OUT                   => soda_hub_data_out,
+                       SODA_ADDR_IN                    => soda_addr,
+                       SODA_READ_IN                    => soda_read,
+                       SODA_WRITE_IN                   => soda_write,
+                       SODA_ACK_OUT                    => soda_ack,\r
+                       STAT                                            =>      open
+               );
+
+       channel :  for i in c_HUB_CHILDREN-1 downto 0 generate
+\r
+               A_SODA_CLIENT : soda_client
+                       port map(
+                               SYSCLK                                  => clk_S,
+                               RESET                                           => rst_S,
+                               CLEAR                                           => '0',
+                               CLK_EN                                  => '1',
+                               --Internal Connection
+                               RX_DLM_WORD_IN                  => hub_dnstream_dlm_word_S(i),
+                               RX_DLM_IN                               => hub_dnstream_dlm_valid_S(i),
+                               TX_DLM_OUT                              => hub_upstream_dlm_valid_S(i),
+                               TX_DLM_WORD_OUT         => hub_upstream_dlm_word_S(i),
+
+                               SODA_DATA_IN                    => soda_data_in,
+                               SODA_DATA_OUT                   => soda_clt_data_out,
+                               SODA_ADDR_IN                    => soda_addr,
+                               SODA_READ_IN                    => soda_read,
+                               SODA_WRITE_IN                   => soda_write,
+                               SODA_ACK_OUT                    => soda_ack,\r
+                               STAT                                            =>      open
+                       );
+
+       end generate;
+
+\r
+------------------------------------------------------------------------------------------------------------
+ -- SODA command packet
+------------------------------------------------------------------------------------------------------------
+       cmd_proc        :process
+       begin
+               wait for 2us;
+                               soda_addr                       <=      "0000";
+                               soda_data_in            <= x"08000000";         -- soda_reset
+                               soda_write                      <= '1';
+               wait for clk_period;
+                               soda_write                      <= '0';
+               wait for clk_period;
+                               soda_addr                       <=      "0000";
+                               soda_data_in            <= x"00000000";         -- soda_reset
+                               soda_write                      <= '1';
+               wait for clk_period;
+                               soda_write                      <= '0';
+------------------------------------------------------------------------------------------------------------
+               wait for 2us;
+                               soda_addr                       <=      "0100";
+                               soda_data_in            <= x"FFFFFFFD";         -- 
+                               soda_write                      <= '1';
+               wait for clk_period;
+                               soda_write                      <= '0';
+------------------------------------------------------------------------------------------------------------
+               wait for 700us;
+                               soda_addr                       <=      "0000";
+                               soda_data_in            <= x"40000000";         -- time_calibration
+                               soda_write                      <= '1';
+               wait for clk_period;
+                               soda_write                      <= '0';
+------------------------------------------------------------------------------------------------------------
+               wait for 700us;
+                               soda_addr                       <=      "0100";
+                               soda_data_in            <= x"FFFFFFFE";         -- time_calibration
+                               soda_write                      <= '1';
+               wait for clk_period;
+                               soda_write                      <= '0';
+------------------------------------------------------------------------------------------------------------
+               wait for 100us;
+                               soda_addr                       <=      "1001";
+                               soda_read                       <= '1';
+               wait for clk_period;
+                               soda_read                       <= '0';
+       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;
+\r
+ burst_proc :process
+ begin
+SOB_S <= '0';
+wait for 2.35us;
+SOB_S <= '1';
+wait for 50ns;
+ end process; 
+
+\r
+end TestBench;\r
+\r
diff --git a/source/TB_soda_source.vhd b/source/TB_soda_source.vhd
new file mode 100644 (file)
index 0000000..6b7c6dd
--- /dev/null
@@ -0,0 +1,139 @@
+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.trb_net16_hub_func.all;
+--     use work.trb3_components.all; 
+--     use work.med_sync_define.all;
+--     use work.version.all;
+use work.soda_components.all;
+
+
+entity TB_soda_source_child is
+end entity;
+\r
+architecture TestBench of TB_soda_source_child is\r
+\r
+ -- Clock period definitions
+ constant clk_period: time:= 4ns;
+\r
+\r
+--Inputs
+       signal rst_S                                                    : std_logic;
+       signal clk_S                                                    : std_logic;
+       signal enable_S                                         : std_logic := '0';
+       signal SOB_S                                                    : std_logic := '0';
+       signal src_dnstream_dlm_word_S  : std_logic_vector(7 downto 0)  := (others => '0');\r
+       signal src_dnstream_dlm_valid_S : std_logic;\r
+       signal src_upstream_dlm_word_S  : std_logic_vector(7 downto 0)  := (others => '0');\r
+       signal src_upstream_dlm_valid_S : std_logic;\r
+
+       --SODA
+       signal soda_ack                                         : std_logic;
+       signal soda_write                                               : std_logic     := '0';
+       signal soda_read                                                : std_logic     := '0';
+       signal soda_data_in                                     : std_logic_vector(31 downto 0) := (others => '0');
+       signal soda_data_out                                    : std_logic_vector(31 downto 0);
+       signal soda_addr                                                : std_logic_vector(3 downto 0)  := (others => '0');
+       signal soda_leds                                                : std_logic_vector(3 downto 0);\r
+begin\r
+\r
+       THE_SODA_SOURCE : soda_source
+               port map(
+                       SYSCLK                                  => clk_S,
+                       RESET                                           => rst_S,
+                       CLEAR                                           => '0',
+                       CLK_EN                                  => '1',
+                       --Internal Connection
+                       SODA_BURST_PULSE_IN     => SOB_S,
+                       RX_DLM_WORD_IN                  => src_upstream_dlm_word_S,
+                       RX_DLM_IN                               => src_upstream_dlm_valid_S,
+                       TX_DLM_OUT                              => src_dnstream_dlm_valid_S, 
+                       TX_DLM_WORD_OUT         => src_dnstream_dlm_word_S,
+
+                       SODA_DATA_IN                    => soda_data_in,
+                       SODA_DATA_OUT                   => soda_data_out,
+                       SODA_ADDR_IN                    => soda_addr,
+                       SODA_READ_IN                    => soda_read,
+                       SODA_WRITE_IN                   => soda_write,
+                       SODA_ACK_OUT                    => soda_ack,\r
+                       LEDS_OUT                                        =>      soda_leds,
+                       TEST_LINE                               =>      open,\r
+                       STAT                                            =>      open
+               );
+
+
+               A_SODA_CLIENT : soda_client
+                       port map(
+                               SYSCLK                                  => clk_S,
+                               RESET                                           => rst_S,
+                               CLEAR                                           => '0',
+                               CLK_EN                                  => '1',
+                               --Internal Connection
+                               RX_DLM_WORD_IN                  => src_dnstream_dlm_word_S,
+                               RX_DLM_IN                               => src_dnstream_dlm_valid_S,
+                               TX_DLM_OUT                              => src_upstream_dlm_valid_S,
+                               TX_DLM_WORD_OUT         => src_upstream_dlm_word_S,
+
+                               SODA_DATA_IN                    => soda_data_in,
+                               SODA_DATA_OUT                   => soda_data_out,
+                               SODA_ADDR_IN                    => soda_addr,
+                               SODA_READ_IN                    => soda_read,
+                               SODA_WRITE_IN                   => soda_write,
+                               SODA_ACK_OUT                    => soda_ack,\r
+                               STAT                                            =>      open
+                       );
+
+------------------------------------------------------------------------------------------------------------
+ -- SODA command packet
+------------------------------------------------------------------------------------------------------------
+       cmd_proc        :process
+       begin
+wait for 2us;
+               soda_addr                       <=      "0000";
+               soda_data_in            <= x"08000000";         -- soda_reset
+               soda_write                      <= '1';
+wait for clk_period;
+               soda_write                      <= '0';
+wait for 700us;
+               soda_data_in            <= x"40000000";         -- time_calibration
+               soda_write                      <= '1';
+wait for clk_period;
+               soda_write                      <= '0';
+
+       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;
+\r
+burst_proc :process
+       begin
+               SOB_S <= '0';
+               wait for 2.35us;
+               SOB_S <= '1';
+               wait for 50ns;
+       end process; 
+
+\r
+end TestBench;\r
+\r
diff --git a/source/soda_calibration_timer.vhd b/source/soda_calibration_timer.vhd
new file mode 100644 (file)
index 0000000..658a53f
--- /dev/null
@@ -0,0 +1,63 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+--use ieee.numeric_std.all;\r
+--use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+\r
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb_net16_hub_func.all; \r
+use work.soda_components.all;
+\r
+entity soda_calibration_timer is\r
+       port(\r
+               SYSCLK                                          : in    std_logic; -- fabric clock\r
+               RESET                                                   : in    std_logic; -- synchronous reset\r
+               CLEAR                                                   : in    std_logic; -- asynchronous reset\r
+               CLK_EN                                          : in    std_logic; \r
+               --Internal Connection\r
+               START_CALIBRATION                       : in    std_logic := '0';\r
+               END_CALIBRATION                 : in    std_logic := '0';\r
+               CALIB_VALID_OUT                 : out   std_logic := '0';       -- 
+               CALIB_TIME_OUT                          : out   std_logic_vector(7 downto 0) := (others => '0')\r
+       );\r
+end soda_calibration_timer;\r
+\r
+architecture Behavioral of soda_calibration_timer is\r
+
+       signal  calibration_running_S   : std_logic     := '0';\r
+       signal  calibration_timer_S             : std_logic_vector(7 downto 0)  := (others => '0');             -- from super-burst-nr-generator\r
+\r
+begin\r
+\r
+       packet_fsm_proc : process(SYSCLK)--, RESET, packet_state_S, crc_valid_S, START_OF_SUPERBURST, soda_cmd_strobe_S)\r
+       begin\r
+               if rising_edge(SYSCLK) then\r
+                       if (RESET='1') then
+                               CALIB_VALID_OUT                                 <= '0';\r
+                               CALIB_TIME_OUT                                          <= (others => '0');
+                               calibration_running_S                   <= '0';
+                               calibration_timer_S                             <=      (others => '0');\r
+                       else
+                               if (START_CALIBRATION='1') then
+                                       calibration_running_S           <= '1';
+                                       calibration_timer_S                     <= (others => '0');
+                                       CALIB_VALID_OUT                         <= '0';\r
+                                       CALIB_TIME_OUT                                  <= (others => '0');
+                               elsif (END_CALIBRATION='1') then
+                                       calibration_running_S           <= '0';
+                                       CALIB_VALID_OUT                         <= '1';\r
+                                       CALIB_TIME_OUT                                  <= calibration_timer_S;
+                               elsif (calibration_timer_S= 255) then
+                                       calibration_running_S           <= '0';
+                                       CALIB_VALID_OUT                         <= '1';\r
+                                       CALIB_TIME_OUT                                  <= calibration_timer_S;
+                               elsif (calibration_running_S='1') then
+                                       calibration_timer_S                     <= calibration_timer_S + 1;
+                               end if;\r
+                       end if;\r
+               end if;\r
+       end process;\r
+\r
+end architecture;
\ No newline at end of file
diff --git a/source/soda_client.vhd b/source/soda_client.vhd
new file mode 100644 (file)
index 0000000..20c4762
--- /dev/null
@@ -0,0 +1,188 @@
+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.trb_net16_hub_func.all; 
+use work.soda_components.all;
+
+entity soda_client 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; 
+
+               RX_DLM_WORD_IN                  : in    std_logic_vector(7 downto 0)    := (others => '0');
+               RX_DLM_IN                               : in std_logic;
+               TX_DLM_OUT                              : out   std_logic;
+               TX_DLM_WORD_OUT         : out   std_logic_vector(7 downto 0)    := (others => '0');
+
+               SODA_DATA_IN                    : in    std_logic_vector(31 downto 0)   := (others => '0');
+               SODA_DATA_OUT                   : out   std_logic_vector(31 downto 0)   := (others => '0');
+               SODA_ADDR_IN                    : in    std_logic_vector(3 downto 0)    := (others => '0');
+               SODA_READ_IN                    : in    std_logic := '0';
+               SODA_WRITE_IN                   : in    std_logic := '0';
+               SODA_ACK_OUT                    : out   std_logic := '0';
+               STAT                                            : out  std_logic_vector(31 downto 0) := (others => '0') -- DEBUG
+       );
+end soda_client;
+
+architecture Behavioral of soda_client is
+
+       --SODA
+
+       signal enable_S                                         : std_logic := '0';
+       signal soda_cmd_word_S                          : std_logic_vector(30 downto 0) := (others => '0');
+       signal soda_cmd_valid_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 crc_data_S                                               : std_logic_vector(7 downto 0)  := (others => '0');
+       signal crc_valid_S                                      : std_logic := '0';
+       
+-- Signals
+  type STATES is (SLEEP,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE);
+  signal CURRENT_STATE, NEXT_STATE: STATES;
+
+  -- slave bus signals
+  signal bus_ack_x        : std_logic;
+  signal bus_ack          : std_logic;
+  signal store_wr_x       : std_logic;
+  signal store_wr         : std_logic;
+  signal store_rd_x       : std_logic;
+  signal store_rd         : std_logic;
+  signal buf_bus_data_out : std_logic_vector(31 downto 0);
+
+begin
+       
+       packet_handler : soda_packet_handler
+               port map(
+                       SYSCLK                                          =>      SYSCLK,
+                       RESET                                                   => RESET,
+                       CLEAR                                                   =>      '0',
+                       CLK_EN                                          =>      '1',
+                       --Internal Connection
+                       START_OF_SUPERBURST             => start_of_superburst_S,
+                       SUPER_BURST_NR                          => super_burst_nr_S,
+                       SODA_CMD_VALID_S                        => soda_cmd_valid_S,
+                       SODA_CMD_WORD_S                 => soda_cmd_word_S,
+                       CRC_VALID_OUT                           => crc_valid_S,\r
+                       CRC_DATA_OUT                            => crc_data_S,
+                       RX_DLM_IN                                       => RX_DLM_IN,
+                       RX_DLM_WORD_IN                          => RX_DLM_WORD_IN
+               );
+
+       reply_packet_builder : soda_reply_pkt_builder           \r
+               port map(
+                       SYSCLK                                  =>      SYSCLK,
+                       RESET                                           =>      RESET,
+                       CLEAR                                           =>      '0',
+                       CLK_EN                                  => CLK_EN,
+                       --Internal Connection
+                       START_OF_SUPERBURST     => start_of_superburst_S,
+                       SUPER_BURST_NR_IN               => super_burst_nr_S,
+                       SODA_CMD_STROBE_IN      => soda_cmd_valid_S,
+                       SODA_CMD_WORD_IN                => soda_cmd_word_S,
+                       TX_DLM_OUT                              => TX_DLM_OUT,
+                       TX_DLM_WORD_OUT         => TX_DLM_WORD_OUT
+               );
+
+---------------------------------------------------------
+-- RegIO Statemachine
+---------------------------------------------------------
+       STATE_MEM: process( SYSCLK)
+       begin
+               if( rising_edge(SYSCLK) ) then
+                       if( RESET = '1' ) then
+                               CURRENT_STATE <= SLEEP;
+                               bus_ack       <= '0';
+                               store_wr      <= '0';
+                               store_rd      <= '0';
+                       else
+                               CURRENT_STATE <= NEXT_STATE;
+                               bus_ack       <= bus_ack_x;
+                               store_wr      <= store_wr_x;
+                       store_rd      <= store_rd_x;
+                       end if;
+               end if;
+       end process STATE_MEM;
+
+-- Transition matrix
+       TRANSFORM: process(CURRENT_STATE, SODA_READ_IN, SODA_WRITE_IN )
+       begin
+               NEXT_STATE <= SLEEP;
+               bus_ack_x  <= '0';
+               store_wr_x <= '0';
+               store_rd_x <= '0';
+               case CURRENT_STATE is
+                       when SLEEP    =>
+                               if   ( (SODA_READ_IN = '1') ) then
+                                       NEXT_STATE <= RD_RDY;
+                                       store_rd_x <= '1';
+                               elsif( (SODA_WRITE_IN = '1') ) then
+                                       NEXT_STATE <= WR_RDY;
+                                       store_wr_x <= '1';
+                               else
+                                       NEXT_STATE <= SLEEP;
+                               end if;
+                       when RD_RDY    =>
+                               NEXT_STATE <= RD_ACK;
+                       when WR_RDY    =>
+                               NEXT_STATE <= WR_ACK;
+                       when RD_ACK    =>
+                               if( SODA_READ_IN = '0' ) then
+                                       NEXT_STATE <= DONE;
+                                       bus_ack_x  <= '1';
+                               else
+                                       NEXT_STATE <= RD_ACK;
+                                       bus_ack_x  <= '1';
+                               end if;
+                       when WR_ACK    =>
+                               if( SODA_WRITE_IN = '0' ) then
+                                       NEXT_STATE <= DONE;
+                                       bus_ack_x  <= '1';
+                               else
+                                       NEXT_STATE <= WR_ACK;
+                                       bus_ack_x  <= '1';
+                               end if;
+                       when DONE    =>
+                               NEXT_STATE <= SLEEP;
+                       when others    =>
+                               NEXT_STATE <= SLEEP;
+       end case;
+end process TRANSFORM;
+
+
+---------------------------------------------------------
+-- data handling                                       --
+---------------------------------------------------------
+-- For sim purposes the CLIENT gets addresses 11XX
+-- register write
+       THE_WRITE_REG_PROC: process( SYSCLK )
+       begin
+               if( rising_edge(SYSCLK) ) then
+                       if   ( RESET = '1' ) then
+                       elsif( (store_wr = '1') and (SODA_ADDR_IN = B"1100") ) then
+                       end if;
+               end if;
+       end process THE_WRITE_REG_PROC;
+  
+-- register read
+       THE_READ_REG_PROC: process( SYSCLK )
+       begin
+               if( rising_edge(SYSCLK) ) then
+                       if   ( RESET = '1' ) then
+                               buf_bus_data_out        <= (others => '0');
+                       elsif( (store_rd = '1') and (SODA_ADDR_IN = B"1100") ) then
+                               buf_bus_data_out        <= '0' & soda_cmd_word_S;
+                       end if;
+               end if;
+       end process THE_READ_REG_PROC;
+
+-- output signals
+       SODA_DATA_OUT   <= buf_bus_data_out;
+       SODA_ACK_OUT    <= bus_ack;
+
+end architecture;
\ No newline at end of file
diff --git a/source/soda_hub.vhd b/source/soda_hub.vhd
new file mode 100644 (file)
index 0000000..d8b6a6d
--- /dev/null
@@ -0,0 +1,325 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.std_logic_unsigned.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb_net16_hub_func.all; 
+use work.soda_components.all;
+
+entity soda_hub 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; 
+       --      SINGLE DUBPLEX LINK TO THE TOP
+               RXTOP_DLM_IN                            : in    std_logic;
+               RXTOP_DLM_WORD_IN                       : in    std_logic_vector(7 downto 0)    := (others => '0');
+               TXTOP_DLM_OUT                           : out   std_logic;
+               TXTOP_DLM_WORD_OUT              : out   std_logic_vector(7 downto 0)    := (others => '0');
+       --      MULTIPLE DUPLEX LINKS TO THE BOTTOM
+               RXBTM_DLM_IN                            : in    t_HUB_DLM;                      -- typedef in soda_components.vhd
+               RXBTM_DLM_WORD_IN                       : in    t_HUB_DLM_WORD; -- typedef in soda_components.vhd
+               TXBTM_DLM_OUT                           : out   t_HUB_DLM;                      -- typedef in soda_components.vhd
+               TXBTM_DLM_WORD_OUT              : out   t_HUB_DLM_WORD; -- typedef in soda_components.vhd
+
+               SODA_DATA_IN                            : in    std_logic_vector(31 downto 0)   := (others => '0');
+               SODA_DATA_OUT                           : out   std_logic_vector(31 downto 0)   := (others => '0');
+               SODA_ADDR_IN                            : in    std_logic_vector(3 downto 0)    := (others => '0');
+               SODA_READ_IN                            : in    std_logic := '0';
+               SODA_WRITE_IN                           : in    std_logic := '0';
+               SODA_ACK_OUT                            : out   std_logic := '0';
+               STAT                                                    : out  std_logic_vector(31 downto 0) := (others => '0') -- DEBUG
+       );
+end soda_hub;
+
+architecture Behavioral of soda_hub is
+
+       --SODA
+       signal enable_S                                         : std_logic := '0';
+       signal soda_cmd_word_S                          : std_logic_vector(30 downto 0) := (others => '0');
+       signal soda_cmd_valid_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 crc_data_S                                               : std_logic_vector(7 downto 0)  := (others => '0');
+       signal crc_valid_S                                      : std_logic := '0';
+       
+-- Signals
+       type STATES is (SLEEP,RD_RDY,WR_RDY,RD_ACK,WR_ACK,DONE);
+       signal CURRENT_STATE, NEXT_STATE: STATES;
+
+       signal last_packet_sent_S                       : t_PACKET_TYPE_SENT;
+       signal expected_reply_S                         : std_logic_vector(7 downto 0);
+       signal reply_valid_S                                    : t_HUB_BIT_ARRAY;
+       signal reply_OK_S                                               : t_HUB_BIT_ARRAY;
+       signal start_calibration_S                      : std_logic;
+       signal calibration_valid_S                      : t_HUB_BIT_ARRAY;
+       signal calibration_time_S                       : t_HUB_BYTE_ARRAY;
+       
+       
+-- slave bus signals
+       signal bus_ack_x                                                : std_logic;
+       signal bus_ack                                                  : std_logic;
+       signal store_wr_x                                               : std_logic;
+       signal store_wr                                         : std_logic;
+       signal store_rd_x                                               : std_logic;
+       signal store_rd                                         : std_logic;
+       signal buf_bus_data_out                         : std_logic_vector(31 downto 0);
+
+       signal dead_channels_S                          : std_logic_vector(31 downto 0) := (others => '0');
+       signal channel_status_S                         : std_logic_vector(31 downto 0) := (others => '0');
+       signal calib_register_S                         : t_HUB_WORD_ARRAY;
+       
+       begin
+       
+       hub_packet_handler : soda_packet_handler
+               port map(
+                       SYSCLK                                          =>      SYSCLK,
+                       RESET                                                   => RESET,
+                       CLEAR                                                   =>      '0',
+                       CLK_EN                                          =>      '1',
+                       --Internal Connection
+                       START_OF_SUPERBURST             => start_of_superburst_S,
+                       SUPER_BURST_NR                          => super_burst_nr_S,
+                       SODA_CMD_VALID_S                        => soda_cmd_valid_S,
+                       SODA_CMD_WORD_S                 => soda_cmd_word_S,
+                       EXPECTED_REPLY_OUT              =>      expected_reply_S,
+                       CRC_VALID_OUT                           => crc_valid_S,\r
+                       CRC_DATA_OUT                            => crc_data_S,
+                       RX_DLM_IN                                       => RXTOP_DLM_IN,
+                       RX_DLM_WORD_IN                          => RXTOP_DLM_WORD_IN
+               );
+
+       reply_packet_builder : soda_reply_pkt_builder           \r
+               port map(
+                       SYSCLK                                  =>      SYSCLK,
+                       RESET                                           =>      RESET,
+                       CLEAR                                           =>      '0',
+                       CLK_EN                                  => CLK_EN,
+                       --Internal Connection
+                       START_OF_SUPERBURST     => start_of_superburst_S,
+                       SUPER_BURST_NR_IN               => super_burst_nr_S,
+                       SODA_CMD_STROBE_IN      => soda_cmd_valid_S,
+                       SODA_CMD_WORD_IN                => soda_cmd_word_S,
+                       TX_DLM_OUT                              => TXTOP_DLM_OUT,
+                       TX_DLM_WORD_OUT         => TXTOP_DLM_WORD_OUT
+               );
+
+       channel :for i in c_HUB_CHILDREN-1 downto 0 generate
+                       
+               packet_builder : soda_packet_builder
+                       port map(
+                               SYSCLK                                  =>      SYSCLK,
+                               RESET                                           =>      RESET,
+                               CLEAR                                           =>      '0',
+                               CLK_EN                                  => CLK_EN,
+                               --Internal Connection
+                               SODA_CMD_STROBE_IN      => soda_cmd_valid_S,
+                               START_OF_SUPERBURST     => start_of_superburst_S,
+                               SUPER_BURST_NR_IN               => super_burst_nr_S,
+                               SODA_CMD_WORD_IN                => soda_cmd_word_S,
+                               EXPECTED_REPLY_OUT      => open,
+                               TIME_CAL_OUT                    =>      start_calibration_S,
+                               TX_DLM_OUT                              => TXBTM_DLM_OUT(i),
+                               TX_DLM_WORD_OUT         => TXBTM_DLM_WORD_OUT(i)
+                       );
+                       
+       hub_reply_handler : soda_reply_handler
+               port map(
+                       SYSCLK                                          =>      SYSCLK,
+                       RESET                                                   => RESET,
+                       CLEAR                                                   =>      '0',
+                       CLK_EN                                          =>      '1',
+                       --Internal Connection
+                       LAST_PACKET                                     =>      last_packet_sent_S,
+                       EXPECTED_REPLY_IN                       => expected_reply_S,
+                       RX_DLM_IN                                       => RXBTM_DLM_IN(i),
+                       RX_DLM_WORD_IN                          => RXBTM_DLM_WORD_IN(i),
+                       REPLY_VALID_OUT                 => reply_valid_S(i),\r
+                       REPLY_OK_OUT                            => reply_OK_S(i)
+               );
+
+       hub_calibration_timer : soda_calibration_timer\r
+               port map(
+                       SYSCLK                                          =>      SYSCLK,
+                       RESET                                                   => RESET,
+                       CLEAR                                                   =>      '0',
+                       CLK_EN                                          =>      '1',
+                       --Internal Connection
+                       START_CALIBRATION                       =>      start_calibration_S,\r
+                       END_CALIBRATION                 =>      reply_valid_S(i),\r
+                       CALIB_VALID_OUT                 =>      calibration_valid_S(i),
+                       CALIB_TIME_OUT                          =>      calibration_time_S(i)\r
+               );
+               
+       hub_store_calib_proc  : process(SYSCLK)
+       begin
+               if rising_edge(SYSCLK) then
+                       if( RESET = '1' ) then
+                               calib_register_S(i)                                     <= (others => '0');
+                       else
+                               calib_register_S(i)(7 downto 0) <= calibration_time_S(i);
+                       end if;
+               end if;
+       end process;
+
+       -----------------------------------------------------------
+       --      Reply status report                                                                                             --
+       -----------------------------------------------------------
+               reply_report_proc : process(SYSCLK)
+               begin
+                       if rising_edge(SYSCLK) then
+                               if( RESET = '1' ) then
+                                       channel_status_S(i)     <= '0';
+                               elsif (reply_valid_S(i)='1') then
+                                       channel_status_S(i)     <= reply_OK_S(i) or dead_channels_S(i);
+                               else 
+                                       channel_status_S(i)     <= '0';
+                               end if;
+                       end if;
+               end process;
+
+       end generate;
+
+-----------------------------------------------------------
+--     Reset the unused bits of channel_status_S                                       --
+-----------------------------------------------------------
+       other_bits :for j in 31 downto c_HUB_CHILDREN generate
+               init_unused_bits_proc : process(SYSCLK)
+               begin
+                       if rising_edge(SYSCLK) then
+                               if( RESET = '1' ) then
+                                       channel_status_S(j)     <= '0';         -- reset status bits
+                               end if;
+                       end if;
+               end process;
+       end generate;
+
+-----------------------------------------------------------
+--     Transmission history for reply-checking                                 --
+-----------------------------------------------------------
+       packet_history_proc : process(SYSCLK)
+       begin
+               if rising_edge(SYSCLK) then
+                       if( RESET = '1' ) then
+                               last_packet_sent_S      <= c_NO_PACKET;
+                       elsif (start_of_superburst_S='1') then
+                               last_packet_sent_S      <= c_BST_PACKET;
+                       elsif (soda_cmd_valid_S='1') then
+                               last_packet_sent_S      <= c_CMD_PACKET;
+                       end if;
+               end if;
+       end process;
+
+---------------------------------------------------------
+-- RegIO Statemachine
+---------------------------------------------------------
+       STATE_MEM: process( SYSCLK)
+       begin
+               if( rising_edge(SYSCLK) ) then
+                       if( RESET = '1' ) then
+                               CURRENT_STATE <= SLEEP;
+                               bus_ack <= '0';
+                               store_wr<= '0';
+                               store_rd<= '0';
+                       else
+                               CURRENT_STATE <= NEXT_STATE;
+                               bus_ack <= bus_ack_x;
+                               store_wr<= store_wr_x;
+                       store_rd<= store_rd_x;
+                       end if;
+               end if;
+       end process STATE_MEM;
+
+-- Transition matrix
+       TRANSFORM: process(CURRENT_STATE, SODA_READ_IN, SODA_WRITE_IN )
+       begin
+               NEXT_STATE <= SLEEP;
+               bus_ack_x<= '0';
+               store_wr_x <= '0';
+               store_rd_x <= '0';
+               case CURRENT_STATE is
+                       when SLEEP    =>
+                               if   ( (SODA_READ_IN = '1') ) then
+                                       NEXT_STATE <= RD_RDY;
+                                       store_rd_x <= '1';
+                               elsif( (SODA_WRITE_IN = '1') ) then
+                                       NEXT_STATE <= WR_RDY;
+                                       store_wr_x <= '1';
+                               else
+                                       NEXT_STATE <= SLEEP;
+                               end if;
+                       when RD_RDY    =>
+                               NEXT_STATE <= RD_ACK;
+                       when WR_RDY    =>
+                               NEXT_STATE <= WR_ACK;
+                       when RD_ACK    =>
+                               if( SODA_READ_IN = '0' ) then
+                                       NEXT_STATE <= DONE;
+                                       bus_ack_x  <= '1';
+                               else
+                                       NEXT_STATE <= RD_ACK;
+                                       bus_ack_x  <= '1';
+                               end if;
+                       when WR_ACK    =>
+                               if( SODA_WRITE_IN = '0' ) then
+                                       NEXT_STATE <= DONE;
+                                       bus_ack_x  <= '1';
+                               else
+                                       NEXT_STATE <= WR_ACK;
+                                       bus_ack_x  <= '1';
+                               end if;
+                       when DONE    =>
+                               NEXT_STATE <= SLEEP;
+                       when others    =>
+                               NEXT_STATE <= SLEEP;
+       end case;
+end process TRANSFORM;
+
+
+---------------------------------------------------------
+-- data handling                                       --
+---------------------------------------------------------
+-- For sim purposes the HUB gets addresses 01XX
+-- register write
+       THE_WRITE_REG_PROC: process( SYSCLK )
+       begin
+               if( rising_edge(SYSCLK) ) then
+                       if   ( RESET = '1' ) then
+                               -- do NOT reset dead_channels; This is a task for slow-control ONLY
+                       elsif( (store_wr = '1') and (SODA_ADDR_IN = "0100") ) then      -- \r
+                               dead_channels_S <= SODA_DATA_IN(31 downto 0);
+                       end if;
+               end if;
+       end process THE_WRITE_REG_PROC;
+  
+-- register read
+       THE_READ_REG_PROC: process( SYSCLK )
+       begin
+               if( rising_edge(SYSCLK) ) then
+                       if   ( RESET = '1' ) then
+                               buf_bus_data_out        <= (others => '0');
+                       elsif( (store_rd = '1') and (SODA_ADDR_IN = B"0100") ) then
+                               buf_bus_data_out        <= '0' & soda_cmd_word_S;
+                       elsif( (store_rd = '1') and (SODA_ADDR_IN = B"0101") ) then
+                               buf_bus_data_out        <= channel_status_S;
+                       elsif( (store_rd = '1') and (SODA_ADDR_IN = B"0110") ) then
+                               buf_bus_data_out        <= dead_channels_S;
+                       elsif( (store_rd = '1') and (SODA_ADDR_IN(3 downto 2) = "10") ) then
+                               for j in 0 to c_HUB_CHILDREN-1 loop
+                                       if (j=conv_integer(SODA_ADDR_IN(1 downto 0))) then
+                                               buf_bus_data_out        <= calib_register_S(j);
+                                       end if;
+                               end loop;
+                       end if;
+               end if;
+       end process THE_READ_REG_PROC;
+-- output signals
+       SODA_DATA_OUT   <= buf_bus_data_out;
+       SODA_ACK_OUT    <= bus_ack;
+
+end architecture;
\ No newline at end of file
diff --git a/source/soda_reply_handler.vhd b/source/soda_reply_handler.vhd
new file mode 100644 (file)
index 0000000..4d33d05
--- /dev/null
@@ -0,0 +1,75 @@
+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.trb_net16_hub_func.all; \r
+use work.soda_components.all;
+
+entity soda_reply_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
+               LAST_PACKET                                     : in    t_PACKET_TYPE_SENT      := c_NO_PACKET;
+               EXPECTED_REPLY_IN                       : in    std_logic_vector(7 downto 0) := (others => '0');
+               RX_DLM_IN                                       : in    std_logic       := '0';
+               RX_DLM_WORD_IN                          : in    std_logic_vector(7 downto 0)    := (others => '0');
+               REPLY_VALID_OUT                 : out std_logic := '0';
+--             SUPERBURST_ERROR_OUT            : out std_logic := '0';
+--             CRC_ERROR_OUT                           : out std_logic := '0';
+               REPLY_OK_OUT                            : out std_logic := '0'
+       );
+end soda_reply_handler;
+
+architecture Behavioral of soda_reply_handler is
+
+       type            packet_state_type is (  c_RST, c_IDLE, c_ERROR, c_REPLY, c_DONE);
+       signal  packet_state_S                          :       packet_state_type := c_IDLE;
+
+begin
+
+       reply_fsm_proc : process(SYSCLK)
+       begin
+               if rising_edge(SYSCLK) then\r
+                       if (RESET='1') then
+                               REPLY_VALID_OUT <= '0';
+                               REPLY_OK_OUT            <= '0';
+                               packet_state_S          <= c_IDLE;
+                       else
+                               REPLY_VALID_OUT <= '0';
+                               case packet_state_S is\r
+                                       when c_IDLE     =>\r
+                                               if (RX_DLM_IN='1') then
+                                                       packet_state_S          <= c_REPLY;
+                                                       REPLY_VALID_OUT <= '1';
+                                                       if (EXPECTED_REPLY_IN = RX_DLM_WORD_IN) then
+                                                               REPLY_OK_OUT    <= '1';
+                                                       else
+                                                               REPLY_OK_OUT    <= '0';
+                                                       end if;
+                                               end if;
+                                       when c_REPLY =>
+                                               if (RX_DLM_IN='0') then\r
+                                                       REPLY_VALID_OUT <= '1';
+                                                       packet_state_S          <= c_IDLE;
+                                               else
+                                                       packet_state_S          <= c_ERROR;\r
+                                               end if;
+                                       when c_ERROR    =>
+                                               packet_state_S                  <= c_IDLE;
+                                               REPLY_OK_OUT    <= '0';
+                                               REPLY_OK_OUT                    <= '0';
+                                       when others =>
+                                               packet_state_S                  <= c_IDLE;
+                                               REPLY_OK_OUT    <= '0';
+                               end case;
+                       end if;\r
+               end if;
+       end process;
+\r
+end architecture;
\ No newline at end of file
diff --git a/source/soda_reply_pkt_builder.vhd b/source/soda_reply_pkt_builder.vhd
new file mode 100644 (file)
index 0000000..ccb1349
--- /dev/null
@@ -0,0 +1,77 @@
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+\r
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb_net16_hub_func.all; \r
+use work.soda_components.all;
+\r
+entity soda_reply_pkt_builder is\r
+       port(\r
+               SYSCLK                                  : in    std_logic; -- fabric clock\r
+               RESET                                           : in    std_logic; -- synchronous reset\r
+               CLEAR                                           : in    std_logic; -- asynchronous reset\r
+               CLK_EN                                  : in    std_logic; \r
+               --Internal Connection\r
+               START_OF_SUPERBURST     : in    std_logic := '0';\r
+               SUPER_BURST_NR_IN               : in    std_logic_vector(30 downto 0) := (others => '0');\r
+               SODA_CMD_STROBE_IN      : in    std_logic := '0';       -- \r
+               SODA_CMD_WORD_IN                : in    std_logic_vector(30 downto 0) := (others => '0');               --REGIO_CTRL_REG in trbnet handler is 32 bit\r
+               TX_DLM_OUT                              : out   std_logic := '0';       -- 
+               TX_DLM_WORD_OUT         : out   std_logic_vector(7 downto 0) := (others => '0')\r
+       );\r
+end soda_reply_pkt_builder;\r
+\r
+architecture Behavioral of soda_reply_pkt_builder is\r
+
+       type            packet_state_type is    (       c_IDLE, c_PKT1, c_PKT2 );\r
+       signal  packet_state_S                          :       packet_state_type := c_IDLE;\r
+\r
+begin\r
+       
+       reply_fsm_proc : process(SYSCLK)
+       begin
+               if rising_edge(SYSCLK) then\r
+                       if (RESET='1') then
+                               packet_state_S          <= c_IDLE;
+                       else
+                               case packet_state_S is\r
+                                       when c_IDLE     =>\r
+                                               if (START_OF_SUPERBURST='1') or (SODA_CMD_STROBE_IN='1') then\r
+                                                       packet_state_S  <= c_PKT1;\r
+                                               end if;
+                                       when c_PKT1 =>
+                                               packet_state_S  <= c_PKT2;\r
+                                       when c_PKT2 =>
+                                               packet_state_S  <= c_IDLE;\r
+                                       when others =>
+                                               packet_state_S  <= c_IDLE;
+                               end case;
+                       end if;\r
+               end if;
+       end process;
+
+       collect_reply_proc : process(SYSCLK)
+       begin
+               if rising_edge(SYSCLK) then\r
+                       if (RESET='1') then
+                               TX_DLM_OUT                      <= '0';\r
+                               TX_DLM_WORD_OUT <= (others=>'0');
+                       elsif (START_OF_SUPERBURST='1') then\r
+                               TX_DLM_OUT                      <= '1';\r
+                               TX_DLM_WORD_OUT <= SUPER_BURST_NR_IN(7 downto 0);\r
+                       elsif (SODA_CMD_STROBE_IN='1') then\r
+                               TX_DLM_OUT                      <= '1';\r
+                               TX_DLM_WORD_OUT <= SODA_CMD_WORD_IN(7 downto 0);
+                       elsif (packet_state_S=c_PKT1) then
+                               TX_DLM_OUT                      <= '0';\r
+                       elsif (packet_state_S=c_PKT2) then
+                               TX_DLM_WORD_OUT <= (others=>'0');
+                       end if;\r
+               end if;
+       end process;
+       \r
+\r
+end architecture;
\ No newline at end of file