blob: f0ead246fee6aa6fe389ea91fb648623b0fe9122 (
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
|
--
-- Copyright 2021 Ettus Research, a National Instruments Brand
--
-- SPDX-License-Identifier: LGPL-3.0-or-later
--
-- Module: axis_mux
--
-- Description:
--
-- This module implements a data mux for a single AXIS bus. When
-- mux_select='0' m_axis_tdata comes from s_axis_tdata. mux_select='1'
-- chooses GPIO as the output data.
--
-- This module IS NOT useful for crossing clock domain boundaries s_axis_aclk
-- and m_axis_mclk must be connected to the same clock.
--
-- This mux is intended for muxing in constant calibration data from gpio.
-- gpio and mux_select are expected to be asynchronous to s_axis_aclk, but
-- this module includes no synchronization logic. When mux_select or gpio
-- change, m_axis_tvalid and m_axis_tdata are undefined in the first few
-- clock cycles. You must wait for bad axis cycles to flush through the
-- remainder of the pipeline before performing calibration and again after
-- exiting calibration mode.
--
-- kAxiWidth must be an integer multiple of kGpioWidth. A concurrent assert
-- statement checks this assumption and should produce a synthesis warning if
-- that requirement is not met.
--
-- Parameters:
--
-- kGpioWidth : GPIO width.
-- kAxiWidth : AXI bus width. Must be an integer multiple of kGpioWidth
--
library IEEE;
use IEEE.std_logic_1164.all;
entity axis_mux is
generic (
kGpioWidth : natural := 32;
kAxiWidth : natural := 256
);
port(
gpio : in std_logic_vector(kGpioWidth-1 downto 0);
mux_select : in std_logic;
-- s_axis_aclk MUST be the same as m_axis_aclk.
-- Declaring an unused clock allows the BD tool to identify the
-- synchronicity of the slave AXIS port signals.
s_axis_aclk : in std_logic;
s_axis_tdata : in std_logic_vector(kAxiWidth - 1 downto 0);
s_axis_tvalid : in std_logic;
s_axis_tready : out std_logic;
m_axis_aclk : in std_logic;
m_axis_tvalid : out std_logic;
m_axis_tdata : out std_logic_vector(kAxiWidth - 1 downto 0)
);
end entity axis_mux;
architecture RTL of axis_mux is
constant kWordSize : natural := gpio'length;
constant kWordCount : natural := kAxiWidth / kWordSize;
subtype AxiData_t is std_logic_vector(kAxiWidth - 1 downto 0);
impure function ConcatenatedData return AxiData_t is
variable rval : AxiData_t;
begin
for i in 0 to kWordCount - 1 loop
rval(i*kWordSize + kWordSize - 1 downto i*kWordSize) := gpio;
end loop;
return rval;
end function ConcatenatedData;
begin
assert kWordSize * kWordCount = kAxiWidth
report "m_axis_tdata'length is not an integer multiple of gpio'length"
severity failure;
MuxOutputRegister:
process (m_axis_aclk) is
begin
if rising_edge(m_axis_aclk) then
if mux_select='1' then
m_axis_tdata <= ConcatenatedData;
m_axis_tvalid <= '1';
else
m_axis_tdata <= s_axis_tdata;
m_axis_tvalid <= s_axis_tvalid;
end if;
end if;
end process MuxOutputRegister;
s_axis_tready <= '1';
end RTL;
|