📄 camera_fifo.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.
// ================================================================================
// ================================================================================
// This module uses altsyncram to implement a (possibly) asynchronous FIFO with.
// ================================================================================
`timescale 1ns/1ns
module camera_fifo
(
rst_n,
// Write side
clk_wr,
wdata,
// Read side
clk_rd,
rd_en,
rdata,
rd_empty
);
// defaults
parameter DEVICE = "Cyclone";
parameter PTR_WIDTH = 8;
parameter DATA_WIDTH = 8;
parameter DEPTH = 256;
input rst_n;
// Write side
input clk_wr;
input [DATA_WIDTH-1:0] wdata;
// Read side
input clk_rd;
input rd_en;
output [DATA_WIDTH-1:0] rdata;
output rd_empty;
// pointers on write side
wire [PTR_WIDTH-1:0] wr_ptr;
wire [PTR_WIDTH-1:0] nxt_wr_ptr;
// pointers on read side
wire [PTR_WIDTH-1:0] rd_ptr;
wire [PTR_WIDTH-1:0] nxt_rd_ptr;
wire [PTR_WIDTH-1:0] binary_rd_ptr;
reg [PTR_WIDTH-1:0] wr_ptr_s;
wire [PTR_WIDTH-1:0] synch_wr_ptr;
reg [PTR_WIDTH-1:0] binary_synch_wr_ptr;
wire [DATA_WIDTH-1:0] rdata;
//---------------------------------------------------------------------------
// Write side
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Write pointer
//
// Write pointer is gray coded and increments on when wr is asserted.
//---------------------------------------------------------------------------
camera_gray_count #(PTR_WIDTH) u_gray_wr_ptr
(
.clk (clk_wr),
.reset_n (rst_n),
.en (1'b1),
.gray (wr_ptr),
.binary (),
.next_gray (nxt_wr_ptr),
.next_binary ()
);
//---------------------------------------------------------------------------
// Memory
//
// Dual port mem.
//---------------------------------------------------------------------------
altsyncram u_dp_ram (
.clock0 (clk_wr),
.wren_a (1'b1),
.address_a (wr_ptr),
.data_a (wdata),
.clock1 (clk_rd),
.address_b (rd_ptr),
.q_b (rdata)
);
defparam
u_dp_ram.operation_mode = "DUAL_PORT",
u_dp_ram.width_a = DATA_WIDTH,
u_dp_ram.widthad_a = PTR_WIDTH,
u_dp_ram.numwords_a = DEPTH,
u_dp_ram.width_b = DATA_WIDTH,
u_dp_ram.widthad_b = PTR_WIDTH,
u_dp_ram.numwords_b = DEPTH,
u_dp_ram.lpm_type = "altsyncram",
u_dp_ram.width_byteena_a = 1,
u_dp_ram.outdata_reg_b = "UNREGISTERED",
u_dp_ram.indata_aclr_a = "NONE",
u_dp_ram.wrcontrol_aclr_a = "NONE",
u_dp_ram.address_aclr_a = "NONE",
u_dp_ram.address_reg_b = "CLOCK1",
u_dp_ram.address_aclr_b = "NONE",
u_dp_ram.outdata_aclr_b = "NONE",
u_dp_ram.ram_block_type = "AUTO",
u_dp_ram.intended_device_family = DEVICE;
//---------------------------------------------------------------------------
// Read side
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Read pointer
//---------------------------------------------------------------------------
camera_gray_count #(PTR_WIDTH) u_gray_rd_ptr
(
.clk (clk_rd),
.reset_n (rst_n),
.en (rd_en),
.gray (rd_ptr),
.binary (binary_rd_ptr),
.next_gray (nxt_rd_ptr),
.next_binary ()
);
//---------------------------------------------------------------------------
// Synchronise write pointer to read side and convert to binary
//---------------------------------------------------------------------------
integer m;
always @(posedge clk_rd or negedge rst_n)
if (~rst_n)
begin
wr_ptr_s <= {PTR_WIDTH{1'b0}};
binary_synch_wr_ptr <= {PTR_WIDTH{1'b0}};
end
else
begin
wr_ptr_s <= wr_ptr;
binary_synch_wr_ptr[PTR_WIDTH-1] = wr_ptr_s[PTR_WIDTH-1];
for (m=PTR_WIDTH-2; m>=0; m=m-1)
binary_synch_wr_ptr[m] = binary_synch_wr_ptr[m+1] ^ wr_ptr_s[m];
end
wire [PTR_WIDTH-1:0] rd_available;
assign rd_available = binary_synch_wr_ptr - binary_rd_ptr;
reg rd_empty;
always @(posedge clk_rd or negedge rst_n)
if (~rst_n)
rd_empty <= 1'b1;
else if (rd_en)
begin
if (rd_available == 1)
rd_empty <= 1'b1;
end
else if (rd_empty)
begin
if (binary_synch_wr_ptr == binary_rd_ptr)
rd_empty <= 1'b1;
else
rd_empty <= 1'b0;
end
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
endmodule // camera_fifo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -