Commit a6ac2cd2 authored by Andrey Filippov's avatar Andrey Filippov

working on the sensor input FIFO to compensate for clock domains crossing

parent 6021159e
...@@ -57,6 +57,9 @@ module sensor_channel#( ...@@ -57,6 +57,9 @@ module sensor_channel#(
parameter SENS_CTRL_LD_DLY = 10, // 10 parameter SENS_CTRL_LD_DLY = 10, // 10
parameter SENS_CTRL_QUADRANTS =12, // 17:12, enable - 20 parameter SENS_CTRL_QUADRANTS =12, // 17:12, enable - 20
parameter SENSOR_DATA_WIDTH = 12,
parameter SENSOR_FIFO_2DEPTH = 4,
parameter SENSOR_FIFO_DELAY = 7,
parameter IODELAY_GRP ="IODELAY_SENSOR", // may need different for different channels? parameter IODELAY_GRP ="IODELAY_SENSOR", // may need different for different channels?
parameter integer IDELAY_VALUE = 0, parameter integer IDELAY_VALUE = 0,
...@@ -114,10 +117,16 @@ module sensor_channel#( ...@@ -114,10 +117,16 @@ module sensor_channel#(
wire sens_par12_status_start; wire sens_par12_status_start;
wire ipclk; // Use in FIFO wire ipclk; // Use in FIFO
wire ipclk2x; // Use in FIFO // wire ipclk2x; // Use in FIFO?
wire [11:0] pxd_to_fifo;
wire vact_to_fifo; // frame active @posedge ipclk
wire hact_to_fifo; // line active @posedge ipclk
// data from FIFO
wire [11:0] pxd; // TODO: align MSB? parallel data, @posedge ipclk wire [11:0] pxd; // TODO: align MSB? parallel data, @posedge ipclk
wire vact; // frame active @posedge ipclk
wire hact; // line active @posedge ipclk wire hact; // line active @posedge ipclk
wire sof; // start of frame
wire eof; // end of frame
status_router2 status_router2_sensori ( status_router2 status_router2_sensori (
.rst (rst), // input .rst (rst), // input
...@@ -205,7 +214,7 @@ module sensor_channel#( ...@@ -205,7 +214,7 @@ module sensor_channel#(
.rst (rst), // input .rst (rst), // input
.pclk (pclk), // input .pclk (pclk), // input
.ipclk (ipclk), // output .ipclk (ipclk), // output
.ipclk2x (ipclk2x), // output .ipclk2x (), // ipclk2x), // output
.vact (sns_dn[1]), // input .vact (sns_dn[1]), // input
.hact (sns_dp[1]), // input .hact (sns_dp[1]), // input
.bpf (sns_dn[0]), // inout .bpf (sns_dn[0]), // inout
...@@ -215,9 +224,9 @@ module sensor_channel#( ...@@ -215,9 +224,9 @@ module sensor_channel#(
.arst (sns_dn[7]), // inout .arst (sns_dn[7]), // inout
.aro (sns_ctl), // inout .aro (sns_ctl), // inout
.dclk (sns_dp[0]), // output .dclk (sns_dp[0]), // output
.pxd_out (pxd[11:0]), // output[11:0] .pxd_out (pxd_to_fifo[11:0]), // output[11:0]
.vact_out (vact), // output .vact_out (vact_to_fifo), // output
.hact_out (hact), // output: either delayed input, or regenerated from the leading edge and programmable duration .hact_out (hact_to_fifo), // output: either delayed input, or regenerated from the leading edge and programmable duration
.mclk (mclk), // input .mclk (mclk), // input
.cmd_ad (cmd_ad), // input[7:0] .cmd_ad (cmd_ad), // input[7:0]
.cmd_stb (cmd_stb), // input .cmd_stb (cmd_stb), // input
...@@ -226,6 +235,25 @@ module sensor_channel#( ...@@ -226,6 +235,25 @@ module sensor_channel#(
.status_start (sens_par12_status_start) // input .status_start (sens_par12_status_start) // input
); );
sensor_fifo #(
.SENSOR_DATA_WIDTH (SENSOR_DATA_WIDTH),
.SENSOR_FIFO_2DEPTH (SENSOR_FIFO_2DEPTH),
.SENSOR_FIFO_DELAY (SENSOR_FIFO_DELAY)
) sensor_fifo_i (
.rst (rst), // input
.iclk (ipclk), // input
.pclk (pclk), // input
.pxd_in (pxd_to_fifo), // input[11:0]
.vact (vact_to_fifo), // input
.hact (hact_to_fifo), // input
.pxd_out (pxd), // output[11:0]
.data_valid (hact), // output
.sof (sof), // output
.eof (eof) // output
);
endmodule endmodule
/*******************************************************************************
* Module: sensor_fifo
* Date:2015-05-19
* Author: andrey
* Description: Cross clock boundary for sensor data, synchronize to HACT
*
* Copyright (c) 2015 <set up in Preferences-Verilog/VHDL Editor-Templates> .
* sensor_fifo.v is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sensor_fifo.v is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/> .
*******************************************************************************/
`timescale 1ns/1ps
module sensor_fifo #(
parameter SENSOR_DATA_WIDTH = 12,
parameter SENSOR_FIFO_2DEPTH = 4, // 4-bit address
parameter SENSOR_FIFO_DELAY = 7 // approxiametly half (1 << SENSOR_FIFO_2DEPTH) - how long to wait after getting HACT on FIFO before stering it on output
)(
input rst,
input iclk, // input -synchronous clock
input pclk, // internal lixel clock
input [SENSOR_DATA_WIDTH-1:0] pxd_in, // sensor data @posedge iclk
input vact,
input hact,
output [SENSOR_DATA_WIDTH-1:0] pxd_out,
output data_valid, // @posedge pclk: continuous data valid for each line, FIFO should compensate for clock differences
output sof, // @posedge pclk: single-cycle Start of Frame
output eof // @posedge pclk: single-cycle End of Frame (not yet used)
);
reg vact_r,hact_r,sof_in,eof_in;
wire [SENSOR_DATA_WIDTH-1:0] pxd_w;
wire nempty, hact_w,sof_w,eof_w;
reg sof_r,eof_r;
wire we;
// output clock domain
wire pre_re,re_w,re;
reg re_r;
reg [1:0] pre_hact;
reg hact_out_r;
reg [SENSOR_DATA_WIDTH-1:0] pxd_r;
wire hact_out_start;
assign we=sof_in || eof_in || hact || hact_r;
always @(posedge rst or posedge iclk) begin
if (rst) {vact_r,hact_r,sof_in,eof_in} <= 0;
else {vact_r,hact_r,sof_in,eof_in} <= {vact,hact, vact && ! vact_r, vact_r && !vact};
end
fifo_cross_clocks #(
.DATA_WIDTH(SENSOR_DATA_WIDTH+3),
.DATA_DEPTH(SENSOR_FIFO_2DEPTH)
) fifo_cross_clocks_i (
.rst (rst), // input
.rclk (pclk), // input
.wclk (iclk), // input
.we (we), // input
.re (re), // input
.data_in ({eof_in, sof_in, hact, pxd_in}), // input[15:0]
.data_out ({eof_w, sof_w, hact_w, pxd_w}), // output[15:0]
.nempty (nempty), // output
.half_empty () // output
);
dly_16 #(
.WIDTH(1)
) hact_dly_16_i (
.clk(pclk), // input
.rst(rst), // input
.dly(SENSOR_FIFO_DELAY), // input[3:0]
.din(pre_hact[0] && ! pre_hact[1]), // input[0:0]
.dout(hact_out_start) // output[0:0]
);
// output clock domain
assign pre_re = nempty && !re_r;
assign re_w = re_r && nempty; // to protect from false positive on nempty
assign re = (re_w && !pre_hact) || hact_out_r;
assign pxd_out= pxd_r;
assign data_valid = hact_out_r;
assign sof = sof_r;
assign eof = eof_r;
always @(posedge rst or posedge iclk) begin
if (rst) re_r <= 0;
else re_r <= pre_re;
if (rst) pre_hact[0] <= 0;
else if (re) pre_hact[0] <= hact_w;
if (rst) pre_hact[1] <= 0;
else if (re) pre_hact[1] <= pre_hact[0];
if (rst) pxd_r <= 0;
else if (re) pxd_r <= pxd_w;
if (rst) hact_out_r <= 0;
else if (hact_out_start) hact_out_r <= 1;
else if (!hact_w) hact_out_r <= 0;
if (rst) sof_r <= 0;
else sof_r <= re && sof_w;
if (rst) eof_r <= 0;
else eof_r <= re && eof_w;
end
endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment