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

📄 spi.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.v,v $
// Revision : $Revision: 1.6 $
// Date     : $Date: 2000/02/16 09:53:26 $
// Author   : $Author: velard_j $
//
//-Description----------------------------------------------------------------
// 
// 
// 
//---------------------------------------------------------------------------

module spi(
	   psel_spi,
	   pstb,
	   pa,
	   pdi,
	   pdo,
	   pwrite,
	   pclk,
	   pnres,
	   test_comb,
	   scan_in1,
	   scan_in2,
	   scan_in3,
	   scan_out1,
	   scan_out2,
	   scan_out3,
	   test_shift,
	   spi_si,
	   spi_so,
	   spi_clk,
	   spi_a,
	   spi_oen,
	   spi_cs,
	   powerdown,
	   spi_int,
	   pdoe,
	   dma_req,
	   dma_op_add_req
	   );
   

// I/O definitions

   input psel_spi;
   input pstb;
   input [7:0] pa;
   input [7:0] pdi;
   output [7:0] pdo;
   input 	pwrite;
   input 	pclk;
   input 	pnres;
   input 	test_comb;
   input 	scan_in1;
   input 	scan_in2;
   input 	scan_in3;
   output 	scan_out1;
   output 	scan_out2;
   output 	scan_out3;
   input 	test_shift;
   input 	spi_si;
   output 	spi_so;
   output 	spi_clk;
   output 	spi_a;
   output 	spi_oen;
   output [3:0] spi_cs;
   input 	powerdown;
   output 	spi_int;
   output 	pdoe;
   output 	dma_req;
   output 	dma_op_add_req;
   
   
//wire and reg definition for interconnexion

   wire [7:0] 	pdo;
   wire 	spi_so;
   wire 	spi_clk;
   wire 	spi_a;
   wire 	spi_oen;
   wire [3:0] 	spi_cs;
   wire 	spi_int;
 
   

   wire 	busy;
   wire [5:0] 	opcode_length;
   wire [5:0] 	address_length;
   wire [1:0] 	spi_mode;
   wire 	wait_state_en;
   wire [1:0] 	wait_numb;
   wire 	start;
   wire [2:0] 	transfert_type;
   wire [31:0] 	opcode_field;
   wire [31:0] 	addr_field;
   wire 	function_clk;
   wire 	nenable_reg_clk;
  

   wire [7:0] 	fifo_do;
   wire [7:0] 	fifo_di;
   wire [7:0] 	page_size;
   wire [3:0] 	cs_polarity;
   wire [1:0] 	activate_cs;
   wire [7:0] 	rxdata;
   wire [3:0] 	fifo_level;
   wire [3:0] 	tx_trigger;
   wire [3:0] 	rx_trigger;
   wire [3:0] 	clk_divider;
   wire [1:0] 	it_mask;
   wire [1:0] 	int_val;
   wire [1:0] 	lcd_a;
   wire [7:0] 	page_number;
   wire [1:0] 	dma_mask;
   wire [2:0] 	time_ext;
      
   wire 	ntest_comb;
   wire 	nena_fifo_clk;
   wire 	nclkena;
   

   
