⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avalon_wr_dma_fifo.v

📁 一个视频信号输入的verilog源代码
💻 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 implements a FIFO plus Avalon DMA write master.
// ================================================================================
`timescale 1ns/1ns
  
module avalon_wr_dma_fifo
  (
   clk_f,
   clk_av,
   reset_n,
   sof,

   // FIFO write interface
   wr,
   wdata,
   full,
   eof_in,

   // Control registers
   wr_mcontrol,
   m_enable_bit,
   fb_done,
   mfb_reg,

   // Avalon DMA master
   m_address,
   m_write_n,
   m_writedata,
   m_waitrequest
   );

  parameter DEVICE = "Cyclone";

  input clk_f;
  input clk_av;
  input reset_n;
  input sof;

   // FIFO write interface
  input wr;
  input [31:0] wdata;
  output       full;
  input        eof_in;

   // Control registers
  input        wr_mcontrol;
  input        m_enable_bit;
  output       fb_done;
  input [31:0] 	mfb_reg;

   // Avalon DMA master
  output [31:0]	m_address;
  output 	m_write_n;
  output [31:0] m_writedata;
  input 	m_waitrequest;
  
  reg [3:0] 	master_state;
  parameter 	idle	= 4'b0000,
		wr1	= 4'b1000,
		wr2	= 4'b1001,
		wr3	= 4'b1010,
		write	= 4'b1100,
		wr_wait = 4'b0100;

  //---------------------------------------------------------------------------
  // Control registers
  //---------------------------------------------------------------------------
  reg [31:0] 	s_readdata;
  reg [31:0] 	m_address;
  reg [31:0] 	m_dataout;
  wire [6:0] 	available;
  reg [4:0] 	burst;

  wire 		cycle_end;
  reg 		fb_done;
  
  reg 		wr_mcontrol_r;
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      wr_mcontrol_r <= 1'b0;
    else
      wr_mcontrol_r <= wr_mcontrol;

  reg 		enable;
  // *** sof should be synchronised to local clock
  // - is it long enough (1 clock at 27MHz) to be detected at all clock rates?
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      enable <= 1'b0;
    else if (~m_enable_bit)
      enable <= 1'b0;
    else if (sof & m_enable_bit)
      enable <= 1'b1;
      
  //---------------------------------------------------------------------------
  // DMA Master
  //
  // When enabled, writes bursts of 8 from FIFO to Avalon.
  //---------------------------------------------------------------------------
  reg 		eof_in_r;
  wire 		eof;
  reg 		eof_in_sync1;
  reg 		eof_in_sync2;
  reg 		final_burst;
  reg 		eof_sync1;
  reg 		eof_sync2;
  always @(posedge clk_f or negedge reset_n)
    if (~reset_n)
    begin
      eof_sync1 <= 1'b0;
      eof_sync2 <= 1'b0;
    end
    else
    begin
      eof_sync1 <= eof;
      eof_sync2 <= eof_sync1;
    end
  
  // Remember end of frame
  always @(posedge clk_f or negedge reset_n)
    if (~reset_n)
      eof_in_r <= 1'b0;
    else if (~enable)
      eof_in_r <= 1'b0;
    else if (eof_in)
      eof_in_r <= 1'b1;
    else if (eof_sync1 & ~eof_sync2)
      eof_in_r <= 1'b0;

  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
    begin
      eof_in_sync1 <= 1'b0;
      eof_in_sync2 <= 1'b0;
    end
    else
    begin
      eof_in_sync1 <= eof_in_r;
      eof_in_sync2 <= eof_in_sync1;
    end
      
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      final_burst <= 1'b0;
    else if (~enable)
      final_burst <= 1'b0;
    else if (eof_in_sync1 & ~eof_in_sync2)
      final_burst <= 1'b1;
    else if (eof)
      final_burst <= 1'b0;

  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      master_state <= idle;
    else if (~enable)
      master_state <= idle;
    else
      case (master_state)
	idle:
	  if (enable & (available >= 9'd32))
	    master_state <= wr1;
	  else if (final_burst & (available >= 9'h0))
	    master_state <= wr1;
	  else
	    master_state <= idle;

	wr1:
	  master_state <= wr2;
	
	wr2:
	  master_state <= write;
	
	write:
	  if (cycle_end & (burst == 5'h2))
	    master_state <= wr_wait;
	  else
	    master_state <= write;

	wr_wait:
	  if (cycle_end & (burst == 5'h0))
	    master_state <= idle;
	  else
	    master_state <= wr_wait;
	
	default: master_state <= idle;
      endcase

  wire m_write_n = ~master_state[2];
  wire rd_en = master_state[3] & ~(~m_write_n & m_waitrequest);

  // detect end of current cycle
  assign cycle_end = ~m_write_n & ~m_waitrequest;

  // detect end of final burst
  assign eof = final_burst & cycle_end & (available == 9'h0);

  wire reload = fb_done & (master_state == wr_wait) & cycle_end & (burst == 5'h0);

  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      fb_done <= 1'b0;
    else if (~enable)
      fb_done <= 1'b0;
    else if (eof)
      fb_done <= 1'b1;
    else if (wr_mcontrol_r)
      fb_done <= 1'b0;

  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      burst <= 5'b0;
    else if (~enable)
      burst <= 5'b0;
    else if ((master_state == idle) & enable & (available >= 9'd32))
      burst <= 5'd31;
    else if ((master_state == idle) & enable & final_burst & (available >= 9'h0))


      // *** What if available == 1 ???


      burst <= available[4:0]-1;
    else if (cycle_end)
      burst <= burst - (|burst);

  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      m_address <= 32'b0;
    else if (reload)
      // auto reload
      m_address <= mfb_reg;
    else if (wr_mcontrol_r)
      // processor controlled re-load
      m_address <= mfb_reg;
    else if (cycle_end)
      // increment
      m_address <= m_address + 32'h4;
  
  reg [31:0] m_writedata;
  wire [31:0] fifo_rdata;
  reg [31:0]  fifo_buffer;
  reg 	      wait_r;
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      wait_r <= 1'b0;
    else
      wait_r <= ~m_write_n & m_waitrequest;
    
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      fifo_buffer <= 32'b0;
    else if (~m_write_n & m_waitrequest & ~wait_r)
      fifo_buffer <= fifo_rdata;
  
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      m_writedata <= 32'b0;
    else if (cycle_end & wait_r)
      m_writedata <= fifo_buffer;
    else if ((master_state == wr2) | cycle_end)
      m_writedata <= fifo_rdata;

  //---------------------------------------------------------------------------
  // Instantiate the FIFO
  //---------------------------------------------------------------------------
  dual_port_fifo #(DEVICE, 7, 32) u1_fifo
    (
     .rst_n		(~(~reset_n | sof)),
     
     // Write side
     .clk_wr		(clk_f),
     .wr		(wr),
     .wdata		(wdata),
     
     .wr_almost_full	(),
     .wr_full		(full),
     
     .reset_fifo_rd	(),
     
     // Read side
     .clk_rd		(clk_av),
     .rd_en		(rd_en),
     
     .rdata		(fifo_rdata),
     .rd_empty		(),
     .rd_available	(available),
     
     .full_error	(),
     .empty_error	()
     );            



endmodule	// avalon_wr_dma_fifo

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -