数码管的静态显示(二)

时间:2024-03-14 13:48:42

1.原理

要按照上图的顺序传递位选和段选的数据。

因为q0是最高位,共阳极数码管结构是dp....a,所以应该先传入低位a,而a在上图中的8段2进制编码中是seg[7],所以段选信号的顺序是seg[0],...seg[7]。

因为输出信号是两个时钟,所以要进行分频,因为不能太高。因为是4分频,所以计数的最大值是3。

(FPGA使用的晶振太高了, 74hc595 在50MHz的频率下没法正常工作, 所以选一个较为低一点的时钟频率作为触发)

为了让时钟信号能正确采集到数据,所以时钟信号的上升沿应该对准数据的稳定状态,也就是数据的中间。

2.代码

2.1 hc595_ctrl.v

module hc595_ctrl(
	input wire			sys_clk		,
	input wire			sys_rst_n		,
	input wire [5:0]	sel			,
	input wire [7:0]	seg			,
	
	output reg 			ds			,
	output reg 			shcp		,
	output reg 			stcp		,
	output wire 		oe		
);

wire [13:0] data;
reg [1:0] cnt;
reg [3:0] cnt_bit;

assign oe=1'b0;
assign data={seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5],sel[4],sel[3],sel[2],sel[1],sel[0]};
	
	
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		cnt<=2'd0;
	else if(cnt==2'd3)
		cnt<=2'd0;
	else
		cnt<=cnt+1'b1;
	
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		cnt_bit<=4'd0;
	else if((cnt==2'd3)&&(cnt_bit==4'd13))
		cnt_bit<=4'd0;
	else if(cnt==2'd3)
		cnt_bit<=cnt_bit+1'b1;
	else
		cnt_bit<=cnt_bit;
		
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		ds<=1'd0;
	else if(cnt==2'd0)
		ds<=data[cnt_bit];
	else
		ds<=ds;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		shcp<=1'b0;
	else if(cnt==2'd2)
		shcp<=1'b1;
	else if(cnt==2'd0)
		shcp<=1'b0;
	else
		shcp<=shcp;
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		stcp<=1'b0;
	else if((cnt==2'b0)&&(cnt_bit<=4'b0))
		stcp<=1'b1;
	else if((cnt==2'd2)&&(cnt_bit==4'b0))
		stcp<=1'b0;
	else
		stcp<=stcp;
		
endmodule
		
		

2.2 seg_595_static.v

module seg_595_static
(
	input wire 		sys_clk			,
	input wire 		sys_rst_n		,
	
	output reg 		ds				,
	output reg 		shcp			,
	output reg		stcp			,
	output reg 		oe		
);

wire [5:0]sel;
wire [7:0]seg;

seg_static #(
	.CNT_MAX  (25'd24)
)
seg_static_inst(
	.sys_clk	(sys_clk)		,
	.sys_rst_n	(sys_rst_n)	,
				
	.sel		(sel)		,
	.seg		(seg)		
);


hc595_ctrl hc595_ctrl_inst(
	.sys_clk	(sys_clk	)	,
	.sys_rst_n	(sys_rst_n	),
	.sel		(sel		)	,
	.seg		(seg		)	,
	
	.ds			(ds			),
	.shcp		(shcp		),
	.stcp		(stcp		),
	.oe		    (oe		   )
);

endmodule

2.3 tb_seg_595_ctrl.v

`timescale 1ns/1ns
module tb_seg_595_ctrl();

reg sys_clk;
reg sys_rst_n;

wire ds	  ;
wire shcp  ;
wire stcp  ;
wire oe	  ;
initial
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		#20
		sys_rst_n<=1'b1;
	end
	
always#10 sys_clk=~sys_clk;

seg_595_static seg_595_static_inst
(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n)	,
				 
	.ds			(ds			)	,
	.shcp		(shcp		)	,
	.stcp		(stcp		)	,
	.oe		    (oe		  )
);

endmodule

2.4 tb_seg_595_static.v

`timescale 1ns/1ns
module tb_seg_595_static();

reg sys_clk;
reg sys_rst_n;

initial
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		#20
		sys_rst_n<=1'b1;
	end
	
always#10 sys_clk=~sys_clk;

seg_static #(
	.CNT_MAX  (25'd24)
)
seg_static_inst(
	.sys_clk	(sys_clk)		,
	.sys_rst_n	(sys_rst_n)	,
				
	.sel		(sel)		,
	.seg		(seg)		
);



endmodule