+library IEEE;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+
+
+entity MimosisInputMulti is
+ generic(
+ INPUT_NUMBER : integer := 8
+ );
+ port (
+ CLK : in std_logic;
+ CLK_SYS : in std_logic;
+ RESET : in std_logic;
+
+ INPUT : in std_logic_vector_array_8(0 to 7);
+
+ BUSRDO_RX : in READOUT_RX;
+ BUSRDO_TX : out READOUT_TX;
+
+ BUS_RX : in CTRLBUS_RX;
+ BUS_TX : out CTRLBUS_TX
+ );
+end entity;
+
+
+architecture arch of MimosisInputMulti is
+ constant HDR_WORD : std_logic_vector(15 downto 0) := x"FE00";
+ constant WORD_LIMIT : integer := 4000;
+ signal input_active_i : std_logic;
+ signal data_i : std_logic_vector(15 downto 0);
+ signal inp_i : std_logic_vector(7 downto 0);
+ signal word_i : std_logic_vector(31 downto 0);
+ signal word_valid : std_logic;
+
+ signal businp_rx, busword_rx, busmimosis_rx : CTRLBUS_RX;
+ signal businp_tx, busword_tx, busmimosis_tx : CTRLBUS_TX;
+
+ signal ct_fifo_afull, ct_fifo_full, ct_fifo_empty : std_logic;
+ signal ct_fifo_read, ct_fifo_valid, ct_fifo_nextvalid : std_logic;
+ signal ct_fifo_data_out : std_logic_vector(31 downto 0);
+
+ signal buffer_empty, buffer_full : std_logic;
+ signal buffer_write, buffer_read : std_logic;
+ signal buffer_valid, buffer_nextvalid : std_logic;
+ signal buffer_din, buffer_dout : std_logic_vector(31 downto 0);
+ signal buffer_fill : std_logic_vector(13 downto 0);
+
+ type state_t is (IDLE,START_COPY, START_COPY2, COPY,FINISH,DONE);
+ signal state : state_t;
+ signal word_count : integer range 0 to 8191;
+
+ signal frame_number : std_logic_vector(31 downto 0);
+ signal frame_length : std_logic_vector(15 downto 0);
+ signal count_words : unsigned(15 downto 0);
+ signal count_header : unsigned(31 downto 0);
+ signal count_trailer : unsigned(31 downto 0);
+ signal count_fe : unsigned(31 downto 0);
+ signal count_ff : unsigned(31 downto 0);
+ signal count_oof : unsigned(31 downto 0);
+ signal pulse_stats : std_logic_vector(31 downto 0);
+ signal buffer_blocked : std_logic;
+ type frame_state_t is (IDLE,HDR1,HDR2,HDR3,WRITING);
+ signal frame_state : frame_state_t;
+
+
+begin
+
+ THE_IN : entity work.InputStageMulti
+ port map (
+ CLK => CLK,
+ CLK_SYS => CLK_SYS,
+ RESET => RESET,
+
+ DIN => INPUT,
+ DOUT => data_i,
+ ACTIVE => input_active_i,
+
+ BUS_RX => businp_rx,
+ BUS_TX => businp_tx
+ );
+
+
+ THE_WORDS: entity work.WordAlign
+ port map(
+ CLK => CLK,
+ CLK_SYS => CLK_SYS,
+ RESET => RESET,
+
+ DIN => data_i,
+ DOUT => word_i,
+ VALID => word_valid,
+
+ ACTIVE => input_active_i,
+
+ BUS_RX => busword_rx,
+ BUS_TX => busword_tx
+ );
+
+
+----------------------------------------------------------------------
+-- Clock Domain Transfer
+----------------------------------------------------------------------
+THE_CT_FIFO : entity work.lattice_ecp5_fifo_36x16_dualport_oreg
+ port map(
+ Data(31 downto 0) => word_i(31 downto 0),
+ Data(35 downto 32) => "0000",
+ WrClock => CLK,
+ RdClock => CLK_SYS,
+ WrEn => word_valid,
+ RdEn => ct_fifo_read,
+ Reset => RESET,
+ RPReset => RESET,
+ Q(31 downto 0) => ct_fifo_data_out(31 downto 0),
+ Empty => ct_fifo_empty,
+ Full => ct_fifo_full,
+ AlmostFull => ct_fifo_afull
+ );
+
+ ct_fifo_read <= '1';
+ ct_fifo_nextvalid <= ct_fifo_read and not ct_fifo_empty when rising_edge(CLK_SYS);
+ ct_fifo_valid <= ct_fifo_nextvalid when rising_edge(CLK_SYS);
+
+----------------------------------------------------------------------
+-- Frame Copy
+----------------------------------------------------------------------
+
+PROC_FRAMES : process begin
+ wait until rising_edge(CLK_SYS);
+ buffer_write <= '0';
+ buffer_din <= ct_fifo_data_out;
+
+ if ct_fifo_valid = '1' then
+ count_words <= count_words + 1;
+ end if;
+
+ if ct_fifo_valid = '1' and ct_fifo_data_out(31 downto 24) = x"FE" then
+ count_fe <= count_fe + 1;
+ end if;
+
+ if ct_fifo_valid = '1' and ct_fifo_data_out(31 downto 24) = x"FF" then
+ count_ff <= count_ff + 1;
+ end if;
+
+ if ct_fifo_valid = '1' and ct_fifo_data_out(31 downto 24) < x"FC" and frame_state = IDLE then
+ count_oof <= count_oof + 1;
+ end if;
+
+ case frame_state is
+ when IDLE =>
+ count_words <= (others => '0');
+ if ct_fifo_valid = '1' and ct_fifo_data_out(31 downto 24) = x"FE" then
+ frame_state <= HDR1;
+ frame_number(15 downto 0) <= ct_fifo_data_out(7 downto 0) & ct_fifo_data_out(23 downto 16);
+ buffer_write <= '1' when buffer_full = '0' and state = IDLE else '0';
+ buffer_blocked <= '0' when buffer_full = '0' and state = IDLE else '1';
+ count_header <= count_header + 1;
+ end if;
+ when HDR1 =>
+ if ct_fifo_valid = '1' then
+ frame_state <= HDR2;
+ frame_number(31 downto 16) <= ct_fifo_data_out(7 downto 0) & ct_fifo_data_out(23 downto 16);
+ buffer_write <= not buffer_blocked;
+ end if;
+ when HDR2 =>
+ if ct_fifo_valid = '1' then
+ frame_state <= HDR3;
+ buffer_din(23 downto 16) <= pulse_stats(7 downto 0);
+ buffer_din(7 downto 0) <= pulse_stats(15 downto 8);
+ buffer_write <= not buffer_blocked;
+ end if;
+ when HDR3 =>
+ if ct_fifo_valid = '1' then
+ frame_state <= WRITING;
+ buffer_din(23 downto 16) <= pulse_stats(23 downto 16);
+ buffer_din(7 downto 0) <= pulse_stats(31 downto 24);
+ buffer_write <= not buffer_blocked;
+ end if;
+ when WRITING =>
+ buffer_write <= ct_fifo_valid and not buffer_blocked;
+ if ct_fifo_valid = '1' and ct_fifo_data_out(31 downto 24) = x"FF" then
+ frame_state <= IDLE;
+ frame_length <= std_logic_vector(count_words);
+ count_trailer <= count_trailer + 1;
+ end if;
+ if ct_fifo_valid = '1' and ct_fifo_data_out(31 downto 24) = x"FE" and count_words >= x"0004" then
+ frame_state <= HDR1;
+ count_header <= count_header + 1;
+ frame_number(15 downto 0) <= ct_fifo_data_out(7 downto 0) & ct_fifo_data_out(23 downto 16);
+ buffer_write <= not buffer_full;
+ buffer_blocked <= buffer_full;
+ end if;
+ end case;
+
+ end process;
+
+
+
+----------------------------------------------------------------------
+-- Main Fifo
+----------------------------------------------------------------------
+THE_FIFO : entity work.fifo_36x8k_oreg
+ port map(
+ Data(31 downto 0) => buffer_din,
+ Clock => CLK_SYS,
+ WrEn => buffer_write,
+ RdEn => buffer_read,
+ Reset => RESET,
+ AmFullThresh => "0010000000000",
+ Q(31 downto 0) => buffer_dout,
+ WCNT => buffer_fill,
+ Empty => buffer_empty,
+ Full => open,
+ AlmostFull => buffer_full
+ );
+
+ buffer_nextvalid <= buffer_read and not buffer_empty when rising_edge(CLK_SYS);
+ buffer_valid <= buffer_nextvalid when rising_edge(CLK_SYS);
+
+---------------------------------------------------------------------------
+-- Buffer Handler
+---------------------------------------------------------------------------
+PROC_RDO : process begin
+ wait until rising_edge(CLK_SYS);
+-- if state = IDLE and buffer_full = '1' then
+-- buffer_read <= '1';
+-- else
+ buffer_read <= '0';
+-- end if;
+
+
+ BUSRDO_TX.busy_release <= '0';
+ BUSRDO_TX.data_write <= '0';
+ BUSRDO_TX.data_finished <= '0';
+
+ case state is
+ when IDLE =>
+ if BUSRDO_RX.valid_timing_trg = '1' or BUSRDO_RX.valid_notiming_trg = '1' then
+ state <= START_COPY;
+ buffer_read <= '1';
+ word_count <= 0;
+ end if;
+ if BUSRDO_RX.invalid_trg = '1' then
+ state <= FINISH;
+ end if;
+
+ when START_COPY =>
+ state <= START_COPY2;
+ buffer_read <= '1';
+ word_count <= word_count + 1;
+
+ when START_COPY2 =>
+ state <= COPY;
+ buffer_read <= '1';
+ word_count <= word_count + 1;
+
+ when COPY =>
+
+ if word_count = WORD_LIMIT or buffer_valid = '0' then
+ state <= FINISH;
+ else
+ buffer_read <= '1';
+ word_count <= word_count + 1;
+ BUSRDO_TX.data <= buffer_dout;
+ BUSRDO_TX.data_write <= '1';
+ end if;
+
+ when FINISH =>
+ BUSRDO_TX.data_finished <= '1';
+ state <= DONE;
+
+ when DONE =>
+ BUSRDO_TX.busy_release <= '1';
+ state <= IDLE;
+ end case;
+
+end process;
+
+---------------------------------------------------------------------------
+-- Bus Handler
+---------------------------------------------------------------------------
+
+
+ THE_BUS_HANDLER : entity work.trb_net16_regio_bus_handler_record
+ generic map(
+ PORT_NUMBER => 3,
+ PORT_ADDRESSES => (0 => x"0000", 1 => x"0100", 2 => x"0200", others => x"0000"),
+ PORT_ADDR_MASK => (0 => 5, 1 => 5, 2 => 4, others => 0),
+ PORT_MASK_ENABLE => 1
+ )
+ port map(
+ CLK => CLK_SYS,
+ RESET => RESET,
+
+ REGIO_RX => BUS_RX,
+ REGIO_TX => BUS_TX,
+
+ BUS_RX(0) => businp_rx,
+ BUS_RX(1) => busword_rx,
+ BUS_RX(2) => busmimosis_rx,
+
+ BUS_TX(0) => businp_tx,
+ BUS_TX(1) => busword_tx,
+ BUS_TX(2) => busmimosis_tx,
+ STAT_DEBUG => open
+ );
+
+PROC_REGS : process
+ variable addr : integer range 0 to 7;
+begin
+ wait until rising_edge(CLK_SYS);
+ busmimosis_tx.ack <= '0';
+ busmimosis_tx.unknown <= '0';
+ busmimosis_tx.nack <= '0';
+ busmimosis_tx.data <= (others => '0');
+
+ if busmimosis_rx.write = '1' then
+ if busmimosis_rx.addr = x"0009" then
+ pulse_stats <= busmimosis_rx.data;
+ busmimosis_tx.ack <= '1';
+ else
+ busmimosis_tx.unknown <= '1';
+ end if;
+ elsif busmimosis_rx.read = '1' then
+ busmimosis_tx.ack <= '1';
+ if busmimosis_rx.addr = x"0000" then
+ busmimosis_tx.data <= std_logic_vector(count_header);
+ elsif busmimosis_rx.addr = x"0001" then
+ busmimosis_tx.data <= std_logic_vector(count_trailer);
+ elsif busmimosis_rx.addr = x"0002" then
+ busmimosis_tx.data <= x"0000" & frame_length;
+ elsif busmimosis_rx.addr = x"0003" then
+ busmimosis_tx.data <= frame_number;
+ elsif busmimosis_rx.addr = x"0004" then
+ busmimosis_tx.data <= x"0000" & std_logic_vector(count_words);
+ elsif busmimosis_rx.addr = x"0005" then
+ busmimosis_tx.data <= x"0000" & "00" & buffer_fill;
+ elsif busmimosis_rx.addr = x"0006" then
+ busmimosis_tx.data <= std_logic_vector(count_fe);
+ elsif busmimosis_rx.addr = x"0007" then
+ busmimosis_tx.data <= std_logic_vector(count_ff);
+ elsif busmimosis_rx.addr = x"0008" then
+ busmimosis_tx.data <= std_logic_vector(count_oof);
+ elsif busmimosis_rx.addr = x"0009" then
+ busmimosis_tx.data <= pulse_stats;
+ else
+ busmimosis_tx.ack <= '0';
+ busmimosis_tx.unknown <= '1';
+
+ end if;
+ end if;
+end process;
+
+end architecture;