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

📄 spi_control.v

📁 verilog语言写的SPI接口,全同步设计,低门数,可以很容易应用到嵌入设计方案中.
💻 V
字号:
//----------------------------------------------------------------------------
// Project  : SCP1 - Standard Communication Platform Version 1
//----------------------------------------------------------------------------
// Source   : $Source: /db1/Razor_db/RAZOR_UNIVERSE/DOMAIN_01/SCP/Archive/RZ_VCS/scp1/design/arm_periph/spi/rtl/spi_control.v,v $
// Revision : $Revision: 1.3 $
// Date     : $Date: 1999/09/08 07:30:34 $
// Author   : $Author: coste_e $
//
//-Description----------------------------------------------------------------
// 
// 
// 
//---------------------------------------------------------------------------



module spi_control (
		    nreset,
		    clk,

		    operation,
		    start,		    
		    end_bitcnt,
		    end_bytecnt,
		    end_waitcnt,
		    wait_en,
		    fifo_full,
		    fifo_empty,
		    break,
		    
		    load,
		    busy,
		    ns_rst_bitcnt,
		    ns_rst_bytecnt,
		    ns_rst_waitcnt,
		    stop_clk,
		    nwr_spi_fifo,
		    nrd_spi_fifo,
		    field,
		    spi_oen,
		    shift_ena,
		    stop_clkgen,
		    halt_clk
		    );


   input nreset;
   input clk;

   input [2:0] operation;
   input       start;
   input       end_bitcnt;
   input       end_bytecnt;
   input       end_waitcnt;
   input       wait_en;
   input       fifo_full;
   input       fifo_empty;
   input       break;
   
   output      load;
   output      busy;
   output      ns_rst_bitcnt;
   output      ns_rst_bytecnt;
   output      ns_rst_waitcnt;
   output      stop_clk;
   output      nwr_spi_fifo;
   output      nrd_spi_fifo;
   output [1:0] field;
   output 	spi_oen;
   output 	shift_ena;
   output 	stop_clkgen;
   output 	halt_clk;
   
   reg 		load;
   reg 		busy;
   reg 		ns_rst_bitcnt;
   reg 		ns_rst_bytecnt;
   reg 		ns_rst_waitcnt;
   reg 		stop_vlk;
   reg 		nwr_spi_fifo;
   reg 		nrd_spi_fifo;
   reg [1:0] 	field;
   reg 		spi_oen;
   reg 		shift_ena;
   reg 		stop_clk;
   reg 		stop_clkgen;
   reg 		halt_clk;
   
   
     
   reg [3:0] 	current_state;
   reg [3:0] 	next_state;

// PARAMETERS DEFINITION

parameter
  opcode_sel = 2'b01,
  addr_sel =2'b10,
  data_sel =2'b11;
   
   
   
