SPIX4_TT_V1_0

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)begin
	if(srst)begin
		state_c <= STATE_IDLE;
	end
	else begin
		state_c <= state_n;
	end
end

always	@(*)begin
	case(state_c)
		STATE_IDLE:begin
			if(idle2s1_start)begin
				state_n = STATE_S1;
			end
			else begin
				state_n = state_c;
			end
		end
		STATE_S1:begin
			if(s12s2_start)begin
				state_n = STATE_S2;
			end
			else begin
				state_n = state_c;
			end
		end
		STATE_S2:begin
			if(s22s3_start)begin
				state_n = STATE_S3;
			end
			else begin
				state_n = state_c;
			end
		end
		STATE_S3:begin
			if(s32s4_start)begin
				state_n = STATE_S4;
			end
			else begin
				state_n = state_c;
			end
		end
		STATE_S4:begin
			if(s42idle_start)begin
				state_n = STATE_IDLE;
			end
			else begin
				state_n = state_c;
			end
		end
		default: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)begin
	if(idle2s1_start)begin
		addr_sc <= s_axis_taddr;
		data_sc <= s_axis_tdata;
		rw_sc	<= s_axis_rw;
	end
end
/************************************************************
						分频
************************************************************/
always	@(posedge clk)begin
	if(srst)begin
		cnt <= 0;
	end
	else if(add_cnt)begin
		if(end_cnt)begin
			cnt <= 0;
		end
		else begin
			cnt <= cnt + 1'b1;
		end
	end
end
assign	add_cnt = !(state_c == STATE_IDLE);
assign	end_cnt = add_cnt && cnt == CNT_NUM - 1;
/************************************************************
						地址
************************************************************/
always	@(posedge clk)begin
	if(srst)begin
		cnta <= 0;
	end
	else if(add_cnta)begin
		if(end_cnta)begin
			cnta <= 0;
		end
		else begin
			cnta <= cnta + 1'b1;
		end
	end
end
assign	add_cnta = state_c == STATE_S2;
assign	end_cnta = add_cnta && cnta == ADDR_W - 1;
/************************************************************
						数据
************************************************************/
always	@(posedge clk)begin
	if(srst)begin
		cntd <= 0;
	end
	else if(add_cntd)begin
		if(end_cntd)begin
			cntd <= 0;
		end
		else begin
			cntd <= cntd + 1'b1;
		end
	end
end
assign	add_cntd = state_c == STATE_S3;
assign	end_cntd = add_cntd && cntd == DATA_W - 1;
/************************************************************
						SCLK
************************************************************/
always	@(posedge clk)begin
	if(srst)begin
		sclk_r <= 0;
	end
	else if(end_cnt)begin
		sclk_r <= 0;
	end
	else if(cnt == (CNT_NUM/2-1))begin
		sclk_r <= 1;
	end
end
assign	SCLK = sclk_r;
/************************************************************
						CS_B
************************************************************/
always	@(posedge clk)begin
	if(srst)begin
		cs_b_r <= 1;
	end
	else if(s32s4_start)begin
		cs_b_r <= 1;
	end
	else if(s12s2_start)begin
		cs_b_r <= 0;
	end
end
assign	CS_B = cs_b_r;
/************************************************************
						SDO
************************************************************/
always	@(posedge clk)begin
	if(s12s2_start)begin
		sdo_r <= {addr_sc,data_sc};
	end
	else if(end_cnt)begin
		sdo_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)begin
	if(T && (cnt == (CNT_NUM/2-1)))begin
		jieshou <= {jieshou[DATA_W-2:0],SDI};
	end
end
assign	m_axis_tdata  = {addr_sc,jieshou};
assign	m_axis_tvalid = s32s4_start;

endmodule

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值