-- Do not edit.  Generated on Tue Feb 16 11:24:52 2021 by tgingold
-- With Cheby 1.4.dev0 and these options:
--  --gen-hdl wrtd_tdc_x2_host_map.vhd -i wrtd_tdc_x2_host_map.cheby


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;

entity wrtd_tdc_x2_host_map 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;

    -- a ROM containing the carrier metadata
    metadata_i           : in    t_wishbone_master_in;
    metadata_o           : out   t_wishbone_master_out;

    -- TDC0
    tdc0_i               : in    t_wishbone_master_in;
    tdc0_o               : out   t_wishbone_master_out;

    -- TDC1
    tdc1_i               : in    t_wishbone_master_in;
    tdc1_o               : out   t_wishbone_master_out;

    -- Mock Turtle
    mt_i                 : in    t_wishbone_master_in;
    mt_o                 : out   t_wishbone_master_out
  );
end wrtd_tdc_x2_host_map;

architecture syn of wrtd_tdc_x2_host_map is
  signal adr_int                        : std_logic_vector(18 downto 2);
  signal rd_req_int                     : std_logic;
  signal wr_req_int                     : std_logic;
  signal rd_ack_int                     : std_logic;
  signal wr_ack_int                     : std_logic;
  signal wb_en                          : std_logic;
  signal ack_int                        : std_logic;
  signal wb_rip                         : std_logic;
  signal wb_wip                         : std_logic;
  signal metadata_re                    : std_logic;
  signal metadata_we                    : std_logic;
  signal metadata_wt                    : std_logic;
  signal metadata_rt                    : std_logic;
  signal metadata_tr                    : std_logic;
  signal metadata_wack                  : std_logic;
  signal metadata_rack                  : std_logic;
  signal tdc0_re                        : std_logic;
  signal tdc0_we                        : std_logic;
  signal tdc0_wt                        : std_logic;
  signal tdc0_rt                        : std_logic;
  signal tdc0_tr                        : std_logic;
  signal tdc0_wack                      : std_logic;
  signal tdc0_rack                      : std_logic;
  signal tdc1_re                        : std_logic;
  signal tdc1_we                        : std_logic;
  signal tdc1_wt                        : std_logic;
  signal tdc1_rt                        : std_logic;
  signal tdc1_tr                        : std_logic;
  signal tdc1_wack                      : std_logic;
  signal tdc1_rack                      : std_logic;
  signal mt_re                          : std_logic;
  signal mt_we                          : std_logic;
  signal mt_wt                          : std_logic;
  signal mt_rt                          : std_logic;
  signal mt_tr                          : std_logic;
  signal mt_wack                        : std_logic;
  signal mt_rack                        : std_logic;
  signal rd_ack_d0                      : std_logic;
  signal rd_dat_d0                      : std_logic_vector(31 downto 0);
  signal wr_req_d0                      : std_logic;
  signal wr_adr_d0                      : std_logic_vector(18 downto 2);
  signal wr_dat_d0                      : std_logic_vector(31 downto 0);
  signal wr_sel_d0                      : std_logic_vector(3 downto 0);
