|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
module spi_master(
clk, // global clock
reset_n, // global async low reset
clk_div, // spi clock divider
wr, // spi write
wrdata, // spi write data, 8bit
rddata, // spi recieve data, 8bit, valid when ready assert
sck, // spi master clock out
sdi, // spi master data in (MISO)
sdo, // spi master data out (MOSI)
ready // spi master ready (idle)
);
input clk;
input reset_n;
input [7:0]clk_div;
input wr;
input [7:0]wrdata;
output [7:0]rddata;
output sck;
output sdo;
output ready;
input sdi;
parameter clock_polarity = 1; // '0': mode 0, sck=0 when idle; '1': mode 3, sck=1 when idle
reg [7:0]dat;
reg rsck;
reg [7:0]cnt;
reg busy;
reg [3:0]state;
reg [7:0]rddata;
wire sdo = dat[7];
wire sck = busy? rsck:clock_polarity;
wire sdi_tick = (cnt==clk_div>>1)/*synthesis keep*/;
wire sdo_tick = (cnt==clk_div)/*synthesis keep*/;
wire ready = !(wr||busy);
always @(posedge clk or negedge reset_n)
if(!reset_n)
cnt <= 0;
else if(cnt<clk_div && busy)
cnt <= cnt + 1;
else
cnt <= 1;
always @(posedge clk or negedge reset_n)
if(!reset_n)
rsck <= 0;
else if(sdi_tick)
rsck <= 1;
else if(sdo_tick)
rsck <= 0;
always @(posedge clk or negedge reset_n)
if(!reset_n)
busy <= 0;
else if(wr && !busy)
busy <= 1;
else if(state==8 && sdo_tick)
busy <= 0;
always@(posedge clk or negedge reset_n)
if(!reset_n)
state <= 0;
else if(wr && !busy)
state <= 1;
else if(state==8 && sdo_tick)
state <= 0;
else if(sdo_tick)
state <= state + 1;
always @(posedge clk or negedge reset_n)
if(!reset_n)
dat <= 0;
else if(wr && !busy)
dat <= wrdata;
else if(sdo_tick && busy && state!=8)
dat <= dat<<1;
always @(posedge clk or negedge reset_n)
if(!reset_n)
rddata <= 0;
else if(sdi_tick && busy)
rddata <= {rddata[6:0],sdi};
endmodule |
|