恩恩,好的~~我写了个SPI的从模块,受单片机控制,现在只想最先实现对16位数据的收发,写先写地址,再读写数据,地址的首位表示读或者写,但是我的时序老是有问题,请各位高手指教~~!!<br>
module my_spi_sm(<br>
reset, //system reset<br>
ste, //enable the spi_sm to work<br>
sclk, <br>
simo, <br>
somi,<br>
crdata,<br>
cwdata,<br>
caddr<br>
);<br>
input reset,sclk,ste;<br>
input simo;<br>
output somi;<br>
input[15:0] crdata;<br>
output[15:0] cwdata;<br>
output[15:0] caddr;<br>
<br>
reg ff;<br>
reg somi;<br>
reg [7:0] data_in;<br>
reg [7:0] data_out;<br>
<br>
<br>
reg [15:0] data_write;<br>
reg crnw; //read/1 or write/0 enable <br>
reg [7:0] caddrh;<br>
reg [7:0] caddrl;<br>
reg caddrh_ready;<br>
reg caddrl_ready;<br>
reg cdatah_ready;<br>
reg cdatal_ready;<br>
reg [6:0] main_state;<br>
reg[7:0] sh8in_state;<br>
reg[7:0] sh8out_state;<br>
<br>
assign caddr=caddrl_ready?{1'b1,caddrh[6:0],caddrl[7:0]}:16'h0000;<br>
assign cwdata=cdatal_ready?data_write:16'h0000;<br>
<br>
//-----------------------------parameters--------------------------------------------------<br>
parameter <br>
idle =7'b0000001,<br>
write_addrh =7'b0000010,<br>
write_addrl =7'b0000100,<br>
write_datah =7'b0001000,<br>
write_datal =7'b0010000,<br>
read_datah =7'b0100000,<br>
read_datal =7'b1000000;<br>
<br>
parameter<br>
sh8in_bit7=8'b00000001,<br>
sh8in_bit6=8'b00000010,<br>
sh8in_bit5=8'b00000100,<br>
sh8in_bit4=8'b00001000,<br>
sh8in_bit3=8'b00010000,<br>
sh8in_bit2=8'b00100000,<br>
sh8in_bit1=8'b01000000,<br>
sh8in_bit0=8'b10000000;<br>
<br>
parameter<br>
sh8out_bit7=8'b00000001,<br>
sh8out_bit6=8'b00000010,<br>
sh8out_bit5=8'b00000100,<br>
sh8out_bit4=8'b00001000,<br>
sh8out_bit3=8'b00010000,<br>
sh8out_bit2=8'b00100000,<br>
sh8out_bit1=8'b01000000,<br>
sh8out_bit0=8'b10000000;<br>
<br>
<br>
<br>
//--------------------------main state machine----------------------------------------<br>
<br>
always@(posedge sclk or posedge reset)<br>
if(reset)<br>
begin<br>
ff <= 0;<br>
caddrh <= 0;<br>
caddrl <= 0;<br>
caddrh_ready <= 0;<br>
caddrl_ready <= 0;<br>
cdatah_ready <= 0;<br>
cdatal_ready <= 0; <br>
<br>
main_state <=idle;<br>
end <br>
else<br>
begin<br>
casex(main_state)<br>
idle: begin <br>
ff <=0;<br>
caddrh_ready <= 0;<br>
caddrl_ready <= 0;<br>
cdatah_ready <= 0;<br>
cdatal_ready <= 0; <br>
if(ste==0)<br>
begin<br>
main_state <=write_addrh;<br>
sh8in_state<=sh8in_bit7;<br>
end<br>
else<br>
main_state <=idle;<br>
end<br>
write_addrh:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
crnw <=data_in[7];<br>
caddrh<=data_in[7:0];<br>
caddrh_ready <=1;<br>
main_state <=write_addrl;<br>
ff <=0;<br>
end<br>
write_addrl:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
ff <=0;<br>
caddrl_ready <=1;<br>
caddrl <=data_in[7:0];<br>
if(crnw==1)<br>
begin<br>
main_state<=read_datah;<br>
sh8out_state<=sh8out_bit7;<br>
data_out<=crdata[15:8];<br>
end<br>
else <br>
begin<br>
main_state<=write_datah;<br>
end<br>
end<br>
<br>
write_datah:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
data_write[15:8]<=data_in;<br>
cdatah_ready<=1; <br>
main_state<=write_datal;<br>
ff<=0;<br>
end<br>
write_datal:<br>
if(ff==0)<br>
shift8_in;<br>
else<br>
begin<br>
data_write[7:0]<=data_in;<br>
cdatal_ready<=1;<br>
main_state<=idle;<br>
ff<=0;<br>
end<br>
read_datah: <br>
if(ff==0)<br>
shift8_out;<br>
else<br>
begin<br>
data_out<=crdata[7:0];<br>
main_state<=read_datal;<br>
ff<=0;<br>
end<br>
read_datal:<br>
if(ff==0)<br>
shift8_out;<br>
else<br>
begin<br>
main_state<=idle;<br>
ff<=0;<br>
end<br>
default: main_state<=idle;<br>
endcase<br>
end<br>
<br>
<br>
<br>
//--------------------------shift in bit by bit---------------------------------------- <br>
task shift8_in;<br>
begin<br>
casex(sh8in_state) <br>
sh8in_bit7: if(!sclk)<br>
begin<br>
data_in[7]<=simo;<br>
sh8in_state<=sh8in_bit6;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit7; <br>
sh8in_bit6: if(!sclk)<br>
begin<br>
data_in[6]<=simo;<br>
sh8in_state<=sh8in_bit5;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit6;<br>
sh8in_bit5: if(!sclk)<br>
begin<br>
data_in[5]<=simo;<br>
sh8in_state<=sh8in_bit4;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit5;<br>
sh8in_bit4: if(!sclk)<br>
begin<br>
data_in[4]<=simo;<br>
sh8in_state<=sh8in_bit3;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit4;<br>
sh8in_bit3: if(!sclk)<br>
begin<br>
data_in[3]<=simo;<br>
sh8in_state<=sh8in_bit2;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit3;<br>
sh8in_bit2: if(!sclk)<br>
begin<br>
data_in[2]<=simo;<br>
sh8in_state<=sh8in_bit1;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit2; <br>
sh8in_bit1: if(!sclk)<br>
begin<br>
data_in[1]<=simo;<br>
sh8in_state<=sh8in_bit0;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit1; <br>
sh8in_bit0: if(!sclk)<br>
begin<br>
data_in[0]<=simo;<br>
sh8in_state<=sh8in_bit7;<br>
ff<=1;<br>
end<br>
else<br>
sh8in_state<=sh8in_bit0;<br>
default: <br>
begin<br>
ff<=0;<br>
sh8in_state<=sh8in_bit7;<br>
end<br>
endcase<br>
end<br>
endtask<br>
<br>
//--------------------------shift out bit by bit---------------------------------------- <br>
task shift8_out;<br>
begin<br>
casex(sh8out_state)<br>
sh8out_bit7:<br>
if(sclk)<br>
begin<br>
somi<=data_out[7];<br>
sh8out_state<=sh8out_bit6;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit7;<br>
sh8out_bit6:<br>
if(sclk)<br>
begin<br>
somi<=data_out[6];<br>
sh8out_state<=sh8out_bit5;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit6;<br>
sh8out_bit5:<br>
if(sclk)<br>
begin<br>
somi<=data_out[5];<br>
sh8out_state<=sh8out_bit4;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit5;<br>
sh8out_bit4:<br>
if(sclk)<br>
begin<br>
somi<=data_out[4];<br>
sh8out_state<=sh8out_bit3;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit4;<br>
sh8out_bit3:<br>
if(sclk)<br>
begin<br>
somi<=data_out[3];<br>
sh8out_state<=sh8out_bit2;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit3;<br>
sh8out_bit2:<br>
if(sclk)<br>
begin<br>
somi<=data_out[2];<br>
sh8out_state<=sh8out_bit1;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit2;<br>
sh8out_bit1:<br>
if(sclk)<br>
begin<br>
somi<=data_out[1];<br>
sh8out_state<=sh8out_bit0;<br>
end<br>
else<br>
sh8out_state<=sh8out_bit1;<br>
sh8out_bit0:<br>
if(sclk)<br>
begin<br>
somi<=data_out[0]; <br>
sh8out_state<=sh8out_bit7;<br>
ff<=1; <br>
end<br>
else<br>
sh8out_state<=sh8out_bit0;<br>
<br>
default: <br>
begin<br>
ff<=0;<br>
sh8out_state<=sh8out_bit7;<br>
end<br>
endcase<br>
end<br>
endtask <br>
<br>
<br>
endmodule |