📄 spi_burst.v
字号:
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 + -