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