aboutsummaryrefslogtreecommitdiffstats
path: root/testsuite/synth/issue1731/axis_conv1d9x1.vhdl
blob: 45eae2ff744b0107aecc60cc627659f1f10a5bc9 (plain)
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
89
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
library ieee;
context ieee.ieee_std_context;

entity axis_conv1d9x1 is
  generic (
    fifo_depth : integer := 0 -- ceiling of the log base 2 of the desired FIFO length
  );
  port (
    s_axis_clk   : in  std_logic;
    s_axis_rstn  : in  std_logic;
    s_axis_rdy   : out std_logic;
    s_axis_data  : in  std_logic_vector(31 downto 0);
    s_axis_valid : in  std_logic;
    s_axis_strb  : in  std_logic_vector(3 downto 0);
    s_axis_last  : in  std_logic;

    m_axis_clk   : in  std_logic;
    m_axis_rstn  : in  std_logic;
    m_axis_valid : out std_logic;
    m_axis_data  : out std_logic_vector(31 downto 0);
    m_axis_rdy   : in  std_logic;
    m_axis_strb  : out std_logic_vector(3 downto 0);
    m_axis_last  : out std_logic
  );
end axis_conv1d9x1;

architecture arch of axis_conv1d9x1 is

  constant data_width : integer := 32;

  signal r, e, f, wr, rd, valid : std_logic;
  signal d, q : std_logic_vector(31 downto 0);

  signal acca, accb, acca_n, accb_n : signed(31 downto 0);
  signal rlast : std_logic;

begin

  r <= (s_axis_rstn nand m_axis_rstn);

  fifo: entity work.fifo
    generic map (
      fifo_depth => fifo_depth,
      data_width => 32
    )
    port map (
      CLKW => s_axis_clk,
      CLKR => m_axis_clk,
      RST => r,
      WR => wr,
      RD => rd,
      E => e,
      F => f,
      D => d,
      Q => q
    );

  process(s_axis_clk) begin
    if rising_edge(s_axis_clk) then
      if not s_axis_rstn then
        acca <= (others=>'0');
        accb <= (others=>'0');
      elsif s_axis_valid and s_axis_rdy then
        acca <= acca_n;
        accb <= accb_n;
      end if;
    end if;
  end process;

  acca_n <=
    acca + signed(s_axis_data(15 downto 0)) when rlast='0' else
    resize(signed(s_axis_data(15 downto 0)), acca) when ??(s_axis_valid and s_axis_rdy) else
    (others=>'0');
  accb_n <=
    accb + signed(s_axis_data(31 downto 16)) when rlast='0' else
    resize(signed(s_axis_data(31 downto 16)), acca) when ??(s_axis_valid and s_axis_rdy) else
    (others=>'0');

  process(s_axis_clk) begin
    if rising_edge(s_axis_clk) then
      if not s_axis_rstn then
        rlast <= '0';
      else
        rlast <= s_axis_last and (s_axis_valid and s_axis_rdy);
      end if;
    end if;
  end process;

  wr <= rlast;
  d <= std_logic_vector(accb(18 downto 3)) & std_logic_vector(acca(18 downto 3));

-- AXI4 Stream Slave logic

  s_axis_rdy <= not f;

-- AXI4 Stream Master logic

  rd <= (not e) and (valid nand (not m_axis_rdy));

  process(m_axis_clk) begin
    if rising_edge(m_axis_clk) then
      if ((not m_axis_rstn) or ((valid and E) and m_axis_rdy))='1' then
        valid <= '0';
      elsif rd then
        valid <= '1';
      end if;
    end if;
  end process;

  m_axis_valid <= valid;
  m_axis_last <= q(d'left);
  m_axis_strb <= (others=>'1');
  m_axis_data <= q(data_width-1 downto 0);

end architecture;