x393  1.0
FPGAcodeforElphelNC393camera
gtx_comma_align.v
Go to the documentation of this file.
1 
40  input wire rst,
41  input wire clk,
42  // input data comes this way (standart 8/10 bit notation)
43  // cycle 0: {[hgfedcba]=1st byte,[hgfedcba]=0st byte}
44  // cycle 1: {[hgfedcba]=3rd byte,[hgfedcba]=2dn byte}
45  // => {[cycle1 data], [cycle0 data]} = as if we were reading by dwords
46  input wire [19:0] indata,
47  output wire [19:0] outdata,
48  // outdata contains comma
49  output wire comma,
50  // pulse, indicating that stream was once again adjusted to a comma
51  // if asserted after link was down - OK
52  // if asserted during a work - most likely indicates an error in a stream
53  output wire realign
54  // asserted when input stream looks like comma, but it is not
55  // later on after 10/8 it would get something link NOTINTHETABLE error anyways
56 // output wire error
57 );
58 // only comma character = K28.5, has 5 '1's or 5 '0's in a row.
59 // after we met it, call it a comma group, we could compare other symbols
60 /*
61 // create a window
62 reg [19:0] indata_r;
63 wire [23:0] window;
64 always @ (posedge clk)
65  indata_r <= indata;
66 assign window = {indata_r[17:0], indata[19:14]};
67 
68 // search for a comma group - parallel 24-bit window into 20 5-bit words
69 // transposed -> 5 x 20-bit words
70 wire [19:0] lane0;
71 wire [19:0] lane1;
72 wire [19:0] lane2;
73 wire [19:0] lane3;
74 wire [19:0] lane4;
75 assign lane0 = window[19:0];
76 assign lane1 = window[20:1];
77 assign lane2 = window[21:2];
78 assign lane3 = window[22:3];
79 assign lane4 = window[23:4];
80 // calcute at what position in a window comma group is detected,
81 // so the position in actual {indata_r, indata} would be +2 from the left side
82 wire [19:0] comma_pos;
83 assign comma_pos = lane0 & lane1 & lane2 & lane3 & lane4;
84 */
85 
86 // seach for a comma
87 // TODO make it less expensive
88 reg [19:0] indata_r;
89 wire [38:0] window;
90 always @ (posedge clk)
91  indata_r <= indata;
92 assign window = {indata[18:0], indata_r};
93 
94 // there is only 1 matched subwindow due to 20-bit comma's non-repetative pattern
95 wire [19:0] subwindow [19:0];
96 wire [19:0] comma_match;
97 wire [19:0] comma_match_p;
98 reg [19:0] aligned_data;
99 reg [19:0] comma_match_prev;
101 wire [19:0] comma_p = 20'b10101010100101111100;
102 wire [19:0] comma_n = 20'b10101010101010000011;
103 
104 genvar ii;
105 generate
106  for (ii = 0; ii < 20; ii = ii + 1)
107  begin: look_for_comma
108  assign subwindow[ii] = window[ii + 19:ii];
109 // assign comma_match[ii] = subwindow[ii] == 20'b01010101010011111010 | subwindow[ii] == 20'b01010101011100000101;
110  // stream comes inverted
111  assign comma_match_p[ii] = subwindow[ii] == comma_p;
112  assign comma_match[ii] = comma_match_p[ii] | subwindow[ii] == comma_n;
113  end
114 endgenerate
115 
116 assign comma_detected = |comma_match;
117 
118 // save the shift count
119 always @ (posedge clk)
121 // shift
122 /* TODO
123 wire [38:0] shifted_window;
124 assign shifted_window = comma_detected ? {window >> (comma_match - 1)} : {window >> (comma_match_prev - 1)};
125 */
126 // temp shift
127 wire [19:0] shifted_window;
128 wire [19:0] ored_subwindow [19:0];
129 wire [19:0] ored_subwindow_comdet [19:0];
130 assign ored_subwindow_comdet[0] = {20{comma_match_p[0]}} & comma_p | {20{~comma_match_p[0] & comma_match[0]}} & comma_n;
131 assign ored_subwindow[0] = {20{comma_match_prev[0]}} & subwindow[0];
132 generate
133  for (ii = 1; ii < 20; ii = ii + 1)
134  begin: or_all_possible_windows
135  assign ored_subwindow_comdet[ii] = {20{comma_match_p[ii]}} & comma_p | {20{~comma_match_p[ii] & comma_match[ii]}} & comma_n | ored_subwindow_comdet[ii-1]; // SuppressThisWarning VEditor -warning would be fixed in future releases
136  assign ored_subwindow[ii] = {20{comma_match_prev[ii]}} & subwindow[ii] | ored_subwindow[ii-1]; // SuppressThisWarning VEditor -warning would be fixed in future releases
137  end
138 endgenerate
139 
141 always @ (posedge clk)
142 // aligned_data <= comma_detected ? {window >> (comma_match - 1)}[19:0] : {window >> (comma_match_prev - 1)}[19:0];
143  aligned_data <= shifted_window[19:0];
144 
145 // form outputs
146 assign comma = comma_detected;
148 assign outdata = aligned_data;
149 
150 endmodule
14772aligned_datareg[19:0]
14770comma_matchwire[19:0]
14767indata_rreg[19:0]
14777shifted_windowwire[19:0]
14775comma_pwire[19:0]
wire [19:0] 14764outdata
14768windowwire[38:0]
14776comma_nwire[19:0]
[19:0] 14769subwindowwire[19:0]
[19:0] 14778ored_subwindowwire[19:0]
[19:0] 14779ored_subwindow_comdetwire[19:0]
14771comma_match_pwire[19:0]
14773comma_match_prevreg[19:0]
wire [19:0] 14763indata