// Instances palcement 
   spi_regs reg_if
     (//-- VPB --------------------------------------------------------------------
      .psel_spi(psel_spi),
      .pstb(pstb),
      .pa(pa),
      .pdin(pdi),
      .pdout(pdo),
      .pwrite(pwrite),
      //-- clk/reset --------------------------------------------------------------
      .pclk(reg_clk),
      .pnres(pnres),
      //-- SPI specific I/Os-------------------------------------------------------
      .fifo_do(fifo_do),         // fifo data out bus
      .busy(busy),               // transfer is ongoing
      .opcode_length(opcode_length),      // specify the size of opcode field to be sent
      .address_length(address_length),     // specify the size of address field to be sent
      .spi_mode(spi_mode),                // specify which spi mode will be used for transfert 0 1 2 3
      .wait_state_en(wait_state_en),      // activation of wait state between opcode-address and data 
      .wait_state_numb(wait_numb),    // number of wait state to be insterted.
      .device_cs_polarity(cs_polarity), // active high/low chip select for the devices.
      .addressed_device(activate_cs),   // which device is addressed acive high (broadcast possible)
      .start_transfert(start_reg),    // statr transfer. to be plugged on an edge detector
      .transfert_type(transfert_type),     // read/write/opcode... type of tranfert
      .address_field(addr_field),      // address bits to be sent (from MSB to LSB)
      .opcode_field(opcode_field),       // opcode to be sent to device from MSB
      .page_size(page_size),          // number of bytes to be sent/received
      .lcd_address(lcd_a),         // LCD specific serial address bit
      .nwr_fifo(nwr_fifo_reg),           // write data to fifo 
      .nrd_fifo(nrd_fifo_reg),            // read_data from fifo
      .break(break),           //in case of fifo full/empty stop transmission completely
      .clk_divider(clk_divider),
      .it_mask(it_mask),
      .tx_trigger(tx_trigger),
      .rx_trigger(rx_trigger),
      .int_reg_read(int_reg_read),
      .spi_int(spi_int),
      .dma_mask(dma_mask),
      
      .int_val(int_val),
      .fifo_full(fifo_full),
      .fifo_empty(fifo_empty),
      .fifo_level(fifo_level[2:0]),
      .pdoe(pdoe),
      .page_number(page_number),
      .time_ext(time_ext)
		  
      ); 
   
   
   spi_core core(
		 .clk(function_clk),             //clock 
		 .nreset(pnres),          //async system reset
		 .wait_state_en(wait_state_en),   //enable usage of wait states
		 .spi_si(spi_si),          //spi serial output
		 .spi_mode(spi_mode),        //spi mode (0, 1, 2, 3)
		 .opcode_length(opcode_length),   //size of opcode to be transmitted
		 .address_length(address_length),  //size of address to be sent
		 .wait_numb(wait_numb),       //number of wait states to be inserted
		 .opcode_field(opcode_field),    //opcode to send
		 .addr_field(addr_field),      //adress to send
		 .data_field(fifo_do),      //data to send
		 .start(start),           //initiate transfert
		 .transfert_type(transfert_type),  //read/write, opcode+read/write ....
		 .break(break),           //in case of fifo full/empty stop transmission completely
		 .lcd_a(lcd_a),           //bit value to be sent with opcode+address and data field
		 .time_ext(time_ext),
		 
		 .spi_clk(spi_clk),         //spi clock to be sent to device
		 .spi_so(spi_so),          //spi serial output
		 .busy(busy),            //indicates a tranfer is ongoing
		 .fifo_empty(fifo_empty),      //fifo is empty 
		 .fifo_full(fifo_full),       //fifo is full
		 .nwr_fifo_r(nwr_fifo_core),        //write to fifo
		 .nrd_fifo(nrd_fifo_core),         //read from fifo
		 .nb_data_byte(page_size),    //number of data byte to send, receive
		 .activate_cs(activate_cs),     //designate the device that will be addressed
		 .inactive_cs_state(cs_polarity),//activity level of the cs
		 .spi_cs(spi_cs),           //spi chip select to devices  
		 .spi_oen(spi_oen),           //spi output enable active low
		 .rxdata(rxdata),            //serialy received data
		 .spi_a(spi_a),             //serial address for LCD
		 .transfert_started(transfert_started),
		 .page_number(page_number),
		 .n_opcode_addr_busy(n_opcode_addr_busy)
		 );      

   spi_it int(
	      .clk(fifo_clk),
	      .nreset(pnres),
	      .read(int_reg_read),
	      .end_com(~busy),
	      .fifo_level(fifo_level),
	      .rx_trigger_level(rx_trigger),
	      .tx_trigger_level(tx_trigger),
	      .operation(transfert_type),
	      .mask(it_mask),
	      .dma_mask(dma_mask),
	      .start_from_reg(start_reg),
	      .busy(transfert_started),
	      .n_opcode_addr_busy(n_opcode_addr_busy),
	      
	      .spi_int(spi_int),
	      .it_val(int_val),
	      .dma_req(dma_req),
	      .start_to_core(start),
	      .dma_op_add_req(dma_op_add_req)
	      );
