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

📄 spi_clock_gen.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_clock_gen.v,v $
// Revision : $Revision: 1.3 $
// Date     : $Date: 1999/09/08 06:59:28 $
// Author   : $Author: coste_e $
//
//-Description----------------------------------------------------------------
// 
// 
// 
//---------------------------------------------------------------------------



module spi_clock_gen(
		     nreset,    //async system reset
		     clk,       //system clock
		     start,   //start transmition signal
		     spi_mode,  //spi mode
		     stop_clk, //used to assert wait state or stop the clock.
		     end_communication, //from main state machine when comm is over
		     spi_clk,   //spi clock to be sent to device only
		     base_cs,    //Chip select used to generate all devices chip selects
		     halt_clk,
		     fifo_empty,
		     transfer_type,
		     time_ext,
		     cs_gen_busy,
		     cs_done
		     );

   `define IDLE     3'h0
   `define ENA_CLK  3'h1
   `define TEMPO    3'h2
   `define STOP_CLK 3'h3
   `define STOP_CS  3'h4
   `define CS_SETUPADD 3'h5
   `define CS_HOLDADD 3'h6
   `define CS_IDLEADD 3'h7
   
   input nreset;
   input clk;
   input start;
   input [1:0] spi_mode;
   input       stop_clk;
   input       end_communication;
   output      spi_clk;
   output      base_cs;
   input       halt_clk;
   input       fifo_empty;
   input [2:0] transfer_type;
   input [2:0] time_ext;
   output      cs_gen_busy;
   output      cs_done;

   
   reg 	       spi_clk;
   reg 	       base_cs;
   reg 	       cs_gen_busy;
   wire        cs_done;
   reg        start_able;
//-----------------------------------------------------------------------------
// Parameters and constants   
//-----------------------------------------------------------------------------
// All flip-flops are modeled (in RTL) with a (cp->q) delay: tcQ.
// This is to prevent potential problems with gated clocks.

   parameter tcQ=1;