begin

  -- WB decode signals
  adr_int <= wb_i.adr(18 downto 2);
  wb_en <= wb_i.cyc and wb_i.stb;

  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        wb_rip <= '0';
      else
        wb_rip <= (wb_rip or (wb_en and not wb_i.we)) and not rd_ack_int;
      end if;
    end if;
  end process;
  rd_req_int <= (wb_en and not wb_i.we) and not wb_rip;

  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        wb_wip <= '0';
      else
        wb_wip <= (wb_wip or (wb_en and wb_i.we)) and not wr_ack_int;
      end if;
    end if;
  end process;
  wr_req_int <= (wb_en and wb_i.we) and not wb_wip;

  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';

  -- pipelining for wr-in+rd-out
  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        rd_ack_int <= '0';
        wr_req_d0 <= '0';
      else
        rd_ack_int <= rd_ack_d0;
        wb_o.dat <= rd_dat_d0;
        wr_req_d0 <= wr_req_int;
        wr_adr_d0 <= adr_int;
        wr_dat_d0 <= wb_i.dat;
        wr_sel_d0 <= wb_i.sel;
      end if;
    end if;
  end process;

  -- Interface metadata
  metadata_tr <= metadata_wt or metadata_rt;
  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        metadata_rt <= '0';
        metadata_wt <= '0';
      else
        metadata_rt <= (metadata_rt or metadata_re) and not metadata_rack;
        metadata_wt <= (metadata_wt or metadata_we) and not metadata_wack;
      end if;
    end if;
  end process;
  metadata_o.cyc <= metadata_tr;
  metadata_o.stb <= metadata_tr;
  metadata_wack <= metadata_i.ack and metadata_wt;
  metadata_rack <= metadata_i.ack and metadata_rt;
  metadata_o.adr <= ((25 downto 0 => '0') & adr_int(5 downto 2)) & (1 downto 0 => '0');
  metadata_o.sel <= wr_sel_d0;
  metadata_o.we <= metadata_wt;
  metadata_o.dat <= wr_dat_d0;

  -- Interface tdc0
  tdc0_tr <= tdc0_wt or tdc0_rt;
  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        tdc0_rt <= '0';
        tdc0_wt <= '0';
      else
        tdc0_rt <= (tdc0_rt or tdc0_re) and not tdc0_rack;
        tdc0_wt <= (tdc0_wt or tdc0_we) and not tdc0_wack;
      end if;
    end if;
  end process;
  tdc0_o.cyc <= tdc0_tr;
  tdc0_o.stb <= tdc0_tr;
  tdc0_wack <= tdc0_i.ack and tdc0_wt;
  tdc0_rack <= tdc0_i.ack and tdc0_rt;
  tdc0_o.adr <= ((15 downto 0 => '0') & adr_int(15 downto 2)) & (1 downto 0 => '0');
  tdc0_o.sel <= wr_sel_d0;
  tdc0_o.we <= tdc0_wt;
  tdc0_o.dat <= wr_dat_d0;

  -- Interface tdc1
  tdc1_tr <= tdc1_wt or tdc1_rt;
  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        tdc1_rt <= '0';
        tdc1_wt <= '0';
      else
        tdc1_rt <= (tdc1_rt or tdc1_re) and not tdc1_rack;
        tdc1_wt <= (tdc1_wt or tdc1_we) and not tdc1_wack;
      end if;
    end if;
  end process;
  tdc1_o.cyc <= tdc1_tr;
  tdc1_o.stb <= tdc1_tr;
  tdc1_wack <= tdc1_i.ack and tdc1_wt;
  tdc1_rack <= tdc1_i.ack and tdc1_rt;
  tdc1_o.adr <= ((15 downto 0 => '0') & adr_int(15 downto 2)) & (1 downto 0 => '0');
  tdc1_o.sel <= wr_sel_d0;
  tdc1_o.we <= tdc1_wt;
  tdc1_o.dat <= wr_dat_d0;

  -- Interface mt
  mt_tr <= mt_wt or mt_rt;
  process (clk_i) begin
    if rising_edge(clk_i) then
      if rst_n_i = '0' then
        mt_rt <= '0';
        mt_wt <= '0';
      else
        mt_rt <= (mt_rt or mt_re) and not mt_rack;
        mt_wt <= (mt_wt or mt_we) and not mt_wack;
      end if;
    end if;
  end process;
  mt_o.cyc <= mt_tr;
  mt_o.stb <= mt_tr;
  mt_wack <= mt_i.ack and mt_wt;
  mt_rack <= mt_i.ack and mt_rt;
  mt_o.adr <= ((14 downto 0 => '0') & adr_int(16 downto 2)) & (1 downto 0 => '0');
  mt_o.sel <= wr_sel_d0;
  mt_o.we <= mt_wt;
  mt_o.dat <= wr_dat_d0;

  -- Process for write requests.
  process (wr_adr_d0, wr_req_d0, metadata_wack, tdc0_wack, tdc1_wack, mt_wack) begin
    metadata_we <= '0';
    tdc0_we <= '0';
    tdc1_we <= '0';
    mt_we <= '0';
    case wr_adr_d0(18 downto 17) is
    when "00" =>
      case wr_adr_d0(16 downto 16) is
      when "0" =>
        -- Submap metadata
        metadata_we <= wr_req_d0;
        wr_ack_int <= metadata_wack;
      when "1" =>
        -- Submap tdc0
        tdc0_we <= wr_req_d0;
        wr_ack_int <= tdc0_wack;
      when others =>
        wr_ack_int <= wr_req_d0;
      end case;
    when "01" =>
      -- Submap tdc1
      tdc1_we <= wr_req_d0;
      wr_ack_int <= tdc1_wack;
    when "10" =>
      -- Submap mt
      mt_we <= wr_req_d0;
      wr_ack_int <= mt_wack;
    when others =>
      wr_ack_int <= wr_req_d0;
    end case;
  end process;

  -- Process for read requests.
  process (adr_int, rd_req_int, metadata_i.dat, metadata_rack, tdc0_i.dat, tdc0_rack, tdc1_i.dat, tdc1_rack, mt_i.dat, mt_rack) begin
    -- By default ack read requests
    rd_dat_d0 <= (others => 'X');
    metadata_re <= '0';
    tdc0_re <= '0';
    tdc1_re <= '0';
    mt_re <= '0';
    case adr_int(18 downto 17) is
    when "00" =>
      case adr_int(16 downto 16) is
      when "0" =>
        -- Submap metadata
        metadata_re <= rd_req_int;
        rd_dat_d0 <= metadata_i.dat;
        rd_ack_d0 <= metadata_rack;
      when "1" =>
        -- Submap tdc0
        tdc0_re <= rd_req_int;
        rd_dat_d0 <= tdc0_i.dat;
        rd_ack_d0 <= tdc0_rack;
      when others =>
        rd_ack_d0 <= rd_req_int;
      end case;
    when "01" =>
      -- Submap tdc1
      tdc1_re <= rd_req_int;
      rd_dat_d0 <= tdc1_i.dat;
      rd_ack_d0 <= tdc1_rack;
    when "10" =>
      -- Submap mt
      mt_re <= rd_req_int;
      rd_dat_d0 <= mt_i.dat;
      rd_ack_d0 <= mt_rack;
    when others =>
      rd_ack_d0 <= rd_req_int;
    end case;
  end process;
end syn;
