|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
又要麻烦大家,最近在用fpga写一个spi的接口程序,虽然spi的协议不复杂,但是对于我这种菜鸟,要写出来还是有点麻烦。
我再书上找了一个例程看,但是有些地方还是不太明白。
我把看不太懂的地方用红色注视写出来,还码放各位帮我看下。
先谢谢啦
module spi_master(addr,in_data,out_data,rd,wr,cs,clk,miso,mosi,sclk);
input wire [1:0] addr;
input wire [7:0] in_data;
output reg [7:0] out_data;
input wire rd;
input wire wr;
input wire cs;
input wire clk;
inout miso;
inout mosi;
inout sclk;
reg sclk_buffer=0;
reg mosi_buffer=0;
reg busy=0;
reg [7:0] in_buffer=0;
reg [7:0] out_buffer=0;
reg [7:0] clkcount=0;
reg [7:0] clkdiv=0;
reg [4:0] count=0;
always @ ( cs or rd or addr or out_buffer or busy or clkdiv )
begin
out_data=8'bx;
if(cs && rd) // 读操作
begin
case ( addr ) //不太明白这个addr的意思,是通过addr区分输入输出不同的寄存器吗?
2'b00 : out_data=out_buffer;
2'b01 : out_data={7'b0,busy}; //看不明白
2'b10 : out_data=clkdiv; //看不明白
default : ;
endcase
end
else
;
end
always @ ( posedge clk )
begin
if( !busy ) //当busy=0, 可以把数据打入输入寄存器;当busy==1, 忙。
begin
if( cs && wr ) // 写操作
begin
case ( addr ) //不明白
2'b00 : begin in_buffer=in_data; busy=1'b1; end
2'b10 : begin clkdiv=in_data; end //看不明白这是什么意思
default : ;
endcase
end
end
else
begin
clkcount=clkcount+1;
if ( clkcount>=clkdiv ) //不明白clkcount和clkdiv的关系
begin
clkcount=0;
if ( ( count%2 )==0 )
begin
mosi_buffer=in_buffer[7]; //最高位优先(不过既然是master输出为什么不用输出寄存器而是用输入寄存器呢?)
in_buffer=in_buffer<<1;
end
if ( count>0 && count<17 )
begin
sclk_sclk_bufferbuffer=~sclk_buffer; //产生sclk信号
end
count=count+1;
if ( count>17 ) // 8个周期16次跳变
begin
count=0;
busy=1'b0;
end
end
end
end
always @ ( posedge sclk_buffer )
begin
out_buffer=out_buffer<<1;
out_buffer[0]=miso;
end
assign sclk=sclk_buffer;
assign mosi=mosi_buffer;
endmodule |
|