// wires and registers inaciation

  
   reg 	     spi_clk_ena;
   wire      inactive_level; //inactive level of spi_clk
   reg [2:0] next_state;
   reg [2:0] current_state;
   wire      tci_c;
   reg 	     load;
   assign cs_done= (time_ext==3'b000)?start:tci_c&start_able;
   
   

// state machine controling the start of spi clk
// the goal of this stae machine is to have the active edge of
// spi always at the same place in time whatever the mode
// selected. Therefore for mode 1 and 3 it is nescessary to
// start the clock for mode 1 and 3 ealier than for mode 0 and 2.
// In addition we need to have the Chip select to move one spi_clock
// period (2 clk period) before the first active edge of spi_clock
// thus upon detecting the start signal we need to assert the 
// base_cs signal regardless of the spi mode (thanks to the 
// fact that all the active edge will be at the same point in time. 
// NB. * marks the active edge  

//TEMPO state is here to have all the active edge alligned in time 
//whatever the given mode
//TEMPO2 is here to ensure that Chip select will remain active for 
//1 spi_clk clock period (0.5 clock period due to sync between control SM
// and 0.5 due to TEMPO2)      
/*
             __    __    __    __   __    __
clk        _|  |__|  |__|  |__|  |_|  |__|  |_
             _____
start      _/     \__________________________
                   __________________________
base_cs   ________/ 
                               _____      ____
mode0_clk ____________________*     \____*
                         _____       ____    
mode1_clk ______________/     *_____/    *____
          ____________________       ____
mode2_clk                     *_____/    *
          ______________       _____      ____
mode3_clk               \_____*     \____*
*/
//state machine combinatioanl part

   
    always @ (current_state or spi_mode or end_communication or 
	     start or fifo_empty or transfer_type or tci_c)
     begin
       //default value of the output signals
       base_cs=1;
       spi_clk_ena=0;
       cs_gen_busy=1;
       load=0;
       start_able=0;
       
       case(current_state)
	`IDLE :
	  begin
	    base_cs=0;
	    cs_gen_busy=0;
	    load=1;
	    if(start&((transfer_type==3'h6)&(!fifo_empty)|transfer_type!=3'h6))
	      begin
		if(tci_c)
		  if((spi_mode==2'h0)||(spi_mode==2'h2))
		    next_state=`TEMPO;
		  else
		    next_state=`ENA_CLK;
		else
		  next_state=`CS_SETUPADD;
	      end // else: !if(transfer_type==3'h6)
	    else
	      next_state=`IDLE;
	  end // case: `STOP_CLK
	
	`TEMPO :   next_state=`ENA_CLK;
	
	
	`CS_SETUPADD :
	  begin
	    start_able=1;
	    if(tci_c)
	      if((spi_mode==2'h0)||(spi_mode==2'h2))
		next_state=`TEMPO;
	      else
		next_state=`ENA_CLK;
	    else
	      next_state=`CS_SETUPADD;
	  end // case: `SETUPADD

	`ENA_CLK :
	  begin
	    spi_clk_ena=1;
	    load=1;
	    if(end_communication)
	      if((spi_mode==2'h1)|(spi_mode==2'h2))
		next_state=`STOP_CLK;
	      else
		next_state=`STOP_CLK;
	    else
	      next_state=`ENA_CLK;
	  end // case: `ENA_CLK
	
	`STOP_CLK : 
	  begin
	    load=1;
	    if (tci_c) 
	      next_state=`STOP_CS;
	    else
	      next_state=`CS_HOLDADD;
	  end // case: `STOP_CLK
	
	`CS_HOLDADD :
	  if (tci_c) 
	    next_state=`STOP_CS;
	  else
	    next_state=`CS_HOLDADD;
	
	`STOP_CS : 
	  begin
	    base_cs=0;
	    load=1;
	    if(tci_c)
	      next_state=`IDLE;
	    else
	      next_state=`CS_IDLEADD;
	  end // case: `STOP_CS
	
	`CS_IDLEADD : 
	  begin
	    base_cs=0;
	    if(tci_c)
	      next_state=`IDLE;
	    else
	      next_state=`CS_IDLEADD;
	  end // case: `CS_IDLEADD
	
	default : next_state=`IDLE;
	
       endcase // case(current_state)
     end // always @ (spi_mode or stop_clk or start)
   
   
   //sequential part of the Sate Machine
   always @(posedge clk or negedge nreset)
     if(!nreset)
       current_state<=`IDLE;
     else
       current_state<=next_state;
   
			 
    
// acording to spi mode the inactive level of the clock should be eithe
// '0' for mode 0 and 2 and '1' for mode 1 and 3.
// inactive means the clock is not pulsing and SPI_CS inactive.
   
   assign inactive_level = spi_mode[1];


   
 
// ff to generate glitch free spi_clk at a frequency of clk/2.
// the pause_clk signal is used to add the wait states.
// when pause_clk is asserted spi_clk is stoppped at 
// - '0' level for spi mode 1 and 2
// - '1' level for spi mode 0 and 3
// this is to say on the level folowing the active edge for
// a given mode
   
   always @(negedge nreset or posedge clk)
     begin
       if (~nreset)
	 spi_clk <= 0;
       else
	 begin
	 if((~spi_clk_ena) || halt_clk)
	   spi_clk <= inactive_level;
	 else
	   if(stop_clk)
	     spi_clk <= spi_clk;
	   else
	     spi_clk <= !spi_clk;
	 end // else: !if(!nreset)
       
     end // always @ (posedge clk)

   
   spi_cs_cnt u1 (.clk(clk),       // Clock Input
		  .cdn(nreset),       // Clear Direct Not Input
		  .load(load),      // Load Control Input
		  .datain(time_ext),    // Data Input
		  .q(),         //  3 bit Result
		  .tci(tci));      // Terminal Count Indicator

   assign tci_c=tci | (time_ext==3'b000);
   
endmodule // spi_clock_gen



/*
spi_clock_gen(
                     .nreset(),    //async system reset
		     .clk(),       //system clock
		     .start(),     //start transmition signal 
		     .spi_mode(), //spi mode
		     .stop_clk(), //used to asser wait state or stop the clock
		     .end_communication(), //from main state machine when comm is over
		     .spi_clk(),   // spi clock to be sent to device only
		     .base_cs(),    //Chip select used to generate all devices chip selects 
                     .halt_clk(),
		     .fifo_empty(),
		     .transfer_type(),
                     .cs_gen_busy() //block is busy cannot start a new transfer yet
		     );
*/
  

⌨️ 快捷键说明

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