## lustrec-tests / vhdl_json / vhdl_files / 2-exportOK / ghdl / ghdl / testsuite / gna / issue301 / src / acs.vhd @ 2051e520

History | View | Annotate | Download (4.23 KB)

1 |
--! |
---|---|

2 |
--! Copyright (C) 2011 - 2014 Creonic GmbH |

3 |
--! |

4 |
--! This file is part of the Creonic Viterbi Decoder, which is distributed |

5 |
--! under the terms of the GNU General Public License version 2. |

6 |
--! |

7 |
--! @file |

8 |
--! @brief Add-compare-select unit for trellis processing. |

9 |
--! @author Markus Fehrenz |

10 |
--! @date 2011/07/04 |

11 |
--! |

12 |
--! @details The ACS decides which path is the the surviving trellis path. |

13 |
--! In the design there are 2^{K-1} ACS instances. |

14 |
--! |

15 | |

16 |
library ieee; |

17 |
use ieee.std_logic_1164.all; |

18 |
use ieee.numeric_std.all; |

19 | |

20 |
library dec_viterbi; |

21 |
use dec_viterbi.pkg_param.all; |

22 |
use dec_viterbi.pkg_param_derived.all; |

23 |
use dec_viterbi.pkg_types.all; |

24 |
use dec_viterbi.pkg_helper.all; |

25 | |

26 | |

27 |
entity acs is |

28 |
generic( |

29 | |

30 |
-- Reset value |

31 |
INITIALIZE_VALUE : in signed(BW_MAX_PROBABILITY - 1 downto 0) |

32 |
); |

33 |
port( |

34 |
clk : in std_logic; |

35 |
rst : in std_logic; |

36 | |

37 |
-- |

38 |
-- Values from branch distance, signed values in std_logic_vector |

39 |
-- high is located in the upper half. |

40 |
-- |

41 |
s_axis_inbranch_tvalid : in std_logic; |

42 |
s_axis_inbranch_tdata_low : in std_logic_vector(BW_BRANCH_RESULT - 1 downto 0); |

43 |
s_axis_inbranch_tdata_high : in std_logic_vector(BW_BRANCH_RESULT - 1 downto 0); |

44 |
s_axis_inbranch_tlast : in std_logic; |

45 |
s_axis_inbranch_tready : out std_logic; |

46 | |

47 |
-- |

48 |
-- Probabilities from previous nodes, signed values in std_logic_vector |

49 |
-- high is located in the upper half. |

50 |
-- |

51 |
s_axis_inprev_tvalid : in std_logic; |

52 |
s_axis_inprev_tdata_low : in std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0); |

53 |
s_axis_inprev_tdata_high : in std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0); |

54 |
s_axis_inprev_tready : out std_logic; |

55 | |

56 |
-- probability result of the add compare and select |

57 |
m_axis_outprob_tvalid : out std_logic; |

58 |
m_axis_outprob_tdata : out std_logic_vector(BW_MAX_PROBABILITY - 1 downto 0); |

59 |
m_axis_outprob_tready : in std_logic; |

60 | |

61 |
-- decision result of the add compare and select |

62 |
m_axis_outdec_tvalid : out std_logic; |

63 |
m_axis_outdec_tdata : out std_logic; |

64 |
m_axis_outdec_tlast : out std_logic; |

65 |
m_axis_outdec_tready : in std_logic |

66 |
); |

67 |
end entity acs; |

68 | |

69 | |

70 |
architecture rtl of acs is |

71 | |

72 |
signal s_axis_inbranch_tlast_d : std_logic; |

73 |
signal m_axis_outdec_tvalid_int : std_logic; |

74 |
signal s_axis_inbranch_tready_int : std_logic; |

75 | |

76 |
begin |

77 | |

78 |
s_axis_inbranch_tready_int <= '1' when m_axis_outdec_tready = '1' or m_axis_outdec_tvalid_int = '0' else |

79 |
'0'; |

80 |
s_axis_inbranch_tready <= s_axis_inbranch_tready_int; |

81 |
m_axis_outdec_tvalid <= m_axis_outdec_tvalid_int; |

82 | |

83 |
-- Add branch to previous, compare both paths and select survivor. |

84 |
pr_add_compare : process(clk) is |

85 |
variable v_diff, v_high, v_low : signed(BW_MAX_PROBABILITY - 1 downto 0); |

86 |
begin |

87 |
if rising_edge(clk) then |

88 |
if rst = '1' then |

89 |
m_axis_outdec_tvalid_int <= '0'; |

90 |
m_axis_outdec_tdata <= '0'; |

91 |
m_axis_outdec_tlast <= '0'; |

92 |
m_axis_outprob_tvalid <= '0'; |

93 |
s_axis_inprev_tready <= '0'; |

94 |
s_axis_inbranch_tlast_d <= '0'; |

95 |
m_axis_outprob_tdata <= std_logic_vector(INITIALIZE_VALUE); |

96 |
else |

97 |
-- If this is the last value, prepare for processing of next incoming value. |

98 |
if s_axis_inbranch_tlast_d = '1' then |

99 |
m_axis_outprob_tdata <= std_logic_vector(INITIALIZE_VALUE); |

100 |
s_axis_inbranch_tlast_d <= '0'; |

101 |
m_axis_outdec_tvalid_int <= '0'; |

102 |
end if; |

103 |
if m_axis_outdec_tvalid_int = '1' and m_axis_outdec_tready = '1' then |

104 |
m_axis_outdec_tvalid_int <= '0'; |

105 |
end if; |

106 | |

107 |
-- Process only if we receive valid data. |

108 |
if s_axis_inbranch_tvalid = '1' and s_axis_inbranch_tready_int = '1' then |

109 |
s_axis_inbranch_tlast_d <= s_axis_inbranch_tlast; |

110 | |

111 |
-- Add. |

112 |
v_low := signed(s_axis_inbranch_tdata_low) + signed(s_axis_inprev_tdata_low); |

113 |
v_high := signed(s_axis_inbranch_tdata_high) + signed(s_axis_inprev_tdata_high); |

114 | |

115 |
-- Use modulo normalization, do not extend the sign here! |

116 |
v_diff := v_low - v_high; |

117 | |

118 |
-- Compare, select the correct path. |

119 |
if v_diff < 0 then |

120 |
m_axis_outdec_tdata <= '1'; |

121 |
m_axis_outprob_tdata <= std_logic_vector(v_high); |

122 |
else |

123 |
m_axis_outdec_tdata <= '0'; |

124 |
m_axis_outprob_tdata <= std_logic_vector(v_low); |

125 |
end if; |

126 |
m_axis_outdec_tvalid_int <= '1'; |

127 |
end if; |

128 | |

129 |
m_axis_outdec_tlast <= s_axis_inbranch_tlast; |

130 |
end if; |

131 |
end if; |

132 |
end process pr_add_compare; |

133 | |

134 |
end architecture rtl; |