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

📄 avalon_rd_dma_fifo.v

📁 Altera的基于NIOS II的LCD控制器源代码
💻 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_rd_dma_fifo
  (
   clk_f,
   clk_av,
   reset_n,

   // FIFO read interface
   rd,
   rdata,
   empty,

   // Avalon DMA master
   m_address,
   m_read_n,
   m_readdata,
   m_waitrequest,
   m_readdatavalid,

   // Register interface
   dma_start_addr,
   dma_length,
   dma_layer_on
   );


  // defaults
  parameter DEVICE = "Cyclone";  
  parameter WR_PTR_WIDTH = 7;
  parameter RD_PTR_WIDTH = 8;
  parameter WR_DATA_WIDTH = 32;
  parameter RD_DATA_WIDTH = 16;
  parameter WR_DEPTH = 128;
  parameter RD_DEPTH = 256;
  parameter WRITE_ALMOST_BIT = 6;
  parameter DIFF_RD_WR = 1;


  input clk_f;
  input clk_av;
  input reset_n;

   // FIFO write interface
  input rd;
  output [RD_DATA_WIDTH-1:0] rdata;
  output 	empty;

   // Register Interface
  input [31:0] dma_start_addr;
  input [31:0] dma_length;
  input dma_layer_on;

   // Avalon DMA master
  output [31:0]	m_address;
  output 	m_read_n;
  input [31:0]  m_readdata;
  input 	m_waitrequest;
  input 	m_readdatavalid;
  
  wire almost_full;
  wire cycle_end;

  reg [31:0] 	count;
  reg [4:0] burst;
  reg [31:0] m_address;

  reg 		master_state;
  parameter 	idle	= 1'b0,
		read	= 1'b1;
  
  //---------------------------------------------------------------------------
  // DMA Master
  //
  // When enabled, reads bursts of 32 from Avalon to FIFO
  //---------------------------------------------------------------------------
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      master_state <= idle;
    else
      case (master_state)
	idle:
	  if (dma_layer_on & ~almost_full)
	    master_state <= read;
	  else
	    master_state <= idle;

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

	default: master_state <= idle;
      endcase

  wire m_read_n = ~master_state;

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

/*
 Support for frame length in linear frame buffer
 not being a multiple of SDRAM burst size, in this case 32
 So the last burst read from the frame buffer is not 32, added.

 - The last burst size should be set by the bottom 5 bits of "frame length"
   when the upper bits are 'b0.


 This assumes that the frame buffer is aligned to 32 word boundaries
 to ensure that efficient SDRAM bursts are performed that do not
 go over the page boundaries.
 Frame buffer is arranged with first pixel at low address and subsequent
 pixels at successively higher addresses.

 Future implementation of windowing will also require the start burst
 to be able to be less than 32words, to enable all subsequent bursts
 to be aligned, again for efficient SDRAM accesses.
*/
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      burst <= 5'b0;
    else if ((master_state == idle) & dma_layer_on & ~almost_full & ((|count[31:5]) == 0))
      burst <= 5'h1f;
    else if ((master_state == idle) & dma_layer_on & ~almost_full)
      burst <= count[4:0];
    else if (cycle_end)
      burst <= burst - (|burst); //subtract 1 from burst length counter

  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      m_address <= 32'b0;
    else if (~dma_layer_on)
      //load
      m_address <= dma_start_addr;
    else if (cycle_end & (count == 32'b0))
      // re-load
      m_address <= dma_start_addr;
    else if (cycle_end)
      // increment
      m_address <= m_address + 32'h4;
  
  always @(posedge clk_av or negedge reset_n)
    if (~reset_n)
      count <= 32'b0;
    else if (~dma_layer_on)
      // load
      count <= ((dma_length >> DIFF_RD_WR)-1); //left shift count by the diference in the read and write pointer widths
    else if (cycle_end & (count == 32'b0))
      // re-load
      count <= ((dma_length >> DIFF_RD_WR)-1); //left shift count by the diference in the read and write pointer widths
    else if (cycle_end)
      // decrement
      count <= count - 1;

  //---------------------------------------------------------------------------
  // Instantiate the FIFO
  //---------------------------------------------------------------------------

/*
 FIFO needs modifying for the different output widths
 Layer0 & 1 = 16-bit
 Layer2-4 = 8-bit

 rd_en signal should be conmnected to the act_lX signal
 Check if act_lX signal needs to be generated early to take
 into account the pipeline delay within the FIFO?

 IF act_lX/layer_X_on is de-asserted what value should be output from the FIFO
 since the layer has been turned off. Possible options:
 Force pixel_alpha = 0 or constant_alpha = 0
 
*/

  lcd_dual_port_fifo #(DEVICE, WR_PTR_WIDTH, RD_PTR_WIDTH, WR_DATA_WIDTH, RD_DATA_WIDTH, WR_DEPTH, RD_DEPTH, WRITE_ALMOST_BIT, DIFF_RD_WR) u1_fifo
    (
     .rst_n		(reset_n),
     
     // Write side
     .clk_wr		(clk_av),
     .wr		(m_readdatavalid),
     .wdata		(m_readdata),
     
     .wr_almost_full	(almost_full),
     .wr_full		(),
     
     .reset_fifo_rd	(~dma_layer_on),
     
     // Read side
     .clk_rd		(clk_f),
     .rd_en		(rd),
     
     .rdata		(rdata),
     .rd_empty		(empty),
     .rd_available	(),
     
     .full_error	(),
     .empty_error	()
     );            



endmodule	// avalon_wr_dma_fifo

⌨️ 快捷键说明

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