~ruther/jesd204b-vhdl

ref: 3a90bcd770ae8006024ec819086cc74d972c2054 jesd204b-vhdl/src/data_link/link_controller.vhd -rw-r--r-- 5.6 KiB
3a90bcd7 — František Boháček feat: make sync aligned to frame clock 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
-------------------------------------------------------------------------------
-- Title      : controller of data link layer
-------------------------------------------------------------------------------
-- File       : link_controller.vhd
-------------------------------------------------------------------------------
-- Description: Controller for link layer, handling CGS and ILAS.
-- 
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use work.data_link_pkg.all;

-- What does it do?
-- Well, it manages the states (init, cgs, ilas, data)
-- It sends sync if needed (irecoverrable error detected). It holds? ILAS data.
-- It should get all the control outputs from lane_alignment,
-- frame_alignment, an8b10bdecoder, char_alignment.
-- It should get the current data from an8b10bdecoder

entity link_controller is
  generic (
    F : integer; -- Number of octets in a frame
    K : integer; -- Number of frames in a multiframe
    K_character  : std_logic_vector(7 downto 0) := "10111100");  -- Sync character
  port (
    ci_frame_clk : in std_logic;        -- Frame clock
    ci_char_clk : in std_logic;         -- Character clock
    ci_reset : in std_logic;            -- Reset (asynchronous, active low)
    di_char : in character_vector;      -- Output character from 8b10b decoder

    do_config : out link_config;        -- Config found in ILAS

    ci_lane_alignment_error : in std_logic;  -- Signals a problem with lane
                                             -- alignment in this data link
                                             -- (see lane alighnment component)
    ci_lane_alignment_aligned : in std_logic;  -- Signals that lane is
                                               -- correctly aligned (see
                                               -- lane_alignment component)
    ci_lane_alignment_ready : in std_logic;  -- Signals that the lane received
                                             -- /A/ and is waiting to start
                                             -- sending data (see
                                             -- lane_alignment component)

    ci_frame_alignment_error : in std_logic;  -- Signals that the frame was misaligned.
    ci_frame_alignment_aligned : in std_logic;  -- Signals that the frame end
                                                -- was found and did not change.

    ci_resync : in std_logic;           -- Whether to start syncing again.

    co_synced : out std_logic;          -- Whether the lane is synced (received
                                        -- 4 /K/ characters and proceeds correctly)
    co_state : out link_state;          -- The state of the lane.
    co_uncorrectable_error : out std_logic;  -- Detected an uncorrectable
                                             -- error, has to resync (ilas
                                             -- parsing error)
    co_error : out std_logic);          -- Detected any error, processing may
                                        -- differ
end entity link_controller;

architecture a1 of link_controller is
  constant SYNC_COUNT : integer := 4;
  signal synced : std_logic := '0';

  signal reg_state : link_state := INIT;
  signal reg_k_counter : integer range 0 to 15 := 0;

  signal ilas_finished : std_logic := '0';
  signal ilas_error : std_logic := '0';
  signal ilas_wrong_chksum : std_logic := '0';
  signal ilas_unexpected_char : std_logic := '0';
begin  -- architecture a1
  ilas: entity work.ilas_parser
    generic map (
      F                  => F,
      K                  => K)
    port map (
      ci_char_clk        => ci_char_clk,
      ci_reset           => ci_reset,
      ci_state           => reg_state,
      di_char            => di_char,
      do_config          => do_config,
      co_finished        => ilas_finished,
      co_error           => ilas_error,
      co_wrong_chksum    => ilas_wrong_chksum,
      co_unexpected_char => ilas_unexpected_char);

  set_state: process (ci_char_clk, ci_reset) is
  begin  -- process set_state
    if ci_reset = '0' then              -- asynchronous reset (active low)
      reg_state <= INIT;
    elsif ci_char_clk'event and ci_char_clk = '1' then  -- rising clock edge
      if ci_resync = '1' then
        reg_state <= INIT;
        reg_k_counter <= 0;
      elsif reg_state = CGS then
        if reg_k_counter < SYNC_COUNT then
          if di_char.d8b = K_character and di_char.kout = '1' then
            reg_k_counter <= reg_k_counter + 1;
          else
            reg_k_counter <= 0;
          end if;
        elsif di_char.d8b /= K_character or di_char.kout = '0' then
          reg_state <= ILS;
        end if;
      elsif di_char.d8b = K_character and di_char.kout = '1' then
        reg_state <= CGS;
        reg_k_counter <= 0;
      elsif reg_state = ILS then
        if ilas_finished = '1' then
          reg_state <= DATA;
        elsif ilas_error = '1' then
          reg_state <= INIT;
        end if;
      elsif reg_state = DATA then
        -- uncorrectable error? resync.
      end if;
    end if;
  end process set_state;

  set_synced: process(ci_frame_clk, ci_reset) is
  begin
    if ci_reset = '0' then
      co_synced <= '0';
    elsif ci_frame_clk'event and ci_frame_clk = '1' then
      co_synced <= synced;
    end if;
  end process set_synced;

  synced <= '0' when reg_state = INIT or (reg_state = CGS and reg_k_counter < SYNC_COUNT) else '1';

  co_state <= reg_state;
  -- TODO: add ILAS errors, add CGS error in case sync does not happen for long
  -- time
  co_error <= ci_lane_alignment_error or ci_frame_alignment_error or di_char.missing_error or di_char.disparity_error;
  co_uncorrectable_error <= ilas_error;

end architecture a1;
Do not follow this link