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

📄 spi_tx_rx.v

📁 verilog语言写的SPI接口,全同步设计,低门数,可以很容易应用到嵌入设计方案中.
💻 V
字号:
module spi_tx_rx(
		 nreset,              //asynchronous system reset 
		 clk,                 //clock (only use rising edge)
		 nrestart_bitcnt,     //synchronous reset for bit counter
		 field,               //indicate what is to be send/received op/addr/data
		 opcode_length,       //number of valid bit in opcode field
		 opcode_field,        //opcode to send
		 address_length,      //number of valid bit in address field
		 addr_field,          //address to be sent
		 data_field,          //data to be sent.
		 lcd_a,               //parralel value for spi_a pin
		 shift,               //makes shift register shift
		 load,                //makes the shift register load parralell value
		 spi_si,              //serial input
		 spi_so,              //serial output 
		 end_transmit,        //active high when number_of_bit have been tx/rx
		 data_received,       //serialy received data
		 nrestart_bytecnt,    //restart byte counter
		 number_of_byte,      //number of data byte to send/receive
		 end_data_txrx,       //active high when number_of_byte have been tx/rx
		 spi_a,               //indicate to lcd if data is control/raw data
		 n_opcode_addr_busy   //
		 );

   input nreset;
   input clk;
   input nrestart_bitcnt;
   input [1:0] field;
   input [5:0] opcode_length;
   input [31:0] opcode_field;
   input [5:0] address_length;
   input [31:0] addr_field;
   input [7:0] data_field;
   input [1:0] 	lcd_a;
   input 	shift;
   input 	load;
   input 	spi_si;

   output 	spi_so 	;
   output 	end_transmit;
   output [7:0] data_received; // data received is only 8 bit wide because
                               //the only place where receicved data are
                               //going is fifo and the fifo is 8 bit wide
   input 	 nrestart_bytecnt;
   input [7:0] 	 number_of_byte;
   output 	 end_data_txrx;
   output 	 spi_a;
   output 	 n_opcode_addr_busy;

//-----------------------------------------------------------------------------
// 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 definition
   reg [5:0] 	number_of_bit; //number of bit to transmit
   reg [31:0] 	data_to_send; //data to be sent serialy
   wire 	spi_so;       //serial output
   wire 	end_transmit; //active high, activate when number_of_bit have been sent 	
   wire [7:0] 	data_received; //received data from the SPI device
   wire 	end_data_txrx;
   wire 	byte_count;
   reg 		n_opcode_addr_busy;
   reg 		spi_a,spi_a_c;
   
   reg 		end_transmit_r;
   
   // shift register instanciation
   reg [31:0] 	shift_reg;

   
   spi_bitcounter bitcnt (.clk(clk),       // Clock Input
			  .cdn(nreset),       // Clear Direct Not Input
			  .csn(nrestart_bitcnt),
			  .cen(shift),       // Count Enable Input
			  .maxval(number_of_bit),    // Programmable Maximum Count Value
			  .q(),         //  3 bit Result
			  .tci(end_transmit));      // Terminal Count Indicator

   
   spi_bytecounter bytecnt (.clk(clk),       // Clock Input
			    .cdn(nreset),       // Clear Direct Not Input
			    .csn(nrestart_bytecnt),
			    .cen(byte_count),       // Count Enable Input
			    .maxval({number_of_byte}),    // Programmable Maximum Count Value
			    .q(),         //  3 bit Result
			    .tci(end_data_txrx));      // Terminal Count Indicator
   

  
   
   always @(posedge clk or negedge nreset)
     if(!nreset)
       end_transmit_r<=0;
     else
       end_transmit_r<=end_transmit;

   assign data_received=shift_reg[7:0];
   assign byte_count=end_transmit&(~end_transmit_r);  
   
   
// shift register to shift out/in the dat to/from the SPI device
// the length of the shift register is 24 bits. This is due to the 
// size of the address field. It is possible to reduce it to
// 8 bit however this will introduce extra complexity in the
// control part for a limited gain in term of gate
// this shift register shifts MSB first;
   
   assign spi_so=shift_reg[31];
 
     
   always @(posedge clk)
     begin
       if(load)
	 shift_reg <= #tcQ data_to_send;
       else
	 if (shift)
	   begin
	     shift_reg[31:1] <= #tcQ shift_reg[30:0];  //shift out msb first
	     shift_reg[0] <= #tcQ spi_si;
	   end 
	 else
	   shift_reg <= #tcQ shift_reg;  //shift out msb first
       
     end // always @ (negedge nreset or negedge clk)



   //select the appropriate data to be sent to the shift register
//and the number of bit that are to be sent
//according to the control state machine field instruction
//This introduce only combinational logic
   always @(field or opcode_field or addr_field or data_field
	    or opcode_length or address_length or lcd_a)
     begin
       case(field)
	2'b01   : 
	  begin 
	    data_to_send = opcode_field; 
	    number_of_bit = opcode_length;
	    spi_a_c=lcd_a[0];
	    n_opcode_addr_busy=0;
	  end
	2'b10   : 
	  begin 
	    data_to_send = addr_field; 
	    number_of_bit = address_length;
	    spi_a_c=lcd_a[0];
	    n_opcode_addr_busy=0;
	  end
	2'b11   : 
	  begin 
	    data_to_send[31:24] = data_field;
	    data_to_send[23:0] = 24'hxx_xx_xx;
	    number_of_bit={2'b00,3'b111};
	    spi_a_c=lcd_a[1];
	    n_opcode_addr_busy=1;
	  end
	default : 
	  begin 
	    data_to_send = 32'hxx_xx_xx_xx;
	    number_of_bit=5'b11111; 
	    spi_a_c=lcd_a[1];
	    n_opcode_addr_busy=0;
	  end
       endcase
       end // always @ (field or opcode_field or addr_field)

   always @(posedge clk)
     spi_a<=spi_a_c;

endmodule // spi_rx_tx

/*
 spi_rx_tx{
		 .nreset(),              //asynchronous system reset 
		 .clk(),                 //clock (only use rising edge)
		 .nrestart_bitcnt(),     //synchronous reset for bit counter
 		 .field_selector(),      //indicate what is to be send/received op/addr/data
		 .opcode_length(),       //number of valid bit in opcode field
		 .opcode(),              //opcode to send
		 .address_length(),      //number of valid bit in address field
		 .addr_field(),          //address to be sent
		 .data_field(),          //data to be sent.
		 .lcd_a(),               //parralel value for spi_a pin
		 .shift(),               //makes shift register shift
		 .load(),                //makes the shift register load parralell value
		 .spi_si(),              //serial input
		 .spi_so(),              //serial output 
		 .end_transmit(),        //active high when number_of bit have been sent
		 .data_received(),       //serialy received data
		 .nrestart_bytecnt(),    //restart byte counter
		 .number_of_byte(),      //number of data byte to send/receive
		 .end_data_txrx(),       //active high when number_of_byte have been tx/rx
		 .spi_a(),               //indicate to lcd if data is control/raw data
                 .n_opcode_addr_busy()   //
                 );
*

⌨️ 快捷键说明

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