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;elsecnt<=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;elsecnt_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];elseds<=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;elseshcp<=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;elsestcp<=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 ;
initialbeginsys_clk=1'b1;sys_rst_n<=1'b0;#20sys_rst_n<=1'b1;endalways#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;initialbeginsys_clk=1'b1;sys_rst_n<=1'b0;#20sys_rst_n<=1'b1;endalways#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