SPIX4
module SPIX4_TT #(
parameter CNT_NUM = 10,
parameter ADDR_W = 16,
parameter DATA_W = 8
)(
input clk ,
input srst ,
output s_axis_tready ,
input s_axis_tvalid ,
input s_axis_rw ,//高为读,从器件到FPGA;低为写,从FPGA到器件;
input [ADDR_W-1:0] s_axis_taddr ,//不只是地址,控制指令
input [DATA_W-1:0] s_axis_tdata ,
output T ,//高为输入,高阻;低为输出;
output CS_B ,
output SCLK ,
output SDO ,
input SDI ,
output m_axis_tvalid ,
output [ADDR_W+DATA_W-1:0] m_axis_tdata
);
localparam STATE_IDLE = 4'd0;
localparam STATE_S1 = 4'd1;
localparam STATE_S2 = 4'd2;
localparam STATE_S3 = 4'd3;
localparam STATE_S4 = 4'd4;reg [ 3: 0] state_c = STATE_IDLE;
reg [ 3: 0] state_n;wire idle2s1_start;
wire s12s2_start;
wire s22s3_start;
wire s32s4_start;
wire s42idle_start;reg [ 7: 0] cnt = 0;
wire add_cnt;
wire end_cnt;
reg [ 7: 0] cnta = 0;
wire add_cnta;
wire end_cnta;
reg [ 7: 0] cntd = 0;
wire add_cntd;
wire end_cntd;reg [ADDR_W-1:0] addr_sc = 0;
reg [DATA_W-1:0] data_sc = 0;
reg rw_sc = 0;
reg sclk_r = 0;
reg cs_b_r = 1;
reg [ADDR_W+DATA_W-1:0] sdo_r = 0;
reg [DATA_W-1:0] jieshou = 0;
/************************************************************状态机
************************************************************/
always @(posedge clk)beginif(srst)beginstate_c <= STATE_IDLE;endelse beginstate_c <= state_n;end
endalways @(*)begincase(state_c)STATE_IDLE:beginif(idle2s1_start)beginstate_n = STATE_S1;endelse beginstate_n = state_c;endendSTATE_S1:beginif(s12s2_start)beginstate_n = STATE_S2;endelse beginstate_n = state_c;endendSTATE_S2:beginif(s22s3_start)beginstate_n = STATE_S3;endelse beginstate_n = state_c;endendSTATE_S3:beginif(s32s4_start)beginstate_n = STATE_S4;endelse beginstate_n = state_c;endendSTATE_S4:beginif(s42idle_start)beginstate_n = STATE_IDLE;endelse beginstate_n = state_c;endenddefault:state_n = STATE_IDLE;endcase
end
assign idle2s1_start = state_c == STATE_IDLE && s_axis_tvalid;
assign s12s2_start = state_c == STATE_S1 && end_cnt;
assign s22s3_start = state_c == STATE_S2 && end_cnta;
assign s32s4_start = state_c == STATE_S3 && end_cntd;
assign s42idle_start = state_c == STATE_S4 && end_cnt;assign s_axis_tready = state_c == STATE_IDLE;
/************************************************************锁存数据
************************************************************/
always @(posedge clk)beginif(idle2s1_start)beginaddr_sc <= s_axis_taddr;data_sc <= s_axis_tdata;rw_sc <= s_axis_rw;end
end
/************************************************************分频
************************************************************/
always @(posedge clk)beginif(srst)begincnt <= 0;endelse if(add_cnt)beginif(end_cnt)begincnt <= 0;endelse begincnt <= cnt + 1'b1;endend
end
assign add_cnt = !(state_c == STATE_IDLE);
assign end_cnt = add_cnt && cnt == CNT_NUM - 1;
/************************************************************地址
************************************************************/
always @(posedge clk)beginif(srst)begincnta <= 0;endelse if(add_cnta)beginif(end_cnta)begincnta <= 0;endelse begincnta <= cnta + 1'b1;endend
end
assign add_cnta = state_c == STATE_S2;
assign end_cnta = add_cnta && cnta == ADDR_W - 1;
/************************************************************数据
************************************************************/
always @(posedge clk)beginif(srst)begincntd <= 0;endelse if(add_cntd)beginif(end_cntd)begincntd <= 0;endelse begincntd <= cntd + 1'b1;endend
end
assign add_cntd = state_c == STATE_S3;
assign end_cntd = add_cntd && cntd == DATA_W - 1;
/************************************************************SCLK
************************************************************/
always @(posedge clk)beginif(srst)beginsclk_r <= 0;endelse if(end_cnt)beginsclk_r <= 0;endelse if(cnt == (CNT_NUM/2-1))beginsclk_r <= 1;end
end
assign SCLK = sclk_r;
/************************************************************CS_B
************************************************************/
always @(posedge clk)beginif(srst)begincs_b_r <= 1;endelse if(s32s4_start)begincs_b_r <= 1;endelse if(s12s2_start)begincs_b_r <= 0;end
end
assign CS_B = cs_b_r;
/************************************************************SDO
************************************************************/
always @(posedge clk)beginif(s12s2_start)beginsdo_r <= {addr_sc,data_sc};endelse if(end_cnt)beginsdo_r <= addr_sc;end
end
assign SDO = sdo_r[ADDR_W+DATA_W-1];
/************************************************************T
************************************************************/
assign T = (state_c == STATE_S3) && rw_sc;
/************************************************************SDI
************************************************************/
always @(posedge clk)beginif(T && (cnt == (CNT_NUM/2-1)))beginjieshou <= {jieshou[DATA_W-2:0],SDI};end
end
assign m_axis_tdata = {addr_sc,jieshou};
assign m_axis_tvalid = s32s4_start;endmodule
更多推荐
SPIX4
发布评论