x393  1.0
FPGAcodeforElphelNC393camera
sensor_fifo.v
Go to the documentation of this file.
1 
39 `timescale 1ns/1ps
40 
41 module sensor_fifo #(
42  parameter SENSOR_DATA_WIDTH = 12,
43  parameter SENSOR_FIFO_2DEPTH = 4, // 4-bit address
44  parameter [3:0] SENSOR_FIFO_DELAY = 5 // 7 // approxiametly half (1 << SENSOR_FIFO_2DEPTH) - how long to wait after getting HACT on FIFO before stering it on output
45 )(
46 // input rst,
47  input iclk, // input -synchronous clock
48  input pclk, // internal lixel clock
49  input prst, // @ posedge pclk
50  input irst, // @ posedge iclk
51 
52  input [SENSOR_DATA_WIDTH-1:0] pxd_in, // sensor data @posedge iclk
53  input vact,
54  input hact,
55  output [SENSOR_DATA_WIDTH-1:0] pxd_out,
56  output data_valid, // @posedge pclk: continuous data valid for each line, FIFO should compensate for clock differences
57  output sof, // @posedge pclk: single-cycle Start of Frame
58  output eof // @posedge pclk: single-cycle End of Frame (not yet used)
59 );
63  reg sof_r,eof_r;
64  wire we;
65  // output clock domain
66 // wire pre_re;
67  wire re; // re_w,re;
68 // reg re_r;
69  reg [1:0] pre_hact;
70  reg [1:0] hact_out_r;
72 // wire hact_out_start;
73 
74  assign we=sof_in || eof_in || hact || hact_r;
75  always @(posedge iclk) begin
76  if (irst) {vact_r,hact_r,sof_in,eof_in} <= 0;
77  else {vact_r,hact_r,sof_in,eof_in} <= {vact,hact, vact && ! vact_r, vact_r && !vact};
78  end
79 
81  .DATA_WIDTH(SENSOR_DATA_WIDTH+3),
82  .DATA_DEPTH(SENSOR_FIFO_2DEPTH)
83  ) fifo_cross_clocks_i (
84  .rst (1'b0), // rst), // input
85  .rrst (prst), // input
86  .wrst (irst), // input
87  .rclk (pclk), // input
88  .wclk (iclk), // input
89  .we (we), // input
90  .re (re), // input
91  .data_in ({eof_in, sof_in, hact, pxd_in}), // input[15:0]
92  .data_out ({eof_w, sof_w, hact_w, pxd_w}), // output[15:0]
93  .nempty (nempty), // output
94  .half_empty () // output
95  );
96 /*
97  dly_16 #(
98  .WIDTH(1)
99  ) hact_dly_16_i (
100  .clk(pclk), // input
101  .rst(prst), // input
102  .dly(SENSOR_FIFO_DELAY), // input[3:0]
103  .din(pre_hact[0] && ! pre_hact[1]), // input[0:0]
104  .dout(hact_out_start) // output[0:0]
105  );
106 */
110 
111  wire sof_pclk;
112  wire eof_pclk;
113  wire sol_pclk;
114 
115  pulse_cross_clock pulse_cross_clock_sof_i (
116  .rst (irst), // input
117  .src_clk (iclk), // input
118  .dst_clk (pclk), // input
119  .in_pulse (sof_in), // input
120  .out_pulse (pre_sof_pclk), // output
121  .busy() // output
122  );
123 
124  pulse_cross_clock pulse_cross_clock_eof_i (
125  .rst (irst), // input
126  .src_clk (iclk), // input
127  .dst_clk (pclk), // input
128  .in_pulse (eof_in), // input
129  .out_pulse (pre_eof_pclk), // output
130  .busy() // output
131  );
132 
133  pulse_cross_clock pulse_cross_clock_sol_i (
134  .rst (irst), // input
135  .src_clk (iclk), // input
136  .dst_clk (pclk), // input
137  .in_pulse (hact && !hact_r), // input
138  .out_pulse (pre_sol_pclk), // output
139  .busy() // output
140  );
141 
143  .WIDTH(3)
144  ) hact_dly_16_i (
145  .clk(pclk), // input
146  .rst(prst), // input
147  .dly(SENSOR_FIFO_DELAY), // input[3:0]
148  .din({pre_sof_pclk, pre_eof_pclk, pre_sol_pclk}), // input[0:0]
149  .dout({sof_pclk, eof_pclk, sol_pclk}) // output[0:0]
150  );
151 
152 
153 
154  reg sof_rq;
155  reg eof_rq;
156  reg sol_rq;
157  always @ (posedge pclk) begin
158  if (prst || (re && sof_w)) sof_rq <= 0;
159  else if (sof_pclk) sof_rq <= 1;
160 
161  if (prst || (re && eof_w)) eof_rq <= 0;
162  else if (eof_pclk) eof_rq <= 1;
163 
164  if (prst || (re && hact_out_r[0] && !hact_out_r[1])) sol_rq <= 0;
165  else if (sol_pclk) sol_rq <= 1;
166  end
167 
168 
169 
170  // output clock domain
171 // assign pre_re = nempty && !re_r;
172 // Generating first read (for hact), then wait to fill half FIFO and continue continuous read until hact end
173 // assign re_w = re_r && nempty; // to protect from false positive on nempty
174 // assign re = (re_w && !pre_hact) || hact_out_r; // no check for nempty - producing un-interrupted stream
175 // assign re = (re_r && nempty && !pre_hact[0]) || hact_out_r[0]; // no check for nempty - producing un-interrupted stream
176  assign re = ((sof_rq || eof_rq || sol_rq) && nempty) || hact_out_r[0]; // no check for nempty - producing un-interrupted stream
177  assign pxd_out= pxd_r;
178  assign data_valid = hact_out_r[1];
179  assign sof = sof_r;
180  assign eof = eof_r;
181 
182  always @(posedge pclk) begin
183 // if (prst) re_r <= 0;
184 // else re_r <= nempty && !re_r && !pre_hact[0]; // only generate one cycle (after SOF of HACT)
185 
186  if (prst) pre_hact[0] <= 0;
187  else if (re) pre_hact[0] <= hact_w;
188 
189  if (prst) pre_hact[1] <= 0;
190  else pre_hact[1] <= pre_hact[0];
191 
192 
193  if (prst) pxd_r <= 0;
194  else if (re) pxd_r <= pxd_w;
195 
196  if (prst) hact_out_r[0] <= 0;
197  else if (sol_pclk) hact_out_r[0] <= 1;
198  else if (!(hact_w) && re) hact_out_r[0] <= 0;
199 
200  if (prst || (!(hact_w) && re)) hact_out_r[1] <= 0;
201  else hact_out_r[1] <= hact_out_r[0];
202 
203  if (prst) sof_r <= 0;
204  else sof_r <= re && sof_w;
205 
206  if (prst) eof_r <= 0;
207  else eof_r <= re && eof_w;
208 
209  end
210 
211 /*
212  always @(posedge iclk) begin
213  if (irst) re_r <= 0;
214  else re_r <= pre_re;
215 
216  if (irst) pre_hact[0] <= 0;
217  else if (re) pre_hact[0] <= hact_w;
218 
219  if (irst) pre_hact[1] <= 0;
220  else if (re) pre_hact[1] <= pre_hact[0];
221 
222  if (irst) pxd_r <= 0;
223  else if (re) pxd_r <= pxd_w;
224 
225  if (irst) hact_out_r <= 0;
226  else if (hact_out_start) hact_out_r <= 1;
227  else if (!hact_w) hact_out_r <= 0;
228 
229  if (irst) sof_r <= 0;
230  else sof_r <= re && sof_w;
231 
232  if (irst) eof_r <= 0;
233  else eof_r <= re && eof_w;
234 
235  end
236 */
237 
238 
239 endmodule
240 
8137pre_hactreg[1:0]
Definition: sensor_fifo.v:69
8138hact_out_rreg[1:0]
Definition: sensor_fifo.v:70
10332clk
Definition: dly_16.v:44
8129nemptywire
Definition: sensor_fifo.v:62
[SENSOR_DATA_WIDTH-1:0] 8117pxd_in
Definition: sensor_fifo.v:52
8143sof_pclkwire
Definition: sensor_fifo.v:111
[DATA_WIDTH-1:0] 10404data_out
[WIDTH-1:0] 10336dout
Definition: dly_16.v:48
hact_dly_16_i dly_16
Definition: sensor_fifo.v:142
8111SENSOR_FIFO_2DEPTH4
Definition: sensor_fifo.v:43
8142pre_sol_pclkwire
Definition: sensor_fifo.v:109
[WIDTH-1:0] 10335din
Definition: dly_16.v:47
[SENSOR_DATA_WIDTH-1:0] 8120pxd_out
Definition: sensor_fifo.v:55
8131sof_wwire
Definition: sensor_fifo.v:62
pulse_cross_clock_sol_i pulse_cross_clock
Definition: sensor_fifo.v:133
[DATA_WIDTH-1:0] 10403data_in
8140pre_sof_pclkwire
Definition: sensor_fifo.v:107
8132eof_wwire
Definition: sensor_fifo.v:62
8128pxd_wwire[SENSOR_DATA_WIDTH-1:0]
Definition: sensor_fifo.v:61
8144eof_pclkwire
Definition: sensor_fifo.v:112
8130hact_wwire
Definition: sensor_fifo.v:62
fifo_cross_clocks_i fifo_cross_clocks
Definition: sensor_fifo.v:80
8110SENSOR_DATA_WIDTH12
Definition: sensor_fifo.v:42
[3:0] 8112SENSOR_FIFO_DELAY5
Definition: sensor_fifo.v:44
8145sol_pclkwire
Definition: sensor_fifo.v:113
10333rst
Definition: dly_16.v:45
8139pxd_rreg[SENSOR_DATA_WIDTH-1:0]
Definition: sensor_fifo.v:71
8141pre_eof_pclkwire
Definition: sensor_fifo.v:108
[3:0] 10334dly
Definition: dly_16.v:46