📄 camera.v
字号:
// ================================================================================
// (c) 2004 Altera Corporation. All rights reserved.
// Altera products are protected under numerous U.S. and foreign patents, maskwork
// rights, copyrights and other intellectual property laws.
//
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design License
// Agreement (either as signed by you, agreed by you upon download or as a
// "click-through" agreement upon installation andor found at www.altera.com).
// By using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation. In the event that you do
// not agree with such terms and conditions, you may not use the reference design
// file and please promptly destroy any copies you have made.
//
// This reference design file is being provided on an "as-is" basis and as an
// accommodation and therefore all warranties, representations or guarantees of
// any kind (whether express, implied or statutory) including, without limitation,
// warranties of merchantability, non-infringement, or fitness for a particular
// purpose, are specifically disclaimed. By making this reference design file
// available, Altera expressly does not recommend, suggest or require that this
// reference design file be used in combination with any other product not
// provided by Altera.
// ================================================================================
//---------------------------------------------------------------------------
// Dialog Semi Camera Receiver
//---------------------------------------------------------------------------
`timescale 1ns/1ns
module camera (
clk,
reset_n,
// Camera input
cam_clk,
cam_hsync,
cam_vsync,
cam_din,
camxlen,
// Outputs
clk_out_en,
sof,
pixel,
line,
y,
cb,
cr
);
input clk; // 26 MHz
input reset_n;
// Camera input
input cam_clk;
input cam_hsync;
input cam_vsync;
input [7:0] cam_din;
input [9:0] camxlen;
// Outputs
output clk_out_en;
output sof;
output [9:0] pixel;
output [8:0] line;
output [7:0] y;
output [7:0] cb;
output [7:0] cr;
reg sof;
//---------------------------------------------------------------------------
// Pixels are written directly into a FIFO
//
// LPM async fifo doesn't work due to non-continuous camera clock
//---------------------------------------------------------------------------
wire cam_rd_en;
wire [7:0] cam_rdata;
wire cam_empty;
camera_fifo u_camera_fifo (
.rst_n (~(~reset_n | sof)),
.clk_wr (cam_clk),
.wdata (cam_din),
.clk_rd (clk),
.rd_en (cam_rd_en),
.rdata (cam_rdata),
.rd_empty (cam_empty)
);
//---------------------------------------------------------------------------
// Hsync and vsync are sampled by the read side clock and the low period
// detected.
//---------------------------------------------------------------------------
reg hsync_r;
reg hsync_rr;
reg [4:0] hsync_count;
reg vsync_r;
reg vsync_rr;
reg [4:0] vsync_count;
wire h_blank;
wire v_blank;
always @(posedge clk or negedge reset_n)
if (~reset_n)
begin
hsync_r <= 1'b0;
hsync_rr <= 1'b0;
vsync_r <= 1'b0;
vsync_rr <= 1'b0;
end
else
begin
hsync_r <= cam_hsync;
hsync_rr <= hsync_r;
vsync_r <= cam_vsync;
vsync_rr <= vsync_r;
end
always @(posedge clk or negedge reset_n)
if (~reset_n)
hsync_count <= 5'b0;
else if (hsync_r | hsync_rr)
hsync_count <= 5'b0;
else if (~hsync_r & ~hsync_rr)
hsync_count <= hsync_count + {4'b0, ~(&hsync_count)};
always @(posedge clk or negedge reset_n)
if (~reset_n)
vsync_count <= 5'b0;
else if (vsync_r | vsync_rr)
vsync_count <= 5'b0;
else if (~vsync_r & ~vsync_rr)
vsync_count <= vsync_count + {4'b0, ~(&vsync_count)};
// Need to allow enough clocks for latency through FIFO and outputs
assign h_blank = hsync_count[4] & hsync_count[3];
assign v_blank = vsync_count[4] & vsync_count[3];
reg [13:0] sync_count;
always @(posedge clk or negedge reset_n)
if (~reset_n)
sync_count <= 14'b0;
else if (hsync_r & hsync_rr)
sync_count <= 14'b0;
else if (~hsync_r & ~hsync_rr)
sync_count <= sync_count + 14'b1;
always @(posedge clk or negedge reset_n)
if (~reset_n)
sof <= 1'b0;
else
sof <= sync_count[13:3] == (8460>>3);
//---------------------------------------------------------------------------
// Input capture registers
//---------------------------------------------------------------------------
assign cam_rd_en = ~cam_empty;
reg cam_data_valid;
always @(posedge clk or negedge reset_n)
if (~reset_n)
cam_data_valid <= 1'b0;
else
cam_data_valid <= cam_rd_en;
reg [1:0] input_phase;
always @(posedge clk or negedge reset_n)
if (~reset_n)
input_phase <= 2'b0;
else if (h_blank | v_blank)
input_phase <= 2'b0;
else if (cam_data_valid)
input_phase <= input_phase + 2'b01;
reg [7:0] y;
always @(posedge clk or negedge reset_n)
if (~reset_n)
y <= 8'b0;
else if (cam_data_valid & input_phase[0])
y <= cam_rdata;
reg [7:0] cb;
always @(posedge clk or negedge reset_n)
if (~reset_n)
cb <= 8'b0;
else if (cam_data_valid & input_phase == 2'b00)
cb <= cam_rdata;
reg [7:0] cr;
always @(posedge clk or negedge reset_n)
if (~reset_n)
cr <= 8'b0;
else if (cam_data_valid & input_phase == 2'b10)
cr <= cam_rdata;
reg clk_out_en;
always @(posedge clk or negedge reset_n)
if (~reset_n)
clk_out_en <= 1'b0;
else
clk_out_en <= cam_data_valid & input_phase[1];
reg [9:0] pixel;
always @(posedge clk or negedge reset_n)
if (~reset_n)
pixel <= 10'b0;
else if (h_blank)
pixel <= 10'b0;
else if (clk_out_en)
pixel <= pixel + 10'b1;
reg [8:0] line;
always @(posedge clk or negedge reset_n)
if (~reset_n)
line <= 9'b0;
else if (v_blank)
line <= 9'b0;
else if ((pixel == camxlen) & clk_out_en)
line <= line + 9'b1;
endmodule // camera
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -