x393  1.0
FPGAcodeforElphelNC393camera
bit_stuffer_escape.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  input xclk, // pixel clock, sync to incoming data
43  input rst, // @xclk
44 
45  input [31:0] din, // input data, MSB aligned
46  input [1:0] bytes_in, // number of bytes, valid @ ds (0 means 4)
47  input in_stb, // input data/bytes_in strobe
48  input flush_in, // end of input data
49  output reg [31:0] d_out, // output 32-bit data
50  output reg [1:0] bytes_out, // valid @dv(only), 0 means 4 bytes
51  output reg dv, // output data valid
52  output reg flush_out // delayed flush in matching the data latency
53 );
54  wire [3:0] in_ff = {&din[31:24],&din[23:16],&din[15:8],&din[7:0]};
55  wire [3:0] fifo_nempty;
56  wire [3:0] fifo_ff;
57  wire [3:0] fifo_re;
58  wire [31:0] fifo_pre_out;
59  // mask output for flushing
60  wire [31:0] fifo_out = fifo_pre_out & {{8{fifo_nempty[3]}},{8{fifo_nempty[2]}},{8{fifo_nempty[1]}},{8{fifo_nempty[0]}}};
61  reg [3:0] flush_pend;
62 
63  reg [3:0] bytes_in_mask_w;
64  always @* case (bytes_in)
65  2'h0 : bytes_in_mask_w <= 4'b1111;
66  2'h1 : bytes_in_mask_w <= 4'b1000;
67  2'h2 : bytes_in_mask_w <= 4'b1100;
68  2'h3 : bytes_in_mask_w <= 4'b1110;
69  endcase
70 
71 
72  generate
73  genvar i;
74  for (i = 0; i < 4; i = i+1) begin: byte_fifo_block
76  .DATA_WIDTH(9),
77  .DATA_DEPTH(4)
78  ) fifo_same_clock_i (
79  .rst (1'b0), // input
80  .clk (xclk), // input
81  .sync_rst (rst), // input
82  .we (in_stb && bytes_in_mask_w[i]), // input
83  .re (fifo_re[i]), // input
84  .data_in ({in_ff[i],din[8*i +: 8]}), // input[15:0]
85  .data_out ({fifo_ff[i],fifo_pre_out[8*i +: 8]}), // output[15:0]
86  .nempty (fifo_nempty[i]), // output
87  .half_full () // output reg
88  );
89  end
90  endgenerate
91 
92  reg cry_ff; // 0xff was the last byte in the previous word
93  reg [1:0] fifo_byte_pntr; // byte pointer in fifo output, starting from MSB (0)
95  (fifo_byte_pntr[0]?{fifo_ff[0],fifo_ff[3:1]}:{fifo_ff[1:0],fifo_ff[3:2]}):
96  (fifo_byte_pntr[0]?{fifo_ff[2:0],fifo_ff[3]}:fifo_ff[3:0]);
97 
101 
103  (fifo_byte_pntr[0]?{fifo_out[7:0], fifo_out[31: 8]}:{fifo_out[15:0],fifo_out[31:16]}):
104  (fifo_byte_pntr[0]?{fifo_out[23:0],fifo_out[31:24]}:fifo_out[31:0]);
105 
106 // folowing registers are combinatorial signals
107  reg sel3_w; // select source for byte3 (MSB) from the barrel-shifted:0, it's own, 1 - zero (escape)
108  reg [1:0] sel2_w; // select source for byte2 from the barrel-shifted: 0, it's own, 1 - next higher byte, 3 - zero (escape)
109  reg [1:0] sel1_w; // select source for byte1 from the barrel-shifted: 0, it's own, 1 - next higher byte, 3 - zero (escape)
110  reg [1:0] sel0_w; // select source for byte0 (LSB) from the barrel-shifted: 0, it's own, 1 - next higher byte, 2 - two bytes higher,
111  // 3 - zero (escape)
112  reg cry_ff_w; // next value for cry_ff
113  reg [3:0] bytes_rdy_w; // data is available to generate an output word
115  reg [1:0] num_zeros_w; // number of escape zeros in the output word
116  reg [3:0] fifo_re_mask_w; // which fifo to read, bitmask (to be AND-ed with &bytes_rdy_w[3:0]}
117 
118  always @* casex ({cry_ff,fifo_ff_barrel_w})
119  5'b0xxxx: sel3_w <= 0;
120  default: sel3_w <= 1;
121  endcase
122 
123  always @* casex ({cry_ff,fifo_ff_barrel_w})
124  5'b00xxx: sel2_w <= 0;
125  5'b1xxxx: sel2_w <= 1;
126  default: sel2_w <= 3;
127  endcase
128 
129  always @* casex ({cry_ff,fifo_ff_barrel_w})
130  5'b000xx: sel1_w <= 0;
131  5'b01xxx: sel1_w <= 1;
132  5'b10xxx: sel1_w <= 1;
133  default: sel1_w <= 3;
134  endcase
135 
136  always @* casex ({cry_ff,fifo_ff_barrel_w})
137  5'b0000x: sel0_w <= 0;
138  5'b001xx: sel0_w <= 1;
139  5'b010xx: sel0_w <= 1;
140  5'b100xx: sel0_w <= 1;
141  5'b11xxx: sel0_w <= 2;
142  default: sel0_w <= 3;
143  endcase
144 
145  always @* casex ({cry_ff,fifo_ff_barrel_w})
146  5'b00001: cry_ff_w <= 1;
147  5'b0011x: cry_ff_w <= 1;
148  5'b0101x: cry_ff_w <= 1;
149  5'b1001x: cry_ff_w <= 1;
150  5'b111xx: cry_ff_w <= 1;
151  default: cry_ff_w <= 0;
152  endcase
153 
154  always @* case (sel3_w)
155  1'b0 : bytes_rdy_w[3] <= fifo_nempty_barrel_w[3];
156  1'b1 : bytes_rdy_w[3] <= 1;
157  endcase
158 
159  always @* case (sel2_w)
160  2'b00 : bytes_rdy_w[2] <= fifo_nempty_barrel_w[2];
161  2'b01 : bytes_rdy_w[2] <= fifo_nempty_barrel_w[3];
162  2'b11 : bytes_rdy_w[2] <= 1;
163  default : bytes_rdy_w[2] <= 'bx;
164  endcase
165 
166  always @* case (sel1_w)
167  2'b00 : bytes_rdy_w[1] <= fifo_nempty_barrel_w[1];
168  2'b01 : bytes_rdy_w[1] <= fifo_nempty_barrel_w[2];
169  2'b11 : bytes_rdy_w[1] <= 1;
170  default : bytes_rdy_w[1] <= 'bx;
171  endcase
172 
173  always @* case (sel0_w)
174  2'b00 : bytes_rdy_w[0] <= fifo_nempty_barrel_w[0];
175  2'b01 : bytes_rdy_w[0] <= fifo_nempty_barrel_w[1];
176  2'b10 : bytes_rdy_w[0] <= fifo_nempty_barrel_w[2];
177  2'b11 : bytes_rdy_w[0] <= 1;
178  endcase
179 
180 
181  always @* casex ({cry_ff,fifo_ff_barrel_w})
182  5'b0001x: num_zeros_w <= 1;
183  5'b001xx: num_zeros_w <= 1;
184  5'b010xx: num_zeros_w <= 1;
185  5'b011xx: num_zeros_w <= 2;
186  5'b100xx: num_zeros_w <= 1;
187  5'b101xx: num_zeros_w <= 2;
188  5'b110xx: num_zeros_w <= 2;
189  default: num_zeros_w <= 0;
190  endcase
191 
192 
193  always @* casex ({num_zeros_w,fifo_byte_pntr})
194  4'b00xx: fifo_re_mask_w <= 4'b1111;
195  4'b0100: fifo_re_mask_w <= 4'b1110;
196  4'b0101: fifo_re_mask_w <= 4'b0111;
197  4'b0110: fifo_re_mask_w <= 4'b1011;
198  4'b0111: fifo_re_mask_w <= 4'b1101;
199  4'b1000: fifo_re_mask_w <= 4'b1100;
200  4'b1001: fifo_re_mask_w <= 4'b0110;
201  4'b1010: fifo_re_mask_w <= 4'b0011;
202  4'b1011: fifo_re_mask_w <= 4'b1001;
203  default: fifo_re_mask_w <= 'bx; // impossible num_zeros_w
204  endcase
205 
206 // assign fifo_re = flush_pend[2]? fifo_nempty : (rdy_w ? fifo_re_mask_w : 4'b0); // when flushing read whatever is left
207  assign fifo_re = fifo_nempty & (({4{rdy_w}} & fifo_re_mask_w) | {4{flush_pend[2]}});// when flushing read whatever is left
208 
209  always @(posedge xclk) begin
210  if (rst || flush_pend[2]) cry_ff <= 0;
211  else if (rdy_w) cry_ff <= cry_ff_w;
212 
213  if (rst || flush_pend[2]) fifo_byte_pntr <= 0; // flush reads all the remaining data from FIFO, byte pointer should be reset too
215 
216  dv <= rdy_w || (flush_pend[2] && (cry_ff || (|fifo_nempty)));
217  if (rdy_w || (flush_pend[2] && (cry_ff || (|fifo_nempty)))) begin
218  case (sel3_w)
219  1'b0 : d_out[31:24] <= fifo_out_barrel_w[31:24];
220  1'b1 : d_out[31:24] <= 8'b0;
221  endcase
222  case (sel2_w)
223  2'b00 : d_out[23:16] <= fifo_out_barrel_w[23:16];
224  2'b01 : d_out[23:16] <= fifo_out_barrel_w[31:24];
225  2'b11 : d_out[23:16] <= 8'b0;
226  default : d_out[23:16] <= 'bx;
227  endcase
228  case (sel1_w)
229  2'b00 : d_out[15: 8] <= fifo_out_barrel_w[15: 8];
230  2'b01 : d_out[15: 8] <= fifo_out_barrel_w[23:16];
231  2'b11 : d_out[15: 8] <= 8'b0;
232  default : d_out[15: 8] <= 'bx;
233  endcase
234  case (sel0_w)
235  2'b00 : d_out[ 7: 0] <= fifo_out_barrel_w[ 7: 0];
236  2'b01 : d_out[ 7: 0] <= fifo_out_barrel_w[15: 8];
237  2'b10 : d_out[ 7: 0] <= fifo_out_barrel_w[23:16];
238  2'b11 : d_out[ 7: 0] <= 8'b0;
239  default : d_out[ 7: 0] <= 'bx;
240  endcase
241  end
242 
243  if (rst) flush_pend[0] <= 0;
244  else if (flush_in) flush_pend[0] <= 1;
245  else if (flush_pend[1]) flush_pend[0] <= 0;
246 
247  if (rst) flush_pend[1] <= 0;
248  else flush_pend[1] <= flush_pend[0] &&!flush_pend[1] && !rdy_w;
249 
250  if (rst) flush_pend[3:2] <= 0;
251  else flush_pend[3:2] <= {flush_pend[2:1]};
252 
253  if (rst) flush_out <= 0;
254  else flush_out <= flush_pend[3];
255 
256  if (rst) bytes_out <= 'bx;
257  else if ( rdy_w || flush_pend[2]) casex(bytes_rdy_w[3:0])
258  4'b10xx : bytes_out <= 1;
259  4'b110x : bytes_out <= 2;
260  4'b1110 : bytes_out <= 3;
261  default : bytes_out <= 0; // all 4 bytes
262  endcase
263  end
264 
265 endmodule
266 
[DATA_WIDTH-1:0] 10430data_in
fifo_same_clock_i fifo_same_clock[generate]
1313fifo_out_barrel_wwire[31:0]
1312fifo_nempty_barrel_wwire[3:0]
[DATA_WIDTH-1:0] 10431data_out