~ruther/jesd204b-vhdl

ref: 3e9599ef10eead139b55c2e9fd5b67d60b998ef7 jesd204b-vhdl/src/jesd204b_multipoint_link_rx.vhd -rw-r--r-- 7.7 KiB
3e9599ef — Rutherther Merge pull request #25 from Rutherther/feat/subclass-1-support 2 years ago
                                                                                
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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
library ieee;
use ieee.std_logic_1164.all;
use work.jesd204b_pkg.all;
use work.data_link_pkg.all;
use work.transport_pkg.all;

entity jesd204b_multipoint_link_rx is

  generic (
    K_character          : std_logic_vector(7 downto 0) := "10111100";  -- Sync character
    R_character          : std_logic_vector(7 downto 0) := "00011100";  -- ILAS first
                                        -- frame character
    A_character          : std_logic_vector(7 downto 0) := "01111100";  -- Multiframe
                                        -- alignment character
    Q_character          : std_logic_vector(7 downto 0) := "10011100";  -- ILAS 2nd
    DATA_RATE_MULT       : integer;  -- DEVICE_CLK_FREQ*this is lane bit rate
                                     -- frame 2nd character
    MULTIFRAME_RATE      : integer;     -- F * K, should be the same for every
                                        -- device
    ALIGN_BUFFER_SIZE : integer                      := 255;  -- Size of a
                                                              -- buffer that is
                                                              -- used for
                                                              -- aligning lanes
    RX_BUFFER_DELAY      : integer range 1 to 32        := 1;
    LINKS                : integer;     -- Count of links
    LANES                : integer;     -- Total nubmer of lanes
    CONVERTERS           : integer;     -- Total number of converters
    CONFIG               : link_config_array(0 to LINKS - 1);
    ERROR_CONFIG         : error_handling_config        := (2, 0, 5, 5, 5));

  port (
    ci_device_clk       : in  std_logic;
    ci_char_clk         : in  std_logic;
    ci_frame_clk        : in  std_logic;
    ci_sysref           : in  std_logic;
    ci_reset            : in  std_logic;
    ci_request_sync     : in  std_logic;
    co_nsynced          : out std_logic;
    co_error            : out std_logic;
    di_transceiver_data : in  lane_input_array(0 to LANES - 1);
    do_samples          : out simple_samples_array(0 to LINKS - 1)(0 to CONFIG(0).M - 1, 0 to CONFIG(0).CS - 1);
    co_frame_state      : out frame_state_array(0 to LINKS - 1);
    co_correct_data     : out std_logic);

end entity jesd204b_multipoint_link_rx;

architecture a1 of jesd204b_multipoint_link_rx is
  constant all_ones : std_logic_vector(LINKS - 1 downto 0) := (others => '1');
  constant all_zeros : std_logic_vector(LINKS - 1 downto 0) := (others => '0');

  signal links_correct_data : std_logic_vector(LINKS - 1 downto 0);
  signal links_error : std_logic_vector(LINKS - 1 downto 0);
  signal links_nsynced : std_logic_vector(LINKS - 1 downto 0);

  signal multiframe_clk : std_logic;
  signal multiframe_aligned : std_logic;
  signal multiframe_enable_sync : std_logic;
  signal nsynced : std_logic;

  signal reg_lmfc_aligned : std_logic;

  -- purpose: Count lanes before link with index link_index
  function sumCummulativeLanes (
    link_index : integer range 0 to LINKS-1)
    return integer is
    variable lanes_count : integer := 0;
  begin  -- function sumCummulativeLanes
    if link_index /= 0 then
        for i in 0 to link_index -1 loop
          lanes_count := lanes_count + CONFIG(i).L;
        end loop;  -- i
    end if;

    return lanes_count;
  end function sumCummulativeLanes;

  -- purpose: Count converters before link with index link_index
  function sumCummulativeConverters (
    link_index : integer range 0 to LINKS-1)
    return integer is
    variable converters_count : integer := 0;
  begin  -- function sumCummulativeConverters
    if link_index /= 0 then
        for i in 0 to link_index -1 loop
          converters_count := converters_count + CONFIG(i).M;
        end loop;  -- i
    end if;

    return converters_count;
  end function sumCummulativeConverters;
begin  -- architecture a1
  nsynced <= '0' when links_nsynced = all_zeros else '1';

  co_error <= '0' when links_error = all_zeros else '1';
  co_correct_data <= '1' when links_correct_data = all_ones else '0';

  multiframe_subclass_0: if CONFIG(0).SUBCLASSV = 0 generate
    co_nsynced <= nsynced;
  end generate multiframe_subclass_0;

  multiframe_subclass_1: if CONFIG(0).SUBCLASSV = 1 generate
    sysref_alignment: process (ci_device_clk, ci_reset) is
    begin  -- process sysref_alignment
      if ci_reset = '0' then            -- asynchronous reset (active low)
        reg_lmfc_aligned <= '0';
        multiframe_enable_sync <= '0';
      elsif ci_device_clk'event and ci_device_clk = '1' then  -- rising clock edge
        if multiframe_enable_sync = '0' and reg_lmfc_aligned = '0' then
          multiframe_enable_sync <= '1';
        elsif reg_lmfc_aligned = '0' and multiframe_aligned = '1' then
          reg_lmfc_aligned <= '1';
          multiframe_enable_sync <= '0';
        elsif co_nsynced = '0' and nsynced = '1' then
          reg_lmfc_aligned <= '0';
          multiframe_enable_sync <= '1';
        end if;
      end if;
    end process sysref_alignment;
    
    set_multiframe_sync: process (multiframe_clk, ci_reset) is
    begin  -- process set_multiframe_sync
      if ci_reset = '0' then              -- asynchronous reset (active low)
        co_nsynced <= '1';
      elsif multiframe_clk'event and multiframe_clk = '1' then  -- rising clock edge
        co_nsynced <= '1';
        if nsynced = '0' and reg_lmfc_aligned = '1' then
          co_nsynced <= '0';
        end if;
      end if;
    end process set_multiframe_sync;
  end generate multiframe_subclass_1;

  multiframe_gen: entity work.lmfc_counter
    generic map (
      DATA_RATE_MULT  => DATA_RATE_MULT,
      PHASE_ADJUST    => 0,
      MULTIFRAME_RATE => MULTIFRAME_RATE)
    port map (
      ci_device_clk     => ci_device_clk,
      ci_reset          => ci_reset,
      ci_sysref         => ci_sysref,
      ci_enable_sync    => multiframe_enable_sync,
      co_aligned        => multiframe_aligned,
      co_multiframe_clk => multiframe_clk);

  links_rx : for i in 0 to LINKS - 1 generate
    link : entity work.jesd204b_link_rx
      generic map (
        K_character       => K_character,
        R_character       => R_character,
        A_character       => A_character,
        Q_character       => Q_character,
        ERROR_CONFIG      => ERROR_CONFIG,
        ALIGN_BUFFER_SIZE => ALIGN_BUFFER_SIZE,
        RX_BUFFER_DELAY   => RX_BUFFER_DELAY,
        ADJCNT            => CONFIG(i).ADJCNT,
        BID               => CONFIG(i).BID,
        DID               => CONFIG(i).DID,
        HD                => CONFIG(i).HD,
        JESDV             => CONFIG(i).JESDV,
        PHADJ             => CONFIG(i).PHADJ,
        SUBCLASSV         => CONFIG(i).SUBCLASSV,
        K                 => CONFIG(i).K,
        CS                => CONFIG(i).CS,
        M                 => CONFIG(i).M,
        S                 => CONFIG(i).S,
        L                 => CONFIG(i).L,
        F                 => CONFIG(i).F,
        CF                => CONFIG(i).CF,
        N                 => CONFIG(i).N,
        Nn                => CONFIG(i).Nn,
        ADJDIR            => CONFIG(i).ADJDIR)
    port map (
      ci_char_clk         => ci_char_clk,
      ci_frame_clk        => ci_frame_clk,
      ci_multiframe_clk   => multiframe_clk,
      ci_reset            => ci_reset,
      ci_request_sync     => ci_request_sync,
      co_nsynced          => links_nsynced(i),
      co_error            => links_error(i),
      di_transceiver_data => di_transceiver_data(sumCummulativeLanes(i) to sumCummulativeLanes(i) + CONFIG(i).L - 1),
      do_samples          => do_samples(i),  -- do_samples(sumCummulativeConverters(i) to sumCummulativeConverters(i) + CONFIG(i).M - 1),
      co_frame_state      => co_frame_state(i),
      co_correct_data     => links_correct_data(i));
  end generate links_rx;

end architecture a1;
Do not follow this link