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

📄 ahb_slave_sm.v

📁 altera epxa1的例子程序
💻 V
字号:
// Copyright (C) 1991-2001 Altera Corporation
// Any megafunction design, and related net list (encrypted or decrypted),
// support information, device programming or simulation file, and any other
// associated documentation or information provided by Altera or a partner
// under Altera's Megafunction Partnership Program may be used only to
// program PLD devices (but not masked PLD devices) from Altera.  Any other
// use of such megafunction design, net list, support information, device
// programming or simulation file, or any other related documentation or
// information is prohibited for any other purpose, including, but not
// limited to modification, reverse engineering, de-compiling, or use with
// any other silicon devices, unless such use is explicitly licensed under
// a separate agreement with Altera or a megafunction partner.  Title to
// the intellectual property, including patents, copyrights, trademarks,
// trade secrets, or maskworks, embodied in any such megafunction design,
// net list, support information, device programming or simulation file, or
// any other related documentation or information provided by Altera or a
// megafunction partner, remains with Altera, the megafunction partner, or
// their respective licensors.  No other licenses, including any licenses
// needed under any third party's intellectual property, are provided herein.

`include ".\rtl\ahb_slave_include.v"


//TOP MODULE

module ahb_slave_sm(HSEL, 
		    HCLOCK,
		    HADDRESS,
		    HWRITE,
		    HTRANS,
		    HSIZE,
		    HBURST,     
		    HRESETn,    	     
		    HWDATA,     	     
		    HRDATA,     	     
		    HRESP,      	     
		    HREADY,     	     
		    reg_write,  	     
		    reg_address,	     
		    reg_wdata,  	     
		    latch_bus,   	     
		    reg_rdata); 	     
// INPUTS
	input	     HSEL;			//Chip enable
	input [31:0] HADDRESS;                  //AHB Address signals
	input [31:0] HWDATA;			//Data lines
	input	     HWRITE;			//High = Write Low = Read
	input [1:0]  HTRANS;			//Transfer type. Only nonseq is supported
	input [1:0]  HSIZE;			//Size of data packet. Only 32 is supported
        input [2:0]  HBURST;			//Size of burst. Only 1 is supported
	input	     HRESETn;			//System reset. Active low
	input        HCLOCK;			//system clock
	input [31:0] reg_rdata;			//read data from register file
	
	    
// OUTPUTS	
	output [1:0]  HRESP;			//Slave response to status of xfer
        output [31:0] HRDATA;			//Read Data bus
	output [31:0] reg_address;		//address written to register file
	output 	      reg_write;		//register file write/read signal
	output [31:0] reg_wdata;		//Data written to register file
	output        HREADY;			//Insert wait states
	output 	      latch_bus;
//Internal Declarations
	reg [1:0]  HRESP;			//Statemachine output
	reg [31:0] reg_address;		        //Used to latch HADDRESS During Address phase
	reg 	   reg_write;		        //Used to latch HWRITE During Address phase
	reg [1:0]  slave_state;		        //State machine state
	reg	   HREADY;		        //Internal reg
	reg	   latch_bus;		        //latched data buses
//PARAMETERS

parameter ADDRESS_PHASE = 2'b00,                //State machine states
	  DATA_PHASE = 2'b10,
	  READ_WAIT_PHASE = 2'b11,
	  ERROR_PHASE = 2'b01;


//Main Code

assign HRDATA = HRESETn ? reg_rdata : 32'd0;    
assign reg_wdata = HRESETn ? HWDATA : 32'd0;

  
     
   always @(posedge HCLOCK or negedge HRESETn )
	begin
	    if(HRESETn == 1'b0) begin			//Async Reset
		  slave_state <= ADDRESS_PHASE;
		  HRESP <= `OKAY;
		  HREADY <= 1'b1;
		  latch_bus <= 1'b0;
		  reg_address <= 32'D0;
		  reg_write <= 1'b0;
	     end
	     
	   else begin
	   
	   case (slave_state)
	   	ADDRESS_PHASE : begin
		  	if(HSEL == 1'b0) begin				//Slave not selected
				slave_state <= ADDRESS_PHASE;
		  		HRESP <= `OKAY;
		  		HREADY <= 1'b1;
		    		latch_bus <= 1'b0;
		  		reg_address <= 32'd0;
		  		reg_write <= 1'b0;        
		  	end                                  		
		  	else if(HTRANS == `IDLE)begin        		//No new transaction on this clock
		    		slave_state <= ADDRESS_PHASE;
		  		HRESP <= `OKAY;
		  		HREADY <= 1'b1;
		    		latch_bus <= 1'b0;
		  		reg_address <= 32'd0;
		  		reg_write <= 1'b0;        
		   	end
		   	else if(HTRANS == `SEQ)begin   			 //Protocol violation
		    		slave_state <= ERROR_PHASE;
		    		HREADY <= 1'b0;
		    		HRESP <= `ERROR;
		    		latch_bus <= 1'b0;
		    		reg_address <= 32'd0;
		  		reg_write <= 1'b0;     	     
		  	end
		  	else if(HSIZE != `AHB_WORD)begin    		//Only supports word transactions
		    		slave_state <= ERROR_PHASE;
		    		HREADY <= 1'b0;
		    		HRESP <= `ERROR;
		    		latch_bus <= 1'b0;
		    		reg_address <= 32'd0;
		  		reg_write <= 1'b0;     	     
		  	end
			else if(HBURST > `INCR)begin        		//Only supports unspecfied INCR and single transactions
		    		slave_state <= ERROR_PHASE;
		    		HREADY <= 1'b0;
		    		latch_bus <= 1'b0;
		    		reg_address <= 32'd0;
		  		reg_write <= 1'b0;     	     
		  	end
		  	else if(HADDRESS[4:0] > 20)begin		  //Highest address in reg file is 20
		   		slave_state <= ERROR_PHASE;
		    		HREADY <= 1'b0;
		    		HRESP <= `ERROR;
		    		latch_bus <= 1'b0;
		    		reg_address <= 32'd0;
		  		reg_write <= 1'b0;     
		  	end
		  	else if(HADDRESS[4:0] > 12 && HWRITE == 1'b1)begin  //address 16 and 20 are read only
		   		slave_state <= ERROR_PHASE;
		    		HREADY <= 1'b0;
		    		HRESP <= `ERROR;
		    		latch_bus <= 1'b0;
		    		reg_address <= 32'd0;
		  		reg_write <= 1'b0;     
		  	end
			else if(HTRANS == `NONSEQ)begin	  			//valid transaction
		    		if(HWRITE == `AHB_WRITE)begin
		    			slave_state <= DATA_PHASE;
		  			HRESP <= `OKAY;
		  			HREADY <= 1'b1;
		  			latch_bus <= 1'b1;
		  			reg_address <= HADDRESS;
		  			reg_write <= 1'b1;        
		    		end
		    		else begin
		    			slave_state <= READ_WAIT_PHASE;
		  			HRESP <= `OKAY;
		  			HREADY <= 1'b0;
		  			latch_bus <= 1'b1;
		  			reg_address <= HADDRESS;
		  			reg_write <= 1'b0;        
		    		end
		    		
		    	end
		    	else begin
		    		slave_state <= ADDRESS_PHASE;
		  		HRESP <= `OKAY;
		  		HREADY <= 1'b1;
		  		latch_bus <= 1'b0;
		  		reg_address <= 32'd0;
		  		reg_write <= 1'b0;        
		    	end
		end
	     	READ_WAIT_PHASE: begin
	     									//should do some protocol checks but we'll pass
	     		slave_state <= DATA_PHASE;
			HRESP <= `OKAY;
			HREADY <= 1'b1;
			latch_bus <= 1'b1;
			reg_address <= reg_address;
			reg_write <= 1'b0;        
	     	end
	     ERROR_PHASE:begin
			slave_state <= ADDRESS_PHASE;
			HREADY <= 1'b1;
			HRESP <= `ERROR;
			latch_bus <= 1'b0;
			reg_address <= 32'd0;
			reg_write <= 1'b0;      
	     end
	     default: begin							//data phase
	     									//should do some protocol checks but we'll pass
	     	if(HTRANS == `BUSY)begin	  						
	      		slave_state <= DATA_PHASE;
		  	HRESP <= `OKAY;
		  	HREADY <= 1'b1;
		    	latch_bus <= 1'b0;
		 end
		 else if(HTRANS == `SEQ)begin
		 	if(HWRITE == `AHB_READ)begin
		 		slave_state <= READ_WAIT_PHASE;
		  		HRESP <= `OKAY;
		  		HREADY <= 1'b0;
		   		latch_bus <= 1'b1;
		  		reg_address <= HADDRESS;
		  		reg_write <= 1'b0;    	
		 	end
		 	else begin	  
	      			slave_state <= DATA_PHASE;
		  		HRESP <= `OKAY;
		  		HREADY <= 1'b1;
		   		latch_bus <= 1'b1;
		  		reg_address <= HADDRESS;
		  		reg_write <= 1'b1;        
		  	end
		 end
		 else begin						
	      		slave_state <= ADDRESS_PHASE;
		  	HRESP <= `OKAY;
		  	HREADY <= 1'b1;
		   	latch_bus <= 1'b0;
		  	reg_address <= HADDRESS;
		  	reg_write <= 1'b0;        
		 end	     				     		         
	    end
	   endcase
	 end
	end
endmodule


⌨️ 快捷键说明

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