fmc_adc_alt_trigout.vhd 5.94 KB
Newer Older
Tristan Gingold's avatar
Tristan Gingold committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;

entity alt_trigout is
  port (
    rst_n_i              : in    std_logic;
    clk_i                : in    std_logic;
    wb_i                 : in    t_wishbone_slave_in;
    wb_o                 : out   t_wishbone_slave_out;

    -- Set when WR is enabled
    wr_enable_i          : in    std_logic;

    -- WR link status
    wr_link_i            : in    std_logic;

    -- Set when WR time is valid
    wr_valid_i           : in    std_logic;

    -- Set when the timestamp fifo is not empty
    ts_present_i         : in    std_logic;

    -- Seconds part of the timestamp
    ts_sec_i             : in    std_logic_vector(39 downto 0);

    -- Set if channel 1 triggered
    ch1_mask_i           : in    std_logic;

    -- Set if channel 2 triggered
    ch2_mask_i           : in    std_logic;

    -- Set if channel 3 triggered
    ch3_mask_i           : in    std_logic;

    -- Set if channel 4 triggered
    ch4_mask_i           : in    std_logic;

    -- Set if external trigger
    ext_mask_i           : in    std_logic;

    -- Cycles
    cycles_i             : in    std_logic_vector(27 downto 0);
    ts_cycles_rd_o       : out   std_logic
  );
end alt_trigout;

architecture syn of alt_trigout is
  signal wb_en                          : std_logic;
  signal rd_int                         : std_logic;
  signal wr_int                         : std_logic;
  signal ack_int                        : std_logic;
  signal rd_ack_int                     : std_logic;
  signal wr_ack_int                     : std_logic;
  signal wr_ack_done_int                : std_logic;
  signal reg_rdat_int                   : std_logic_vector(31 downto 0);
  signal rd_ack1_int                    : std_logic;
begin

  -- WB decode signals
  wb_en <= wb_i.cyc and wb_i.stb;
  rd_int <= wb_en and not wb_i.we;
  wr_int <= wb_en and wb_i.we;
  ack_int <= rd_ack_int or wr_ack_int;
  wb_o.ack <= ack_int;
  wb_o.stall <= not ack_int and wb_en;
  wb_o.rty <= '0';
  wb_o.err <= '0';

  -- Assign outputs

  -- Process for write requests.
  process (clk_i, rst_n_i) begin
    if rst_n_i = '0' then 
      wr_ack_int <= '0';
      wr_ack_done_int <= '0';
    elsif rising_edge(clk_i) then
      if wr_int = '1' then
        -- Write in progress
        wr_ack_done_int <= wr_ack_int or wr_ack_done_int;
        case wb_i.adr(4 downto 3) is
        when "00" => 
          case wb_i.adr(2 downto 2) is
          when "0" => 
            -- Register status
            wr_ack_int <= not wr_ack_done_int;
          when others =>
89
            wr_ack_int <= not wr_ack_done_int;
Tristan Gingold's avatar
Tristan Gingold committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
          end case;
        when "01" => 
          case wb_i.adr(2 downto 2) is
          when "0" => 
            -- Register ts_mask_sec
            wr_ack_int <= not wr_ack_done_int;
          when "1" => 
            -- Register ts_mask_sec
            wr_ack_int <= not wr_ack_done_int;
          when others =>
            wr_ack_int <= not wr_ack_done_int;
          end case;
        when "10" => 
          case wb_i.adr(2 downto 2) is
          when "0" => 
            -- Register ts_cycles
            wr_ack_int <= not wr_ack_done_int;
          when others =>
            wr_ack_int <= not wr_ack_done_int;
          end case;
        when others =>
        end case;
      else
        wr_ack_int <= '0';
        wr_ack_done_int <= '0';
      end if;
    end if;
  end process;

  -- Process for registers read.
  process (clk_i, rst_n_i) begin
    if rst_n_i = '0' then 
      rd_ack1_int <= '0';
      reg_rdat_int <= (others => 'X');
      ts_cycles_rd_o <= '0';
    elsif rising_edge(clk_i) then
      ts_cycles_rd_o <= '0';
      if rd_int = '1' and rd_ack1_int = '0' then
        rd_ack1_int <= '1';
129
        reg_rdat_int <= (others => '0');
Tristan Gingold's avatar
Tristan Gingold committed
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
        case wb_i.adr(4 downto 3) is
        when "00" => 
          case wb_i.adr(2 downto 2) is
          when "0" => 
            -- status
            reg_rdat_int(0) <= wr_enable_i;
            reg_rdat_int(1) <= wr_link_i;
            reg_rdat_int(2) <= wr_valid_i;
            reg_rdat_int(8) <= ts_present_i;
          when others =>
          end case;
        when "01" => 
          case wb_i.adr(2 downto 2) is
          when "0" => 
            -- ts_mask_sec
            reg_rdat_int(7 downto 0) <= ts_sec_i(39 downto 32);
            reg_rdat_int(16) <= ch1_mask_i;
            reg_rdat_int(17) <= ch2_mask_i;
            reg_rdat_int(18) <= ch3_mask_i;
            reg_rdat_int(19) <= ch4_mask_i;
            reg_rdat_int(24) <= ext_mask_i;
          when "1" => 
            -- ts_mask_sec
            reg_rdat_int <= ts_sec_i(31 downto 0);
          when others =>
          end case;
        when "10" => 
          case wb_i.adr(2 downto 2) is
          when "0" => 
            -- ts_cycles
            reg_rdat_int(27 downto 0) <= cycles_i;
            ts_cycles_rd_o <= '1';
          when others =>
          end case;
        when others =>
        end case;
      else
        rd_ack1_int <= '0';
      end if;
    end if;
  end process;

  -- Process for read requests.
  process (wb_i.adr, reg_rdat_int, rd_ack1_int, rd_int) begin
    -- By default ack read requests
    wb_o.dat <= (others => '0');
    rd_ack_int <= '1';
    case wb_i.adr(4 downto 3) is
    when "00" => 
      case wb_i.adr(2 downto 2) is
      when "0" => 
        -- status
        wb_o.dat <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when others =>
      end case;
    when "01" => 
      case wb_i.adr(2 downto 2) is
      when "0" => 
        -- ts_mask_sec
        wb_o.dat <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when "1" => 
        -- ts_mask_sec
        wb_o.dat <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when others =>
      end case;
    when "10" => 
      case wb_i.adr(2 downto 2) is
      when "0" => 
        -- ts_cycles
        wb_o.dat <= reg_rdat_int;
        rd_ack_int <= rd_ack1_int;
      when others =>
      end case;
    when others =>
    end case;
  end process;
end syn;