parameter tQ         = 1;  // clock to Q delay
//state machine state definition

   `define RESET_STATE         4'h0
   `define OPCODE_LOAD         4'h1
   `define OPCODE_SHIFT        4'h2
   `define ADDR_LOAD           4'h3
   `define ADDR_SHIFT          4'h4
   `define WAIT_STATE          4'h5
   `define LOAD_DATA           4'h6
   `define SHIFT_DATA_OUT      4'h7
   `define WAIT_FIFO_REFIL     4'h8
   `define DEPHASE             4'h9
   `define SHIFT_DATA_IN       4'ha
   `define UNLOAD_DATA         4'hb
   `define WAIT_FIFO_UNLOAD    4'hc
   `define SHIFT_DATA_IN_MSB   4'hd
   `define FINISH              4'he
	
// glue logic used to determine next state and to 
// generate the commands
       
always @( current_state or
	  start or
	  operation or
	  end_bitcnt or
	  wait_en or
	  fifo_empty or
	  fifo_full or
	  break or
	  end_bytecnt or
	  end_waitcnt

	  )
  begin
//default value for the outputs of the state machine
    load=0;
    busy=1;
    ns_rst_bitcnt=0;
    ns_rst_waitcnt=0;
    ns_rst_bytecnt=0;
    stop_clk=0;
    nwr_spi_fifo=1;
    nrd_spi_fifo=1;
    field=2'h0;
    spi_oen=0;
    shift_ena=0;
    stop_clkgen=0;
    halt_clk=0;
    
    
    case(current_state)
     `RESET_STATE :
       begin
	 busy=0;
	 if(start)
	   begin
	     case (operation)
	      3'h5 : next_state=`DEPHASE;
	      
	      3'h6 : 
		if (!fifo_empty)
		  next_state=`LOAD_DATA;
		else
		  next_state=`RESET_STATE;
	      
	      default : next_state=`OPCODE_LOAD;
	     endcase // case(operation)
	   end // if (start)
	 else
	   next_state=`RESET_STATE;
       end // case: `RESET_STATE

     `OPCODE_LOAD :
       begin
	 load=1;
	 field=opcode_sel;
	 next_state=`OPCODE_SHIFT;
       end // case: `OPCODE_LOAD
          
     `OPCODE_SHIFT :
       begin
	 shift_ena=1;
	 ns_rst_bitcnt=1;
	 field=opcode_sel;
	 if (end_bitcnt)
	   begin
	     casex ({wait_en,operation})
	      4'h3   : next_state=`DEPHASE;
	      
	      4'h4   : 
		if (!fifo_empty)
		  next_state=`LOAD_DATA;
		else
		  next_state=`WAIT_FIFO_REFIL;
	      
	      4'bx00x : next_state=`ADDR_LOAD;
	      4'bx010 : next_state=`FINISH;
	      default : next_state=`WAIT_STATE;
	     endcase // case(operation)
	   end // if (end_bitcnt)
	 else
	   next_state=`OPCODE_SHIFT;         //continue shifting not enough bit sent
       end // case: `OPCODE_SHIFT

     `ADDR_LOAD :
       begin
	 load=1;
	 field=addr_sel;
	 next_state=`ADDR_SHIFT;
       end // case: `ADDR_LOAD

     `ADDR_SHIFT :
       begin
	 shift_ena=1;
	 field=addr_sel;
	 ns_rst_bitcnt=1;
	 if (end_bitcnt)
	   if(wait_en)
	     next_state=`WAIT_STATE;
	   else 
	     if (operation==3'h0)
	       next_state=`DEPHASE;  //Read data
	     else
	       if(!fifo_empty)
		 next_state=`LOAD_DATA;   //write data to spi device
	       else 
		 next_state=`WAIT_FIFO_REFIL; //need to write data to spi device but none available
	 else
	   next_state=`ADDR_SHIFT;         //continue shifting not enough bit sent
       end // case: `ADDR_SHIFT

     
     `WAIT_STATE :
       begin
	 ns_rst_waitcnt=1;
	 stop_clk=1;         //PAUSE SPI_CLock
	 if(end_waitcnt)
	   begin
	     if((operation==3'h4)||(operation==3'h1))
	       if(!fifo_empty)
		 next_state=`LOAD_DATA;   //write data to spi device
	       else 
		 next_state=`WAIT_FIFO_REFIL; //need to write data to spi device but none available
	     else
	       next_state=`DEPHASE;
	   end // if (end_waitcnt)
	 else
	   next_state=`WAIT_STATE;
       end // case: `WAIT_STATE

     `LOAD_DATA :
       begin
	 load=1;
	 field=data_sel;
	 ns_rst_bytecnt=1;
	 nrd_spi_fifo=0;
	 if(!end_bytecnt)
	   next_state=`SHIFT_DATA_OUT;
	 else
	   next_state=`FINISH;
       end // case: `LOAD_DATA
     `SHIFT_DATA_OUT :
       begin
	 field=data_sel;
	 ns_rst_bitcnt=1;
	 ns_rst_bytecnt=1;
	 shift_ena=1;
	 if (end_bitcnt)
	   //if(!end_bytecnt)  //not finished to write the page
	   if(!fifo_empty)  //more data to read in fifo => no need to wait for data
	     next_state=`LOAD_DATA;
	   else             //fifo is empty need to wait for new data
	     next_state=`WAIT_FIFO_REFIL;
	 //else               //page as been completely sent => finish
	   //  next_state=`FINISH;
	 else                //current byte transfer is not over 
	   next_state=`SHIFT_DATA_OUT;
       end // case: `SHIFT_DATA_OUT
     `WAIT_FIFO_REFIL :
       begin
	 field=data_sel;  //added
	 ns_rst_bytecnt=1;   //if not assereted then we loose track of how many byte sent
	 stop_clk=1;         //PAUSE SPI_CLock
	 if(!break&!end_bytecnt)          //user want to have "wait state" insterd during fifo refill
	   if(!fifo_empty)  //more data to read in fifo => no need to wait for data
	     next_state=`LOAD_DATA;
	   else             //fifo is empty need to wait for new data
	     next_state=`WAIT_FIFO_REFIL;
	 else
	   next_state=`FINISH;   //communication finished due to no more data available
       end // case: `WAIT_FIFO_REFIL
     
     
     `DEPHASE :
       begin
	 next_state=`SHIFT_DATA_IN;
       end // case: `DEPHASE

     `SHIFT_DATA_IN_MSB :
       begin
	 spi_oen=1;
	 shift_ena=1;
	 field=data_sel;
	 ns_rst_bytecnt=1;
	 next_state=`SHIFT_DATA_IN;
       end // case: `SHIFT_DATA_IN_MSB
     
     `SHIFT_DATA_IN :
       begin
	 spi_oen=1;
	 ns_rst_bytecnt=1;
	 field=data_sel;
	 ns_rst_bitcnt=1;
	 shift_ena=1;
	 if (end_bitcnt)
	   if(!fifo_full)
	     next_state=`UNLOAD_DATA;
	   else   //fifo is full => cannot add data otherwise data loss
	     next_state=`WAIT_FIFO_UNLOAD;
	 else
	   next_state=`SHIFT_DATA_IN;
       end // case: `SHIFT_DATA_IN

     `UNLOAD_DATA :
       begin
	 field=data_sel;   //just added
	 spi_oen=1;
	 shift_ena=1;
	 ns_rst_bytecnt=1;
	 nwr_spi_fifo=0;
	 if(!end_bytecnt)
	   next_state=`SHIFT_DATA_IN;
	 else
	   next_state=`FINISH;
       end // case: `UNLOAD_DATA
     
        
     `WAIT_FIFO_UNLOAD :
       begin
	 field=data_sel;  //added
	 spi_oen=1;
	 ns_rst_bytecnt=1;
	 stop_clk=1;
	 if(!fifo_full)
	   next_state=`UNLOAD_DATA;
	 else
	   if(break)
	     next_state=`FINISH;
	   else
	     next_state=`WAIT_FIFO_UNLOAD;
       end // case: `WAIT_FIFO_UNLOAD
         
     `FINISH :
       begin
	 halt_clk=1;
	 stop_clkgen=1;
	 next_state=`RESET_STATE;
       end // case: `FINISH_EVEN
     
     
	 
     
     default : next_state = `RESET_STATE;
    endcase // case(current_state)
  end // always (current_state)


// sequential part of the state machine
// hopefully the synthesyser can optimize this and the
// combinational logic above to reduce the number of states

   
   always @(negedge nreset or posedge clk)
     begin
       if(!nreset)
	 current_state <=  `RESET_STATE;
       else
	 current_state <= next_state;
     end // always @ (negedge nreset or posedge clk)


endmodule // spi_contro

⌨️ 快捷键说明

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