欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SPIX4_TT_V1_0

程序员文章站 2022-05-10 17:20:02
...
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

 

相关标签: module

推荐阅读