【FPGA】:74HC955模块的驱动程序

驱动模块 

module HC595_Driver(
	input             clk     ,   // 时钟信号
	input             rst_n   ,   // 复位信号(低有效)
	input		[15:0]	Data   ,		//
	input             S_EN   ,		//移位使能,为1则开始输入数据
	
   output	reg		SH_CP,   // 12.5MHZ,上升沿采样
   output	reg		ST_CP   ,   // 为1则发送并行数据
   output	reg		DS     // 数据输出
);

reg	[15:0]	r_data;
always @ (posedge clk)begin
	if(S_EN)
		r_data <= Data;
end


reg	[7:0]		divider_cnt;

parameter CNT_MAX = 2;

always @ (posedge clk or negedge rst_n) begin
	if (!rst_n)
      divider_cnt <= 1'b0;
	else	if(divider_cnt == CNT_MAX - 1)
      divider_cnt <= 1'b0;
	else
		divider_cnt <= divider_cnt + 1'b1;
end

wire src_plus = (divider_cnt == CNT_MAX - 1);



reg	[5:0]	SHCP_EDGE_CNT;
always @(posedge clk or negedge rst_n) begin
	if (!rst_n)
		SHCP_EDGE_CNT <= 0;
	else if(src_plus)begin
		if(SHCP_EDGE_CNT == 6'd32)
			SHCP_EDGE_CNT <= 0;
		else
			SHCP_EDGE_CNT <= SHCP_EDGE_CNT + 1;
	end
	else
		SHCP_EDGE_CNT <= SHCP_EDGE_CNT;
end

always @(posedge clk or negedge rst_n) begin
	if (!rst_n)begin
		SH_CP <= 0;
		ST_CP <= 0;
		DS		<= 0;
	end
	else begin
		case(SHCP_EDGE_CNT)
			0:		begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[15];	end
			1:		begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			2:		begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[14];	end
			3:		begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			4:		begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[13];	end
			5:		begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			6:		begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[12];	end
			7:		begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			8:		begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[11];	end
			9:		begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			10:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[10];	end
			11:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			12:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[9];	end
			13:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			14:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[8];	end
			15:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			16:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[7];	end
			17:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			18:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[6];	end
			19:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			20:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[5];	end
			21:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			22:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[4];	end
			23:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			24:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[3];	end
			25:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			26:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[2];	end
			27:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			28:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[1];	end
			29:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			30:	begin	SH_CP	<= 0;	ST_CP	<=	0;	DS	<= r_data[0];	end
			31:	begin	SH_CP	<= 1;	ST_CP	<=	0;	end
			32:	ST_CP	<= 1;
			default:	begin
				SH_CP <= 0;
				ST_CP <= 0;
				DS		<= 0;
			end
		
		endcase
	end
end


endmodule 

测试模块:

`timescale 1ns/1ps

`define clock_period 20

module HC595_tb;
	
reg             clk     ;   // 时钟信号
reg             rst_n   ;   // 复位信号(低有效)
reg		[15:0]	Data   ;		//
reg             S_EN   ;		//移位使能
	
wire		SH_CP;   // 12.5MHZ
wire		ST_CP   ;   // 
wire		DS;    //
	
HC595_Driver HC(
.clk(clk),   // 时钟信号
.rst_n(rst_n),   // 复位信号(低有效)
.Data(Data)   ,		//
.S_EN(S_EN)   ,		//移位使能
	
.SH_CP(SH_CP) ,   // 12.5MHZ
.ST_CP(ST_CP)   ,   // 
.DS(DS)     // 
);
	
initial clk = 1;
	
always #(`clock_period / 2) clk = ~clk;
	
initial begin
	rst_n = 1'b0;
	Data = 16'h1234;
	S_EN = 0;
	
	#201;
	S_EN = 1;
	rst_n = 1'b1;
	
	#2000;
	S_EN = 0;
	
	#200;
	
	Data = 16'h8765;
	
	S_EN = 1;
	#2000;
	S_EN = 0;
	
	#2000;
	
	$stop;
	end
	
endmodule 

猜你喜欢

转载自blog.csdn.net/qq_42792802/article/details/126814766