x393  1.0
FPGAcodeforElphelNC393camera
bit_stuffer_27_32.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
42  parameter DIN_LEN = 27
43 )(
44  input xclk, // pixel clock, sync to incoming data
45  input rst, // @xclk
46  input [DIN_LEN-1:0] din, // input data, MSB aligned
47  input [4:0] dlen, // input data width
48  input ds, // input data valid
49  input flush_in, // flush remaining data - should be after last ds. Also prepares for the next block
50  output [31:0] d_out, // outpt 32-bit data
51  output reg [1:0] bytes_out, // (0 means 4) valid with dv
52  output reg dv, // output data valid
53  output reg flush_out // delayed flush in matching the data latency
54 );
55  localparam DATA1_LEN = DIN_LEN + 32 - 8;
56  localparam DATA2_LEN = DIN_LEN + 32 - 2;
57  localparam DATA3_LEN = DIN_LEN + 32 - 1;
58  reg [DATA1_LEN-1:0] data1; // first stage of the barrel shifter
59  reg [DATA2_LEN-1:0] data2; // second stage of the barrel shifter
60  reg [DATA3_LEN-1:0] data3; // second stage of the barrel shifter/ output register
61 
62  reg [5:0] early_length; // number of bits in the last word (mod 32)
63  reg [5:0] dlen1; // use for the stage 2, MSB - carry out
64  reg [5:0] dlen2; // use for the stege 3
65 
66  reg [31:0] dmask2_rom; // data mask (sync with data2) - 1 use new data, 0 - use old data. Use small ROM?
67 
68  reg [1:0] stage; // delayed ds or flush
69  reg [1:0] ds_stage;
70  reg [2:0] flush_stage;
71  wire [4:0] pre_bits_out_w = dlen2[4:0] + 5'h7;
72 
73  assign d_out = data3[DATA3_LEN-1 -: 32];
74 
75  always @ (posedge xclk) begin
76 
77  if (rst) stage <= 0;
78  else stage <= {stage[0], ds | flush_in};
79 
80  if (rst) ds_stage <= 0;
81  else ds_stage <= {ds_stage[0], ds};
82 
83  if (rst) flush_stage <= 0;
84  else flush_stage <= {flush_stage[1:0], flush_in};
85 
86  if (rst || flush_in) early_length <= 0;
87  else if (ds) early_length <= early_length[4:0] + dlen; // early_length[5] is not used in calculations, it is just carry out
88 
89  if (rst) dlen1 <= 0;
90  else if (ds) dlen1 <= early_length; // previous value
91 
92  if (rst) dlen2 <= 0;
93  else if (stage[0]) dlen2 <= dlen1; // previous value (position)
94 
95 
96  // barrel shifter stage 1 (0/8/16/24)
97  if (rst) data1 <= 'bx;
98  else if (ds) case (early_length[4:3])
99  2'h0: data1 <= { din, 24'b0};
100  2'h1: data1 <= { 8'b0,din, 16'b0};
101  2'h2: data1 <= {16'b0,din, 8'b0};
102  2'h3: data1 <= {24'b0,din };
103  endcase
104 
105  // barrel shifter stage 2 (0/2/4/6)
106  if (rst) data2 <= 'bx;
107  else if (stage[0]) case (dlen1[2:1])
108  2'h0: data2 <= { data1, 6'b0};
109  2'h1: data2 <= { 2'b0,data1, 4'b0};
110  2'h2: data2 <= { 4'b0,data1, 2'b0};
111  2'h3: data2 <= { 6'b0,data1 };
112  endcase
113 
114  if (rst) dmask2_rom <= 'bx;
115  else if (stage[0]) case (dlen1[4:0])
116  5'h00: dmask2_rom <= 32'hffffffff;
117  5'h01: dmask2_rom <= 32'h7fffffff;
118  5'h02: dmask2_rom <= 32'h3fffffff;
119  5'h03: dmask2_rom <= 32'h1fffffff;
120  5'h04: dmask2_rom <= 32'h0fffffff;
121  5'h05: dmask2_rom <= 32'h07ffffff;
122  5'h06: dmask2_rom <= 32'h03ffffff;
123  5'h07: dmask2_rom <= 32'h01ffffff;
124  5'h08: dmask2_rom <= 32'h00ffffff;
125  5'h09: dmask2_rom <= 32'h007fffff;
126  5'h0a: dmask2_rom <= 32'h003fffff;
127  5'h0b: dmask2_rom <= 32'h001fffff;
128  5'h0c: dmask2_rom <= 32'h000fffff;
129  5'h0d: dmask2_rom <= 32'h0007ffff;
130  5'h0e: dmask2_rom <= 32'h0003ffff;
131  5'h0f: dmask2_rom <= 32'h0001ffff;
132  5'h10: dmask2_rom <= 32'h0000ffff;
133  5'h11: dmask2_rom <= 32'h00007fff;
134  5'h12: dmask2_rom <= 32'h00003fff;
135  5'h13: dmask2_rom <= 32'h00001fff;
136  5'h14: dmask2_rom <= 32'h00000fff;
137  5'h15: dmask2_rom <= 32'h000007ff;
138  5'h16: dmask2_rom <= 32'h000003ff;
139  5'h17: dmask2_rom <= 32'h000001ff;
140  5'h18: dmask2_rom <= 32'h000000ff;
141  5'h19: dmask2_rom <= 32'h0000007f;
142  5'h1a: dmask2_rom <= 32'h0000003f;
143  5'h1b: dmask2_rom <= 32'h0000001f;
144  5'h1c: dmask2_rom <= 32'h0000000f;
145  5'h1d: dmask2_rom <= 32'h00000007;
146  5'h1e: dmask2_rom <= 32'h00000003;
147  5'h1f: dmask2_rom <= 32'h00000001;
148  endcase
149  // barrel shifter stage 3 (0/1), combined with output/hold register
150  if (rst) data3 <= 'bx;
151  else if (ds_stage[1]) begin
152  data3[DATA3_LEN-1 -: 32] <= (~dmask2_rom & (dlen2[5] ? {data3[DATA3_LEN-1-32 : 0],6'b0}: data3[DATA3_LEN-1 -: 32])) |
153  ( dmask2_rom & (dlen2[0] ? {1'b0,data2[DATA2_LEN-1 -: 31]} : data2[DATA2_LEN-1 -: 32]));
154  data3[DATA3_LEN-1-32: 0] <= dlen2[0] ? data2[DATA2_LEN-31-1 : 0] : {data2[DATA2_LEN-32-1 : 0], 1'b0};
155 
156  end
157 // dv <= (ds_stage[1] && dlen2[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32]));
158 // dv <= (ds_stage[1] && dlen1[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32]));
159 // dv <= (ds_stage[0] && dlen1[5]) || (flush_stage[1] && !(|data3[DATA3_LEN-1 -: 32]));
160  dv <= (ds_stage[0] && dlen1[5]) || (flush_stage[1] && (|data3[DATA3_LEN-1 -: 32]));
161 // no difference in number of cells
162 // if (rst ) bytes_out <= 0; // if the dv was caused by 32 bits full - output 4 bytes
163 // else if (ds_stage[1]) bytes_out <= 0; // if the dv was caused by 32 bits full - output 4 bytes
164  if (rst || ds_stage[1]) bytes_out <= 0; // if the dv was caused by 32 bits full - output 4 bytes
165  else if (flush_stage[1]) bytes_out <= pre_bits_out_w[4:3];
166 
167  flush_out <= flush_stage[2];
168 
169  end
170 
171 endmodule
172 
1278DATA2_LENDIN_LEN + 32 - 2
1279DATA3_LENDIN_LEN + 32 - 1
1281data2reg[DATA2_LEN-1:0]
reg [1:0] 1274bytes_out
1277DATA1_LENDIN_LEN + 32 - 8
[DIN_LEN-1:0] 1269din
1290pre_bits_out_wwire[4:0]
1282data3reg[DATA3_LEN-1:0]
1280data1reg[DATA1_LEN-1:0]