// the current fifo depth is 8 bytes if you want to change this please
// open the spi_fifo.v file to check the parameter used for HDLI, then
// reproduce them and change the fifo depth according to your
// wishes.
// it will also be nescessary to make some small modification to the
// Interupt block due to a change in the fifo_level_bus size.
//
   
  spi_fifo fifo(.cp(fifo_clk),         // FIFO clock
                .nrd(fifo_nrd),        // FIFO Read enable
                .nwr(fifo_nwr),        // FIFO Write enable
                .nreseta(pnres),    // FIFO asynchronous reset
                .di(fifo_di),         // FIFO Data input
                .full(fifo_full),       // FIFO Full flag
                .empty(fifo_empty),      // FIFO Empty flag
                .level(fifo_level),      // FIFO Real time level indicator bus
                .do(fifo_do));        // FIFO Data output bus

   
   
//clock divider used to have a spi programable clock speed
//if the clock gating scheme is not in use the folowing can be removed   
   
   spi_clkdiv_count clkdiv_cnt (.clk(div_clk),       // Clock Input
				.cdn(pnres),       // Clear Direct Not Input
				.maxval(clk_divider),    // Programmable Maximum Count Value
				.q(),         //  3 bit Result
				.tci(clkdiv_tci));      // Terminal Count Indicator

   reg 		nrd_fifo_core_r;
   
   always @(posedge fifo_clk or negedge pnres)   //flop used to make the nrd signal comming from core
     if(!pnres)                                 //to fifo one clock edge regardless of where the clock
       nrd_fifo_core_r<=1;                      //is comming from, register or core. 
     else                                       //it is required that the reg clock is faster than function
       nrd_fifo_core_r<=nrd_fifo_core;          //clock
     
   reg 		nwr_fifo_core_r;
   
   always @(posedge fifo_clk or negedge pnres)   //flop used to make the nwr signal comming from core
     if(!pnres)                                 //to fifo one clock edge regardless of where the clock
       nwr_fifo_core_r<=1;                      //is comming from, register or core. 
     else                                       //it is required that the reg clock is faster than function
       nwr_fifo_core_r<=nwr_fifo_core;          //clock
    
   
//top level glue logic for clock gating due to power consumption

   assign fifo_nwr=nwr_fifo_reg & (nwr_fifo_core | ~nwr_fifo_core_r);
   assign fifo_nrd=nrd_fifo_reg & (~nrd_fifo_core | nrd_fifo_core_r);
   assign fifo_di= nwr_fifo_core ? pdi : rxdata;
   
   assign nclkena = (~clkdiv_tci)| powerdown;         //negative enable for funtioanl clock
   assign nenable_reg_clk = ~psel_spi;                //negative enable for register clock
   assign nena_fifo_clk = nenable_reg_clk & nclkena; //negative enable for fifo
                                                     // clock will toggle infunctional mode
                                                     //and during processor access.  
   assign ntest_comb = ~test_comb;          
   
   
// clock gates for the 4 domains
 
//synopsys translate_off   
`ifdef STRUCTURAL
//synopsys translate_on
   
   // A set_clock_gating_check constraint should be set on the design.
   // This constraint will force dc_compiler to check arrival time of the
   // gating signal with respect to the clock and to not optimize gates
   // gating clock with the rest of the logic. However, it may change the
   // drive of these gates.
   aon21d2  reg_clk_u0( .a1( nenable_reg_clk ),
			.a2( ntest_comb ),
			.b ( pclk ),
			.z ( reg_clk ) );
   
   aon21d2  clk_div_u0( .a1( powerdown ),
			.a2( ntest_comb ),
			.b ( pclk ),
			.z ( div_clk ) );
   
   aon21d2  fifo_clk_u0( .a1( nclkena ),
			.a2( ntest_comb ),
			.b ( pclk ),
			.z ( function_clk ) );
   
   aon21d2  function_clk_u0( .a1( nena_fifo_clk ),
			.a2( ntest_comb ),
			.b ( pclk ),
			.z ( fifo_clk ) );
 //synopsys translate_off     
`else
   assign div_clk = pclk | (powerdown & ntest_comb);
   assign function_clk = pclk | (nclkena & ntest_comb);
   assign reg_clk = pclk | (nenable_reg_clk & ntest_comb);
   assign fifo_clk = pclk | (nena_fifo_clk & ntest_comb);
   
`endif
//synopsys translate_on  

   
endmodule // temp_top

 

⌨️ 快捷键说明

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