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

📄 mstr_mem32.v

📁 Master MemoryExamples for MT32 v1.0.0 Rtl core
💻 V
字号:
//------------------------------------------------------------------------------
// 
// Name:                Master Memory 32 Example
// Module Name:         mstr_mem32
// Company:             Altera Corporation  www.altera.com 
// 
// Functional Description:
// 
//   This module is the top level of the local design for the Master
//   32-bit memory example. The design example shows how to interface
//   a 32-bit Master Function to a synchronous memory like altsyncram.
//   
//   This module also shows the sample master control logic required
//   to handle the case when the transaction is terminated by either a Target
//   Retry, Target Disconnect or Master Latency Timeout. If the
//   transaction is terminated before the entire data is transmitted,
//   the control logic will start a new PCI transaction and will
//   transfer the remaining data. 
//
//   The length, direction and the address of the transfer are
//   controlled by input signals.
//
//   This module instantiates the module lm_last which generates the
//   signal lm_lastn. It also instantiates a 256x32 synchronous memory
//   (altsyncram). 
//   
// Copyright:
//   Copyright 2004 Altera Corporation, All rights Reserved
//
//------------------------------------------------------------------------------
`timescale 1ns/1ns
module mstr_mem32 (/*AUTOARG*/
	   // Outputs
	   l_adi, l_cbeni, lm_req32n, lm_lastn, lm_rdyn, lt_rdyn, lt_abortn, 
	   lt_discn, lirqn, done, error, 
	   // Inputs
	   clk, rstn, l_adro, l_dato, l_beno, l_cmdo, lm_adr_ackn, lm_ackn, 
	   lm_dxfrn, lm_tsr, lt_framen, lt_ackn, lt_dxfrn, lt_tsr, cmd_reg, 
	   stat_reg, cache, START_I, PCI_ADDR_I, LOCAL_ADDR_I, LOCAL_DATA_I, 
	   PCI_CMD_I, XFR_LENGTH_I
	   );

   input      clk;
   input      rstn;
   //Data Path Signals
   output [31:0] l_adi;
   output [3:0]  l_cbeni;
   input [31:0]  l_adro;
   input [31:0]  l_dato;
   input [3:0] 	 l_beno;
   input [3:0] 	 l_cmdo;
   // Master O/p Control signals
   output 	 lm_req32n;
   output 	 lm_lastn;
   output 	 lm_rdyn;
   // Master i/p control signals
   input 	 lm_adr_ackn;
   input 	 lm_ackn;
   input 	 lm_dxfrn;
   input [9:0] 	 lm_tsr;
   // Target o/p control signals
   output 	 lt_rdyn;
   output 	 lt_abortn;
   output 	 lt_discn;
   output 	 lirqn;

   input 	 lt_framen;
   input 	 lt_ackn;
   input 	 lt_dxfrn;
   input [11:0]  lt_tsr;

   // Misc signals
   input [6:0] 	 cmd_reg;
   input [6:0] 	 stat_reg;
   input [7:0] 	 cache;
   // TB Master control signals
   input 	 START_I;
   input [31:0]  PCI_ADDR_I;
   input [31:0]  LOCAL_ADDR_I;
   input [31:0]  LOCAL_DATA_I;
   input [3:0] 	 PCI_CMD_I;
   input [10:0]  XFR_LENGTH_I;
   output 	 done; // transaction completed
   output 	 error; // transaction error

   reg 		 done, error;
   // The target interface is not used in this example
   // Target Control Signals
   wire 	 lt_abortn = 1'b1;
   wire 	 lt_rdyn   = 1'b1;
   wire 	 lt_discn  = 1'b1;
   wire 	 lirqn     = 1'b1;
   
   
   // Register the TB control signals
   reg 		 START;
   reg [31:0] 	 PCI_ADDR, LOCAL_ADDR, LOCAL_DATA;
   reg [3:0] 	 PCI_CMD;
   reg [10:0] 	 XFR_LENGTH;

   
   always @ (posedge clk)
     begin
	START      <= START_I;
	PCI_ADDR   <= PCI_ADDR_I;
	LOCAL_ADDR <= LOCAL_ADDR_I;
	LOCAL_DATA <= LOCAL_DATA_I;
	PCI_CMD    <= PCI_CMD_I;
	XFR_LENGTH <= XFR_LENGTH_I;
     end

   // Some renames of lm_tsr signals
   wire 	 pci_adr_phase  = lm_tsr[2];
   wire 	 pci_data_xfr   = lm_tsr[8];
   wire 	 pci_data_phase = lm_tsr[3];

   
   // Master Control State Machine
   // Declare the various inputs required
   reg 		 pci_data_phase_q;
   always @ (posedge clk)
     pci_data_phase_q <= pci_data_phase;

   wire 	 cycle_end = pci_data_phase_q & !pci_data_phase;
   
   reg 		 fatal_error; // Indicates mastor abort or target abort
   
   reg           do_retry;  // Indicates one of the following
   // 1) Target Retry
   // 2) Target Disconnect with or without data
   // 3) Master Latency timer expired
   always @ (posedge clk or negedge rstn)
     if (!rstn) begin
	fatal_error <= 1'b0;
	do_retry    <= 1'b0;
     end
     else if (cycle_end) begin
	fatal_error <= stat_reg[3] | stat_reg[4]; 
	do_retry <= |lm_tsr[7:4];
     end
   
   reg 		 xfr_done; // Indicates all the data has been transferred

   
   // State Definitions
   parameter [5:0] IDLE       = 6'b00_0000,
		   REQ        = 6'b00_0001,
		   ADR_PHASE  = 6'b00_0010,
		   DATA_PHASE = 6'b00_0100,
		   DP_DONE    = 6'b00_1000,
		   CHK_STATE  = 6'b01_0000,
		   RETRY      = 6'b10_0000;
   //state machine
   reg [5:0] 	   m_state;
   always @ (posedge clk or negedge rstn)
     if (!rstn) 
       m_state <= IDLE;
     else  
       case (m_state)
	 IDLE: begin
	    if (START)
	      m_state  <= REQ;
	    else
	      m_state <= IDLE;
	 end
	 REQ: m_state <= ADR_PHASE;
	 ADR_PHASE: begin
	    if (lm_tsr[2])
	      m_state <= DATA_PHASE;
	    else
	      m_state <= ADR_PHASE;
	 end
	 DATA_PHASE: begin
	    if (cycle_end)
	      m_state <= CHK_STATE;
	    else if (!lm_lastn)
	      m_state <= DP_DONE;
	    else
	      m_state <= DATA_PHASE;
	 end
	 DP_DONE: begin
	    if (cycle_end)
	      m_state <= CHK_STATE;
	    else
	      m_state <= DP_DONE;
	 end
	 CHK_STATE: begin
	    if (fatal_error | xfr_done)
	      m_state <= IDLE;
	    else if (do_retry)
	      m_state <= RETRY;
	 end
	 RETRY: m_state <= REQ;
	 default: m_state <= IDLE;
       endcase // case(cs[4:0])
   
   // outputs from state machine
   wire 	 lm_req32n = (m_state == REQ) ? 1'b0: 1'b1;
   
   wire 	 data_sel = (m_state == DATA_PHASE | m_state == ADR_PHASE & lm_tsr[2]) ? 1'b1: 1'b0;

   
   // command and wr_rdn load at the beginning of request
   // wr_rdn = 1 PCI write local side read
   // wr_rdn = 0 PCI read local side write
   reg 		 wr_rdn; 
   reg [3:0] 	 command;

   always @ (posedge clk or negedge rstn)
     if(!rstn) begin
	wr_rdn <= 1'b0;
	command <= 4'h0;
     end else if (m_state == IDLE & START) begin
	command <= PCI_CMD;
	wr_rdn <= PCI_CMD[0];
     end

    // lm_rdyn   

   reg 	lm_rdyn;
   always @ (posedge clk or negedge rstn)
     if (!rstn)
       lm_rdyn <= 1'b1;
     else 
       lm_rdyn <= !(( wr_rdn & (m_state == ADR_PHASE | m_state == DATA_PHASE))|
		    (!wr_rdn & (m_state == DATA_PHASE | m_state == DP_DONE)));

   

   // counters to keep track of the PCI address and the Transfer count 
   reg [31:0] 	 paddr; // PCI address
   reg [10:0] 	 xfr_cnt; // xfr counter
   always @ (posedge clk or negedge rstn)
     if (!rstn) begin
	paddr <= 32'b0;
	xfr_cnt <= 11'b0;
	xfr_done <= 1'b0;
     end else if (m_state == IDLE & START) begin
	paddr <= PCI_ADDR;
	xfr_cnt <= XFR_LENGTH;
	xfr_done <= 1'b0;
     end else if (pci_data_xfr) begin
	paddr <= paddr + 4;
	xfr_cnt <= xfr_cnt - 1;
	xfr_done <= (xfr_cnt == 'h1);
     end
   // lm_last generation
   wire abnormal_term = (fatal_error | do_retry ) & (m_state == CHK_STATE);

   
   lm_last lm_last (.lm_lastn(lm_lastn),
		    .clk(clk),
		    .rstn(rstn),
		    .wr_rdn(wr_rdn),
		    .lm_req32n(lm_req32n),
		    .lm_dxfrn(lm_dxfrn),
		    .lm_tsr(lm_tsr),
		    .xfr_length(xfr_cnt),
		    .abnormal_term(abnormal_term)
		    );

  
   /***********************************************************
    * Local Address Counter logic
    ***********************************************************/
   
   
   wire mem_rd_incr = !wr_rdn & !lm_dxfrn;
   
   wire mem_wr_incr = wr_rdn & (!lm_ackn | !lm_req32n ) ;
   wire mem_incr = (mem_wr_incr | mem_rd_incr) ;

   // The following logic implements an up-down counter and keeps
   // track of the number of DWORDs tranferred on the local side but
   // not on the PCI bus during a PCI write transcation. The local
   // address counter is decremented by the value in this counter when
   // the state machine is in the RETRY state. 
   reg [1:0] pipe;
   always @ (posedge clk or negedge rstn)
     if (!rstn)
       pipe <= 2'b0;
     else begin
	if (m_state == REQ & wr_rdn)
	  pipe <= 2'b1;
	else if (wr_rdn)
	  case ({pci_data_xfr, mem_wr_incr})
	    2'b00: pipe <= pipe;
	    2'b01: pipe <= pipe + 1;
	    2'b10: pipe <= pipe - 1;
	    2'b11: pipe <= pipe;
	  endcase // case({pci_data_xfr, mem_wr_incr})
     end // else: !if(!rstn)
   
   
   wire        undo = (m_state == RETRY) ? 1'b1: 1'b0;   
   reg [7:0]   mem_addr;
   always @ (posedge clk or negedge rstn)
     if (!rstn)
       mem_addr <= 8'b0;
     else begin
	if (m_state == IDLE)
	  mem_addr <= LOCAL_ADDR;
	else if (m_state == RETRY & wr_rdn)
	  mem_addr <= (mem_addr ) - pipe;
	else if (mem_incr)
	  mem_addr <= mem_addr + 1;
     end
   wire mem_wr_enable = !wr_rdn & !lm_dxfrn;
   wire        mem_rd_enable = wr_rdn & (!lm_req32n | !lm_ackn );
   

   wire [31:0] mem_rd_data;
   
   mem256x32 mem (.address(mem_addr),
		  .clock(clk),
		  .clken((mem_wr_enable | mem_rd_enable)),
		  .data (l_dato),
		  .wren(mem_wr_enable),
		  .q(mem_rd_data)
		  );
   
   // Drive TB data in case of a configuration write
   wire [31:0] t_rd_data = (command == 4'b1011) ? LOCAL_DATA : mem_rd_data;
   // Drive PCI address and command on the address cyclce
   
   wire [31:0] l_adi = data_sel  ?  t_rd_data : paddr;
   wire [3:0]  l_cbeni = data_sel ? 4'h0 : command;


   
   // tb control signals
   always @ (posedge clk or negedge rstn)
     if (!rstn) begin
	done <= 1'b0;
	error <= 1'b0;
     end else begin
	if (m_state == IDLE & START ) begin
	   done <= 1'b0;
	   error <= 1'b0;
	end else if (m_state == CHK_STATE) begin
	   done <= xfr_done;
	   error <= fatal_error;
	end
     end // else: !if(!rstn)
   

endmodule // mstr_mem32

⌨️ 快捷键说明

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