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

📄 ahb_master.v

📁 appnote65_quickmips_ahb_interface_design_example AHB接口设计
💻 V
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
*
*               High Speed AMBA Bus (AHB) Interface Example
*                   for "QuickMIPS" QL901M-680 Device
*                              ahb_master.v
*
*                          Copyright (c) 2002
*                           QuickLogic, Corp.
*																			   
*
************************************************************************/
// First Draft (5/14/2002 H. Kim)

`timescale 1ns/10ps

module ahb_master
   (
     // AHB Master Interface
     hclk,
     hreset,

     hready_i,
     hresp_i,
     hgrant_i,

     hbusreq_o,
     htrans_o,
     hwrite_o,
     hsize_o,
     hburst_o,

     haddr_o,
     hwdata_o,
	 hrdata_i,

     // State Machine Interface
	 req_done,
	 rd_req,
	 wr_req,
	 
     // FIFO Interface
     dataout,
	 datain,
	 push,
	 pop,

     // From DMA Register          
     src_addr,
     dst_addr,          
	 block_size
  );

// AHB Interface

input           hclk;                // This clock times all bus transfers
input           hreset;             // AHB reset signal
input           hready_i;           // when active indicates that
                                    // a transfer has finished on the bus
input   [1:0]   hresp_i;            // transfer response from AHB Slave
                                    // (OKAY,ERROR,RETRY,SPLIT)
input           hgrant_i;           // bus grant from AHB Arbiter

output          hbusreq_o;          // bus request to AHB Arbiter
output  [1:0]   htrans_o;           // type of current transfer
output          hwrite_o;           // type of current transfer
                                    // (NONSEQ,SEQ,IDLE,BUSY)
output  [2:0]   hsize_o;            // size of current transfer
output  [2:0]   hburst_o;           // Burst type
output  [31:0]  haddr_o;            // Address out onto AHB for Rd/Wr

output [31:0]   hwdata_o;           // Write data out to AHB for Rx 
input  [31:0]   hrdata_i;           // Read data from AHB for Tx

	// State Machine Interface
output			req_done;
input	 		rd_req;
input			wr_req;

	// FIFO Interface
output	[31:0]  dataout;			// Data Out to Read FIFO
input	[31:0]	datain;				// Data In from Write FIFO
output	 		push;
output			pop;

    // From DMA Register          
input	[31:0]  src_addr;
input	[31:0]  dst_addr;          
input	[4:0]	block_size;

wire              hbusreq_o;
reg               hwrite_o;
wire   [2:0]      hsize_o;
reg    [1:0]      htrans_o;
reg    [2:0]      hburst_o;
wire  [31:0]      haddr_o;
reg   [31:0]      hwdata_o;

wire			req_done;
reg		[4:0]	word_count;
wire			pop;
reg				push;
wire	[31:0]  dataout;			// Data Out to Read FIFO

// Internal register declarations
reg    [3:0]      ahb_master_state;     // AHB Master I/F S/M State bits
reg    [3:0]      state_prev_clk;       // AHB Master I/F S/M State bits
                                        // delayed by 1-clock

reg               latch_addr;           // used to latch address from fifo
                                        // into address incrementer
// reg               latch_prevaddr;       // used to restore the prev. addr
                                        // in case of RETRY/SPLIT
wire              lastbrstrd;           // Last Burst Read
wire              lastbrstwr;           // Last Burst Read
reg				  burstwrflag_last_n;
reg    [29:0]      haddr_reg;            // upper 30-bits of HADDR
wire   [29:0]      nextaddr;             // upper 30-bits of HADDR
reg    [29:0]      haddr_prev;           // lower address bits of the previous
                                        // transfer.  Used to restore address
                                        // in case of RETRY/SPLIT
reg               ahm_busreq_reg;       // AHB registered request signal
                                        // used with busreq_comb to generate
                                        // ahm_busreq O/P to AHB arbiter
reg               rddf_wren;            // enables/disables data fifo
                                        // write logic
reg               busreq_prev;          // AHB access request signal delayed
reg               busreq_comb;

// ******************************************************
// AHB Master Interface State Machine Encoding
// ******************************************************
parameter         AHM_IDLE       =  4'b0000;
parameter         AHM_BREQ       =  4'b0001;
parameter         AHM_NSEQWR     =  4'b0010;
parameter         AHM_SEQWR      =  4'b0011;
parameter         AHM_WRWAIT     =  4'b0101;
parameter         AHM_RETRY      =  4'b0110;
parameter         AHM_LASTWR     =  4'b0111;
parameter         AHM_GOIDLE     =  4'b1000;
parameter         AHM_NSEQRD     =  4'b1001;
parameter         AHM_SEQRD      =  4'b1010;
parameter         AHM_RDWAIT     =  4'b1011;
parameter         AHM_LASTRD     =  4'b1101;


// ******************************************************
// Parameter Definition for AHB Transfer Type(HTRANS)
// ******************************************************
parameter         IDLE                = 2'b00;
parameter         BUSY                = 2'b01;
parameter         NONSEQ              = 2'b10;
parameter         SEQ                 = 2'b11;
  
// ******************************************************
// Parameter Definition for AHB Transfer Type(HBURST)
// ******************************************************
parameter         SINGLE              = 3'b000;
parameter         INCR                = 3'b001;
parameter         INCR4               = 3'b011;
parameter         INCR8               = 3'b101;
parameter         INCR16              = 3'b111;
  
// ******************************************************
// Parameter Definition for AHB Transfer SIZE(HSIZE)
// ******************************************************
parameter         BYTE                = 3'b000;
parameter         HALFWORD            = 3'b001;
parameter         WORD                = 3'b010;
  
// ******************************************************
// Parameter Definition for AHB Response Type(hresp_i)
// ******************************************************
parameter         OKAY                = 2'b00;
parameter         ERROR               = 2'b01;
parameter         RETRY               = 2'b10;
parameter         SPLIT               = 2'b11;
  
// ******************************************************
// Parameter Definition for AHB Write/Read Command (HWRITE)
// ******************************************************
parameter         READ                = 1'b0;
parameter         WRITE               = 1'b1;

// **********************************************************

assign #2 dataout[31:0] = hrdata_i;

// **********************************************************
// AHB Master I/F State Machine
// **********************************************************


assign hsize_o = WORD;		   // Always WORD Transfer
assign req_done = (word_count == 5'b00001) && (push || pop);

always @(posedge hclk or posedge hreset)
begin

   if(hreset) begin

      ahm_busreq_reg    <= 1'b0;
      hwrite_o          <= READ;
      latch_addr        <= 1'b0;
      hburst_o          <= SINGLE;
//      hsize_o           <= WORD;
      rddf_wren         <= 1'b0;
//	  req_done			<= 1'b0;
      ahb_master_state  <= AHM_IDLE;
   end

   // error does not exist or previously generated abort is cleared
   else begin

      case(ahb_master_state)   // synopsys full_case parallel_case

         AHM_IDLE:  begin
               if(rd_req) begin			// DMA Read Cycle
                  // Assert bus access request to AHB Arbiter for read transfers
                  ahm_busreq_reg    <= 1'b1;
                  // assign the read/write command to indicate read cycle
                  hwrite_o          <= READ;
                  // design supports only WORD reads
//                  hsize_o           <= WORD;
                  // latch current address from address fifo into
                  // incrementer, output of which gets onto AHB
                  // as transfer address
                  latch_addr        <= 1'b1;
                  ahb_master_state  <= AHM_BREQ;
               end
               else if(wr_req) begin	// DMA Write Cycle
                  // Assert bus access request to AHB Arbiter
                  ahm_busreq_reg    <= 1'b1;
                  // assign the read/write command to indicate write cycle
                  hwrite_o          <= WRITE;
                  // design supports only WORD reads
//                  hsize_o           <= WORD;
                  // latch current address from address fifo into
                  // incrementer, output of which gets onto AHB
                  // as transfer address
                  latch_addr        <= 1'b1;
                  ahb_master_state  <= AHM_BREQ;
               end
         end

         // wait until bus is granted
         AHM_BREQ:  begin
               latch_addr          <= 1'b0;
  //             latch_prevaddr      <= 1'b0;
               if(hgrant_i & hready_i) begin
                  // write transfer
                  if(hwrite_o) begin
                     ahb_master_state  <= AHM_NSEQWR;
//                     hsize_o           <= hsize;
                     // if it is single write cycle remove bus request
                     // and assert HBURST to SINGLE
                     if(wr_req && (word_count == 5'b00001)) begin
                        ahm_busreq_reg <= 1'b0;
                        hburst_o       <= SINGLE;
                     end
                     // if it is intended burst then keep bus request
                     // asserted and assert HBURST to INCR
                     // (burst of undefined length)
                     else begin
                        hburst_o       <= INCR;
                     end
                  end
                  // read transfer
                  else begin
                     // read request is single
                     if (rd_req && (word_count == 5'b00001)) begin
                        hburst_o          <= SINGLE;
                        ahm_busreq_reg    <= 1'b0;
                     end
                     else begin
                        hburst_o          <= INCR;
                     end
                     // read request is single
                     ahb_master_state    <= AHM_NSEQRD;
                  end
               end
         end
         // first address phase of read transfer
         AHM_NSEQRD:  begin
				// Target is ready accept data
               if(hready_i) begin
                  // If it is single read cycle(hburst_o == SINGLE) OR
                  // only one more data left from current read burst
                  // (rdbrst_compl) OR
                  // current data phase at 1k page boundary
                  // (pgbndry | init_pgboundry)
                  // go to WAIT(until data phase completes) as current data
                  // is last data phase
                  // if data fifo is almost full(it can take only one more data)
                  // terminate the burst read cycle on AHB
                  if(hburst_o == SINGLE) begin
                     ahb_master_state    <= AHM_RDWAIT;
                  end
                  // more data to be read but grant is lost
                  // can't continue the burst beyond the current data phase
                  else if(~hgrant_i) begin
                     ahb_master_state    <= AHM_LASTRD;
                  end
                  // continue to read
                  else begin
                     if(lastbrstrd) begin
                        ahm_busreq_reg      <= 1'b0;
                     end
                     ahb_master_state    <= AHM_SEQRD;
                  end
                  // enable data fifo write logic
                     rddf_wren           <= 1'b1;
               end
         end
         // consecutive transfers of burst read
         AHM_SEQRD:  begin
               // target is ready to provide data
               if(hready_i & hresp_i == OKAY) begin
                  if(htrans_o == IDLE) begin
                     ahb_master_state    <= AHM_GOIDLE;
                     ahm_busreq_reg      <= 1'b0;
                     rddf_wren           <= 1'b0;
                  end
                  // only one more data left from current read burst
                  else if(lastbrstrd) begin 
                     ahb_master_state    <= AHM_RDWAIT;
                     ahm_busreq_reg      <= 1'b0;
                  end
                  else if(~hgrant_i) begin
                     ahb_master_state    <= AHM_LASTRD;
                     if(~busreq_comb) begin
                        ahm_busreq_reg      <= 1'b0;
                     end
                  end
               end
               // system needs to be reset
               else if(~hready_i & hresp_i == ERROR) begin
                  rddf_wren           <= 1'b0;
                  ahb_master_state    <= AHM_IDLE;
                  ahm_busreq_reg      <= 1'b0;
               end
               else begin
                  // enable as long as in SEQRD state
                     rddf_wren           <= 1'b1;
                  if(~busreq_comb) begin
                     ahm_busreq_reg      <= 1'b0;
                  end
               end
         end
         // last read data phase from current read transfer
         // (due to lost ownership of address bus)
         // once the current data phase is over(successful or not(retry/split))
         // master rearbitrates and starts with non-sequential again
         AHM_LASTRD:  begin
               // target is ready to accept data
               if(hready_i & hresp_i == OKAY) begin
                  ahm_busreq_reg      <= 1'b1;
                  ahb_master_state    <= AHM_BREQ;
                  rddf_wren           <= 1'b0;
               end
               else if(~hready_i & (hresp_i == RETRY | hresp_i == SPLIT) ) begin
                  ahm_busreq_reg      <= 1'b1;
                  ahb_master_state    <= AHM_BREQ;
 //                 latch_prevaddr      <= 1'b1;
                  rddf_wren           <= 1'b0;
               end

⌨️ 快捷键说明

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