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

📄 spi_burst.v

📁 Verilog block SPI for Burst R/W Operation
💻 V
📖 第 1 页 / 共 2 页
字号:
    xmit_nxt_dat <= #1 1'b1;
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    xmit_nxt_dat_d1 <= #1 1'b0;
  else if (!reset_s)
    xmit_nxt_dat_d1 <= #1 1'b0;
  else if (spi_clk_trig)
    xmit_nxt_dat_d1 <= #1 xmit_nxt_dat;
end

// generate buffer read enable 
always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    buf_rd <= #1 1'b0;
  else if(!reset_s || (!spi_en && spi_clk_trig))
    buf_rd <= #1 1'b0;
  // read enable when buf-to-SPI
  else if (spi_clk_trig &&(sta_d == BUF_RD) && (cnt7==3'b110) && (buf_rd_cnt != bwdt))
    buf_rd <= #1 1'b1;
  else if (spi_clk_trig)
    buf_rd <= #1 1'b0;
end



always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    cnt7 <= #1 3'b000;
  else if(!reset_s || (spi_dir && spi_clk_trig))
    cnt7 <= #1 3'b000;
  else if (spi_clk_trig && (sta_d == WAIT ))
    cnt7 <= #1 3'b000;
  else if (spi_clk_trig && (sta_d == BUF_RD ))
    cnt7 <= #1 cnt7 + 1'b1;
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    cnt7_for_rd <= #1 13'd0;
  else if(!reset_s || (!mck_en && spi_clk_trig))
    cnt7_for_rd <= #1 13'd0;
  else if(spi_clk_trig && spi_dir && mck_en)
    cnt7_for_rd <= #1 cnt7_for_rd + 1'b1;
end

// 8051 control data transfer, ie. 8051 write data to register 'spidat',
// then start machine to xmit data to pin mdo.
assign cmd_lat = wr_8051 && (addr==8'h6b);

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    cmd_lat_24 <= #1 1'b0;
  else if (!reset_s)
    cmd_lat_24 <= #1 1'b0;
  else if ((state==START) && ~mcu_clk_sel)
    cmd_lat_24 <= #1 1'b0;
  else if (cmd_lat)
    cmd_lat_24 <= #1 1'b1;
  else if (mcu_clk_sel)
    cmd_lat_24 <= #1 1'b0;
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    buf_dat_lch <= #1 8'h0;
  else if (spi_clk_trig)
    buf_dat_lch <= #1 buf_dat;
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    dat_out <= #1 8'hff;
  else if (!reset_s || (xmit_done && spi_clk_trig))
    dat_out <= #1 8'hff;
  else if (spi_clk_trig && cmd_lat_24)
    dat_out <= #1 spidat;
  else if (spi_clk_trig&&(state==XMIT))
    dat_out <= #1 {dat_out[6:0],dat_out2[7]};
  else if (spi_clk_trig && !spi_dir && buf_rd)
    dat_out <= #1 buf_dat_lch;
  else if (spi_clk_trig && !spi_dir && xmit_nxt)
    dat_out <= #1 {dat_out[6:0],1'b0};
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if (!reset_n)
	  dat_out2 <= #1 8'hff;
	else if(!reset_s || (xmit_done&&spi_clk_trig))
	  dat_out2 <= #1 8'hff;
  else if (spi_clk_trig && cmd_lat_24)
    dat_out2 <= #1 sbdw;
  else if (spi_clk_trig&&(state==XMIT))
    dat_out2 <= #1 {dat_out2[6:0],1'b0};
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    mdo <= #1 1'b1;
  else if (!reset_s || (!spi_en&&spi_clk_trig))
    mdo <= #1 1'b1;
  else if ((sta_d==4'h1) && spi_clk_trig)
    mdo <= #1 1'b1;
  else if (spi_clk_trig)
    mdo <= dat_out[7];
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    ctrl_3_24m <= #1 1'b0;
  else if (!reset_s)
    ctrl_3_24m <= #1 1'b0;
  else if (mck_en && ~mcu_clk_sel)
    ctrl_3_24m <= #1 1'b0;
  else if (cmd[1])
    ctrl_3_24m <= #1 1'b1;
  else if (mcu_clk_sel)
    ctrl_3_24m <= #1 1'b0;
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (!reset_n)
    mck_en <= #1 1'b0;
  else if (!reset_s)
    mck_en <= #1 1'b0;
  else if (spi_clk_trig && (state==XMIT))
    mck_en <= #1 1'b1;
  else if (spi_clk_trig && !spi_dir && xmit_nxt_dat)
    mck_en <= #1 1'b1;
  else if (spi_clk_trig && (xmit_done_d1 || (!xmit_nxt_dat && xmit_nxt_dat_d1)))
    mck_en <= #1 1'b0;
  else if (spi_clk_trig && ctrl_3_24m)
    mck_en <= #1 1'b1;
  else if (spi_clk_trig && mck_jump)
    mck_en <= #1 1'b0;
end
//assign spi_work = mck_en ;

reg mck_en_d1;
always @(posedge mcu_clk or negedge reset_n)
begin
	if (!reset_n)
	   mck_en_d1 <= #1 1'b0 ;
	else
	   mck_en_d1 <= #1 mck_en ;
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if (!reset_n)
	   spi_work <= #1 1'b0 ;
	else if(!reset_s)
	   spi_work <= #1 1'b0 ;
	else if(cmd_lat || spi_cmd_sent || cmd[1])
	   spi_work <= #1 1'b1 ;
	else if(!mck_en && mck_en_d1)
	   spi_work <= #1 1'b0 ;
end



assign mck_jump = rd_one_byte ? (cnt7_for_rd[3:0] == 4'h7) : (cnt7_for_rd[12:0] == {brdh[1:0],brdl,3'b111});


assign mck = (!clk)&mck_en ;

// Following RTL for receiving data from SPI.
// After sending command, spi controller is ready to receive data depending on 8051.
// Before receiving data, 8051 has to set two register bits,
// one is cmd[2], which indicates whether the to be received data is special data
// or not, special data, ex. FLASH'S register data, FAT, etc.
// the other is cmd[1], which starts to receive one byte length of data, one START
// receives one byte. cmd[1] is returned to '0' automatically.
// If the received data is special, it will be stored in spidat, and waiting 8051 to
// read it. If not, the received data is automatically transferred to buffer.

reg	mck_d;
always @(posedge mcu_clk or negedge reset_n)
	if (~reset_n)
		mck_d <= #1 1'b0;
	else if (~reset_s)
		mck_d <= #1 1'b0;
	else
		mck_d <= #1 mcu_clk_sel ? 1'b0 : mck ;

always @(posedge mcu_clk or negedge reset_n)
begin
  if (~reset_n)
    spidat <= #1 8'h00;
  else if (!reset_s)
    spidat <= #1 8'h00;
  else if (cmd_lat)
    spidat <= #1 data_in;
  else if (mck_en && spi_dir && mcu_clk_sel)
    spidat <= #1 {spidat[6:0],mdi};
  else if (!mcu_clk_sel && spi_dir && (rcv_edge_sel ? (!mck && mck_d):(mck && !mck_d)))
    spidat <= #1 {spidat[6:0],mdi};
end


assign spidat_vld_pre = spi_dir & (cnt7_for_rd[2:0]==3'b111);

always @(posedge mcu_clk or negedge reset_n)
begin
  if (~reset_n)
    spidat_vld_pre_d1 <= #1 1'b0;
  else if (!reset_s)
    spidat_vld_pre_d1 <= #1 1'b0;
  else
    spidat_vld_pre_d1 <= #1 spidat_vld_pre;
end

always @(posedge mcu_clk or negedge reset_n)
begin
  if (~reset_n)
    spidat_vld_reg <= #1 1'b0;
  else if (!reset_s)
    spidat_vld_reg <= #1 1'b0;
  else if (!spidat_vld_pre && spidat_vld_pre_d1)
    spidat_vld_reg <= #1 1'b1;
  else
    spidat_vld_reg <= #1 1'b0;
end

assign	spidat_vld = mcu_clk_sel ? (!spidat_vld_pre && spidat_vld_pre_d1) : spidat_vld_reg;





always @(posedge mcu_clk or negedge reset_n)
begin
	if (!reset_n)
	   buf_rd_d1 <= #1 1'b0 ;
	else
	   buf_rd_d1 <= #1	buf_rd ;	
end
assign buf_rd_mcu = buf_rd&&(!buf_rd_d1);

/////////////////////////////////////////////////////////////////////////////////////////////Well
//////////////////////////////           Reg File        ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   bus_sel <= #1 2'b00 ;
	else if (wr_8051&&(addr==`SPI_TEST_SEL))
	   bus_sel <= #1 data_in[1:0] ;	
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   bwdl <= #1 8'hff ;
	else if (wr_8051&&(addr==`XMIT_LEN_L))
	   bwdl <= #1 data_in ;	
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   bwdh <= #1 8'h00 ;
	else if (wr_8051&&(addr==`XMIT_LEN_H))
	   bwdh <= #1	data_in ;	
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   brdl <= #1 8'hff ;
	else if (wr_8051&&(addr==`RECV_LEN_L))
	   brdl <= #1	data_in ;	
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   brdh <= #1 8'h00 ;
	else if (wr_8051&&(addr==`RECV_LEN_H))
	   brdh <= #1	data_in ;	
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   bitl <= #1 8'h07 ;
	else if (wr_8051&&(addr==`XMIT_BIT_L))
	   bitl <= #1	data_in ;	
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   sbdw <= #1 8'h00 ;
	else if (wr_8051&&(addr==`XMIT_TWO_D))
	   sbdw <= #1	data_in ;	
end


always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   soft_rst <= #1 1'b1 ;
	else if (wr_8051&&(addr==`SPI_S_RST))
	   soft_rst <= #1 data_in[0] ;
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   cmd  <= #1 8'h04 ;
	else if (wr_8051&&(addr==`SPI_CMD_WR))
	   cmd  <= #1	data_in ;
	else if(cmd[1])
	   cmd  <= #1 {cmd[7:2],1'b0,cmd[0]};
	else if(sta_d == BEGIN)
		 cmd  <= #1 {cmd[7:1],1'b0}; 	
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   ctrl <= #1 8'h80 ;
	else if (wr_8051&&(addr==`SPI_CTL))
	   ctrl <= #1 data_in ;
end

always @(posedge mcu_clk or negedge reset_n)
begin
	if(!reset_n)
	   spi_divclk_ok <= #1 1'b0 ;
	else if(!reset_s)
	   spi_divclk_ok <= #1 1'b0 ;
	else if (wr_8051&&(addr==`SPI_CTL))
	   spi_divclk_ok <= #1 1'b0 ;
	else if (mcu_clk_sel)
	   spi_divclk_ok <= #1 1'b1 ;
	else if (spi_clk_cnt == clk_divx2)
	   spi_divclk_ok <= #1 1'b1 ;
end



////////////////////////////////////////         Reg File Read         /////////////////////////////
always @(addr or bus_sel or ctrl or bwdl or bwdh or brdl or brdh 
    or bitl /*or bith*/ or spidat or sbdw or spi_work or spi_busy 
    or cmd or state or sta_d or spi_divclk_ok or soft_rst)
begin
	case(addr)
     `SPI_TEST_SEL: data_out =  {6'h0,bus_sel};
     `SPI_CTL     : data_out =  ctrl  ;     
     `XMIT_LEN_L  : data_out =  bwdl  ;    
     `XMIT_LEN_H  : data_out =  bwdh  ;    
     `RECV_LEN_L  : data_out =  brdl  ;    
     `RECV_LEN_H  : data_out =  brdh  ;    
     `XMIT_ONE_D  : data_out =  spidat;
     `XMIT_TWO_D  : data_out =  sbdw  ;
     `XMIT_BIT_L  : data_out =  bitl  ;  
     `SPI_CMD_WR  : data_out =  cmd   ;
     `SPI_S_RST   : data_out =  {7'h00,soft_rst} ;
     `SPI_STAT_M  : data_out =  {state,sta_d};
     `SPI_STATUS  : data_out =  {5'h0,spi_divclk_ok,spi_busy,spi_work};    
	   default      : data_out =  8'h00 ;	
	endcase
end



///////////////////////////////////////          SPI Test Bus          /////////////////////////////


wire [15:0] spi_top_bus   = {mcu_clk,clk,mck,mdi,mdo,spi_work,spi_busy,mck_en,state,sta_d};
wire [15:0] spi_bitw_bus  = {mcu_clk,clk,mck,mdo,cmd_lat,cmd_lat_24,xmit_done,mcu_clk_sel,spi_divclk_ok,spi_work,state[1:0],xmit_cnt[3:0]};
wire [15:0] spi_datw_bus  = {mcu_clk,clk,mck,mdo,spi_divclk_ok,spi_cmd_sent,buf_rd,xmit_nxt_dat,spi_busy,spi_work,cnt7[2:0],sta_d[2:0]};
wire [15:0] spi_datr_bus  = {mcu_clk,clk,mck,mdi,spi_dir,ctrl_3_24m,mck_jump,spidat_vld,spidat};

always @(bus_sel or spi_top_bus or spi_bitw_bus or spi_datw_bus or spi_datr_bus)
begin
	case(bus_sel)
	    2'b00: spi_test_bus = spi_top_bus  ;
	    2'b01: spi_test_bus = spi_bitw_bus ;
	    2'b10: spi_test_bus = spi_datw_bus ;
	    2'b11: spi_test_bus = spi_datr_bus ;
	  default: spi_test_bus = spi_top_bus  ;	
	endcase
end







endmodule


⌨️ 快捷键说明

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